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,60 @@ 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 ;
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 ret : Thread = {
602+ id : parseInt ( MINode . valueOf ( element , "id" ) ) ,
603+ targetId : MINode . valueOf ( element , "target-id" )
604+ } ;
605+
606+ let name = MINode . valueOf ( element , "name" ) ;
607+ if ( name ) {
608+ ret . name = name ;
594609 }
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 ) ;
610+
611+ return ret ;
612+ } ) ;
613+ }
614+
615+ async getStack ( maxLevels : number , thread : number ) : Promise < Stack [ ] > {
616+ if ( trace ) this . log ( "stderr" , "getStack" ) ;
617+
618+ let command = "stack-list-frames" ;
619+ if ( thread != 0 ) {
620+ command += ` --thread ${ thread } ` ;
621+ }
622+ if ( maxLevels ) {
623+ command += " 0 " + maxLevels ;
624+ }
625+ let result = await this . sendCommand ( command ) ;
626+ let stack = result . result ( "stack" ) ;
627+ let ret : Stack [ ] = [ ] ;
628+ return stack . map ( element => {
629+ let level = MINode . valueOf ( element , "@frame.level" ) ;
630+ let addr = MINode . valueOf ( element , "@frame.addr" ) ;
631+ let func = MINode . valueOf ( element , "@frame.func" ) ;
632+ let filename = MINode . valueOf ( element , "@frame.file" ) ;
633+ let file = MINode . valueOf ( element , "@frame.fullname" ) ;
634+ let line = 0 ;
635+ let lnstr = MINode . valueOf ( element , "@frame.line" ) ;
636+ if ( lnstr )
637+ line = parseInt ( lnstr ) ;
638+ let from = parseInt ( MINode . valueOf ( element , "@frame.from" ) ) ;
639+ return {
640+ address : addr ,
641+ fileName : filename ,
642+ file : file ,
643+ function : func || from ,
644+ level : level ,
645+ line : line
646+ } ;
620647 } ) ;
621648 }
622649
@@ -651,14 +678,17 @@ export class MI2 extends EventEmitter implements IBackend {
651678 } ) ;
652679 }
653680
654- evalExpression ( name : string ) : Thenable < any > {
681+ async evalExpression ( name : string , thread : number , frame : number ) : Promise < MINode > {
655682 if ( trace )
656683 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- } ) ;
684+
685+ let command = "data-evaluate-expression " ;
686+ if ( thread != 0 ) {
687+ command += `--thread ${ thread } --frame ${ frame } ` ;
688+ }
689+ command += name ;
690+
691+ return await this . sendCommand ( command ) ;
662692 }
663693
664694 async varCreate ( expression : string , name : string = "-" ) : Promise < VariableObject > {
@@ -704,13 +734,12 @@ export class MI2 extends EventEmitter implements IBackend {
704734 this . emit ( "msg" , type , msg [ msg . length - 1 ] == '\n' ? msg : ( msg + "\n" ) ) ;
705735 }
706736
707- sendUserInput ( command : string ) : Thenable < any > {
737+ sendUserInput ( command : string , threadId : number = 0 , frameLevel : number = 0 ) : Thenable < any > {
708738 if ( command . startsWith ( "-" ) ) {
709739 return this . sendCommand ( command . substr ( 1 ) ) ;
710740 }
711741 else {
712- this . sendRaw ( command ) ;
713- return Promise . resolve ( undefined ) ;
742+ return this . sendCliCommand ( command , threadId , frameLevel ) ;
714743 }
715744 }
716745
@@ -723,6 +752,15 @@ export class MI2 extends EventEmitter implements IBackend {
723752 this . process . stdin . write ( raw + "\n" ) ;
724753 }
725754
755+ async sendCliCommand ( command : string , threadId : number = 0 , frameLevel : number = 0 ) {
756+ let mi_command = "interpreter-exec " ;
757+ if ( threadId != 0 ) {
758+ mi_command += `--thread ${ threadId } --frame ${ frameLevel } ` ;
759+ }
760+ mi_command += `console "${ command . replace ( / [ \\ " ' ] / g, '\\$&' ) } "` ;
761+ await this . sendCommand ( mi_command ) ;
762+ }
763+
726764 sendCommand ( command : string , suppressFailure : boolean = false ) : Thenable < MINode > {
727765 let sel = this . currentToken ++ ;
728766 return new Promise ( ( resolve , reject ) => {
0 commit comments