1- import { Breakpoint , IBackend , Stack , SSHArguments , Variable , VariableObject , MIError } from "../backend"
1+ import { Breakpoint , IBackend , Thread , Stack , SSHArguments , Variable , VariableObject , MIError } from "../backend"
22import * as ChildProcess from "child_process"
33import { EventEmitter } from "events"
44import { parseMI , MINode } from '../mi_parse' ;
@@ -365,6 +365,12 @@ export class MI2 extends EventEmitter implements IBackend {
365365 }
366366 } else
367367 this . log ( "log" , JSON . stringify ( parsed ) ) ;
368+ } else if ( record . type == "notify" ) {
369+ if ( record . asyncClass == "thread-created" ) {
370+ this . emit ( "thread-created" , parsed ) ;
371+ } else if ( record . asyncClass == "thread-exited" ) {
372+ this . emit ( "thread-exited" , parsed ) ;
373+ }
368374 }
369375 }
370376 } ) ;
@@ -584,39 +590,55 @@ export class MI2 extends EventEmitter implements IBackend {
584590 } ) ;
585591 }
586592
587- getStack ( maxLevels : number ) : Thenable < Stack [ ] > {
588- if ( trace )
589- this . log ( "stderr" , "getStack" ) ;
590- return new Promise ( ( resolve , reject ) => {
591- let command = "stack-list-frames" ;
592- if ( maxLevels ) {
593- command += " 0 " + maxLevels ;
594- }
595- this . sendCommand ( command ) . then ( ( result ) => {
596- let stack = result . result ( "stack" ) ;
597- let ret : Stack [ ] = [ ] ;
598- stack . forEach ( element => {
599- let level = MINode . valueOf ( element , "@frame.level" ) ;
600- let addr = MINode . valueOf ( element , "@frame.addr" ) ;
601- let func = MINode . valueOf ( element , "@frame.func" ) ;
602- let filename = MINode . valueOf ( element , "@frame.file" ) ;
603- let file = MINode . valueOf ( element , "@frame.fullname" ) ;
604- let line = 0 ;
605- let lnstr = MINode . valueOf ( element , "@frame.line" ) ;
606- if ( lnstr )
607- line = parseInt ( lnstr ) ;
608- let from = parseInt ( MINode . valueOf ( element , "@frame.from" ) ) ;
609- ret . push ( {
610- address : addr ,
611- fileName : filename ,
612- file : file ,
613- function : func || from ,
614- level : level ,
615- line : line
616- } ) ;
617- } ) ;
618- resolve ( ret ) ;
619- } , reject ) ;
593+ async getThreads ( ) : Promise < Thread [ ] > {
594+ if ( trace ) this . log ( "stderr" , "getThreads" ) ;
595+
596+ let command = "thread-info" ;
597+ let result = await this . sendCommand ( command ) ;
598+ let threads = result . result ( "threads" ) ;
599+ let ret : Thread [ ] = [ ] ;
600+ return threads . map ( element => {
601+ let id = parseInt ( MINode . valueOf ( element , "id" ) ) ;
602+ let name = MINode . valueOf ( element , "name" ) + "" ;
603+ return {
604+ id,
605+ name
606+ } ;
607+ } ) ;
608+ }
609+
610+ async getStack ( maxLevels : number , thread : number ) : Promise < Stack [ ] > {
611+ if ( trace ) this . log ( "stderr" , "getStack" ) ;
612+
613+ let command = "stack-list-frames" ;
614+ if ( thread != 0 ) {
615+ command += ` --thread ${ thread } ` ;
616+ }
617+ if ( maxLevels ) {
618+ command += " 0 " + maxLevels ;
619+ }
620+ let result = await this . sendCommand ( command ) ;
621+ let stack = result . result ( "stack" ) ;
622+ let ret : Stack [ ] = [ ] ;
623+ return stack . map ( element => {
624+ let level = MINode . valueOf ( element , "@frame.level" ) ;
625+ let addr = MINode . valueOf ( element , "@frame.addr" ) ;
626+ let func = MINode . valueOf ( element , "@frame.func" ) ;
627+ let filename = MINode . valueOf ( element , "@frame.file" ) ;
628+ let file = MINode . valueOf ( element , "@frame.fullname" ) ;
629+ let line = 0 ;
630+ let lnstr = MINode . valueOf ( element , "@frame.line" ) ;
631+ if ( lnstr )
632+ line = parseInt ( lnstr ) ;
633+ let from = parseInt ( MINode . valueOf ( element , "@frame.from" ) ) ;
634+ return {
635+ address : addr ,
636+ fileName : filename ,
637+ file : file ,
638+ function : func || from ,
639+ level : level ,
640+ line : line
641+ } ;
620642 } ) ;
621643 }
622644
@@ -651,14 +673,17 @@ export class MI2 extends EventEmitter implements IBackend {
651673 } ) ;
652674 }
653675
654- evalExpression ( name : string ) : Thenable < any > {
676+ async evalExpression ( name : string , thread : number , frame : number ) : Promise < MINode > {
655677 if ( trace )
656678 this . log ( "stderr" , "evalExpression" ) ;
657- return new Promise ( ( resolve , reject ) => {
658- this . sendCommand ( "data-evaluate-expression " + name ) . then ( ( result ) => {
659- resolve ( result ) ;
660- } , reject ) ;
661- } ) ;
679+
680+ let command = "data-evaluate-expression " ;
681+ if ( thread != 0 ) {
682+ command += `--thread ${ thread } --frame ${ frame } ` ;
683+ }
684+ command += name ;
685+
686+ return await this . sendCommand ( command ) ;
662687 }
663688
664689 async varCreate ( expression : string , name : string = "-" ) : Promise < VariableObject > {
@@ -704,13 +729,12 @@ export class MI2 extends EventEmitter implements IBackend {
704729 this . emit ( "msg" , type , msg [ msg . length - 1 ] == '\n' ? msg : ( msg + "\n" ) ) ;
705730 }
706731
707- sendUserInput ( command : string ) : Thenable < any > {
732+ sendUserInput ( command : string , threadId : number = 0 , frameLevel : number = 0 ) : Thenable < any > {
708733 if ( command . startsWith ( "-" ) ) {
709734 return this . sendCommand ( command . substr ( 1 ) ) ;
710735 }
711736 else {
712- this . sendRaw ( command ) ;
713- return Promise . resolve ( undefined ) ;
737+ return this . sendCliCommand ( command , threadId , frameLevel ) ;
714738 }
715739 }
716740
@@ -723,6 +747,15 @@ export class MI2 extends EventEmitter implements IBackend {
723747 this . process . stdin . write ( raw + "\n" ) ;
724748 }
725749
750+ async sendCliCommand ( command : string , threadId : number = 0 , frameLevel : number = 0 ) {
751+ let mi_command = "interpreter-exec " ;
752+ if ( threadId != 0 ) {
753+ mi_command += `--thread ${ threadId } --frame ${ frameLevel } ` ;
754+ }
755+ mi_command += `console "${ command . replace ( / [ \\ " ' ] / g, '\\$&' ) } "` ;
756+ await this . sendCommand ( mi_command ) ;
757+ }
758+
726759 sendCommand ( command : string , suppressFailure : boolean = false ) : Thenable < MINode > {
727760 let sel = this . currentToken ++ ;
728761 return new Promise ( ( resolve , reject ) => {
0 commit comments