@@ -19,13 +19,6 @@ static void js_process_breakpoints(JSDebuggerInfo* info,
19
19
SourceBreakpoint * breakpoints ,
20
20
size_t breakpointsLen );
21
21
22
- typedef struct DebuggerSuspendedState {
23
- uint32_t variable_reference_count ;
24
- JSValue variable_references ;
25
- JSValue variable_pointers ;
26
- const uint8_t * cur_pc ;
27
- } DebuggerSuspendedState ;
28
-
29
22
typedef struct VariableType {
30
23
const char * type ;
31
24
int64_t variablesReference ;
@@ -111,6 +104,18 @@ static void init_scope(Scope* scope) {
111
104
scope -> endColumn = NAN ;
112
105
}
113
106
107
+ static void init_variable (Variable * variable ) {
108
+ variable -> name = NULL ;
109
+ variable -> value = NULL ;
110
+ variable -> type = NULL ;
111
+ variable -> presentationHint = NULL ;
112
+ variable -> evaluateName = NULL ;
113
+ variable -> variablesReference = NAN ;
114
+ variable -> namedVariables = NAN ;
115
+ variable -> indexedVariables = NAN ;
116
+ variable -> memoryReference = NULL ;
117
+ }
118
+
114
119
115
120
// Handler for read backend messages from Dart Client.
116
121
static uint32_t handle_client_read (void * ptr , DebuggerMessage * message ) {
@@ -249,7 +254,7 @@ static void js_get_scopes(JSContext* ctx, int64_t frame, ScopesResponseBody* bod
249
254
// Get global
250
255
scopes [2 ].name = "Global" ;
251
256
scopes [2 ].variablesReference = (frame << 2 ) + 0 ;
252
- scopes [2 ].expensive = 0 ;
257
+ scopes [2 ].expensive = 1 ;
253
258
254
259
body -> scopes = scopes ;
255
260
body -> scopesLen = 3 ;
@@ -447,23 +452,23 @@ static void process_request(JSDebuggerInfo* info, struct DebuggerSuspendedState*
447
452
VariablesArguments * arguments = (VariablesArguments * )request -> arguments ;
448
453
int64_t reference = arguments -> variablesReference ;
449
454
JSValue variable = JS_GetPropertyUint32 (ctx , state -> variable_references , reference );
450
- Variable * variables ;
455
+ Variable * variables = NULL ;
451
456
size_t variableLen = 0 ;
452
457
453
458
int skip_proto = 0 ;
454
459
// if the variable reference was not found,
455
460
// then it must be a frame locals, frame closures, or the global
456
461
if (JS_IsUndefined (variable )) {
457
462
skip_proto = 1 ;
458
- int64_t frame = reference >> 2 ;
463
+ int64_t frame = ( reference >> 2 ) - 1 ;
459
464
int64_t scope = reference % 4 ;
460
465
461
466
assert (frame < js_debugger_stack_depth (ctx ));
462
467
463
468
if (scope == 0 )
464
469
variable = JS_GetGlobalObject (ctx );
465
470
else if (scope == 1 )
466
- variable = js_debugger_local_variables (ctx , frame );
471
+ variable = js_debugger_local_variables (ctx , frame , state );
467
472
else if (scope == 2 )
468
473
variable = js_debugger_closure_variables (ctx , frame );
469
474
else
@@ -497,46 +502,53 @@ static void process_request(JSDebuggerInfo* info, struct DebuggerSuspendedState*
497
502
js_debugger_get_variable_type (ctx , state , & variable_type , value );
498
503
499
504
sprintf (name_buf , "%d" , i );
505
+ init_variable (& variables [i ]);
500
506
variables [i ].name = copy_string (name_buf , strlen (name_buf ));
501
507
variables [i ].type = variable_type .type ;
502
508
variables [i ].variablesReference = variable_type .variablesReference ;
503
509
variables [i ].value = to_json_string (ctx , value );
504
510
511
+ assert (variables [i ].name != NULL );
512
+ assert (variables [i ].value != NULL );
505
513
JS_FreeValue (ctx , value );
506
514
}
507
515
goto done ;
508
516
}
509
517
510
518
unfiltered :
511
- if (!JS_GetOwnPropertyNames (ctx , & tab_atom , & tab_atom_count , variable , JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK )) {
519
+ if (!JS_GetOwnPropertyNames (ctx , & tab_atom , & tab_atom_count , variable , JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK )) {
512
520
int offset = 0 ;
521
+ variables = js_malloc (ctx , sizeof (Variable ) * (tab_atom_count + (skip_proto ? 0 : 1 )));
513
522
514
523
if (!skip_proto ) {
515
524
const JSValue proto = JS_GetPrototype (ctx , variable );
516
525
if (!JS_IsException (proto )) {
517
- JSValue value = JS_GetPropertyStr (ctx , state -> variable_references , "__proto__" );
518
-
519
526
VariableType variable_type ;
520
- js_debugger_get_variable_type (ctx , state , & variable_type , value );
521
-
522
- variables [offset ++ ].name = "__proto__" ;
523
- variables [offset ++ ].value = to_json_string (ctx , value );
524
- variables [offset ++ ].type = variable_type .type ;
525
- variables [offset ++ ].variablesReference = variable_type .variablesReference ;
526
- JS_FreeValue (ctx , value );
527
+ js_debugger_get_variable_type (ctx , state , & variable_type , proto );
528
+ int i = offset ++ ;
529
+ init_variable (& variables [i ]);
530
+ variables [i ].name = "[[Prototype]]" ;
531
+ variables [i ].value = to_json_string (ctx , proto );
532
+ variables [i ].type = variable_type .type ;
533
+ variables [i ].variablesReference = variable_type .variablesReference ;
534
+ assert (variables [i ].name != NULL );
535
+ assert (variables [i ].value != NULL );
527
536
}
528
537
JS_FreeValue (ctx , proto );
529
538
}
530
539
531
540
for (int i = 0 ; i < tab_atom_count ; i ++ ) {
532
541
JSValue value = JS_GetProperty (ctx , variable , tab_atom [i ].atom );
533
-
542
+ printf ( "atom %s %p\n" , info -> runtime -> atom_array [ tab_atom [ i ]. atom ] -> u . str8 , JS_VALUE_GET_PTR ( value ));
534
543
VariableType variable_type ;
535
544
js_debugger_get_variable_type (ctx , state , & variable_type , value );
545
+ init_variable (& variables [i + offset ]);
536
546
variables [i + offset ].name = atom_to_string (ctx , tab_atom [i ].atom );
537
547
variables [i + offset ].type = variable_type .type ;
538
548
variables [i + offset ].variablesReference = variable_type .variablesReference ;
539
549
variables [i + offset ].value = to_json_string (ctx , value );
550
+ assert (variables [i + offset ].name != NULL );
551
+ assert (variables [i + offset ].value != NULL );
540
552
JS_FreeValue (ctx , value );
541
553
}
542
554
@@ -546,7 +558,7 @@ static void process_request(JSDebuggerInfo* info, struct DebuggerSuspendedState*
546
558
547
559
done :
548
560
JS_FreeValue (ctx , variable );
549
- VariablesResponse * response = initialize_response (ctx , request , "variable " );
561
+ VariablesResponse * response = initialize_response (ctx , request , "variables " );
550
562
response -> body -> variables = variables ;
551
563
response -> body -> variablesLen = variableLen ;
552
564
js_transport_send_response (info , ctx , (Response * ) response );
@@ -588,14 +600,15 @@ BreakPointMapItem* js_debugger_file_breakpoints(JSContext* ctx, const char* path
588
600
return item ;
589
601
}
590
602
591
- static void js_process_debugger_messages (JSDebuggerInfo * info , const uint8_t * cur_pc ) {
603
+ static void js_process_debugger_messages (JSDebuggerInfo * info , const uint8_t * cur_pc , JSValue this_object ) {
592
604
// continue processing messages until the continue message is received.
593
605
JSContext * ctx = info -> ctx ;
594
606
struct DebuggerSuspendedState state ;
595
607
state .variable_reference_count = js_debugger_stack_depth (ctx ) << 2 ;
596
608
state .variable_pointers = JS_NewObject (ctx );
597
609
state .variable_references = JS_NewObject (ctx );
598
610
state .cur_pc = cur_pc ;
611
+ state .this_object = this_object ;
599
612
600
613
do {
601
614
MessageItem item ;
@@ -622,7 +635,7 @@ void js_debugger_exception(JSContext* ctx) {
622
635
info -> ctx = ctx ;
623
636
js_send_stopped_event (info , "exception" );
624
637
info -> is_paused = 1 ;
625
- js_process_debugger_messages (info , NULL );
638
+ js_process_debugger_messages (info , NULL , JS_NULL );
626
639
info -> is_debugging = 0 ;
627
640
info -> ctx = NULL ;
628
641
}
@@ -653,7 +666,7 @@ void js_debugger_free_context(JSContext* ctx) {
653
666
654
667
// in thread check request/response of pending commands.
655
668
// todo: background thread that reads the socket.
656
- void js_debugger_check (JSContext * ctx , const uint8_t * cur_pc ) {
669
+ void js_debugger_check (JSContext * ctx , const uint8_t * cur_pc , JSValue this_object ) {
657
670
JSDebuggerInfo * info = js_debugger_info (JS_GetRuntime (ctx ));
658
671
if (info -> is_debugging )
659
672
return ;
@@ -734,7 +747,7 @@ void js_debugger_check(JSContext* ctx, const uint8_t* cur_pc) {
734
747
}
735
748
}
736
749
737
- js_process_debugger_messages (info , cur_pc );
750
+ js_process_debugger_messages (info , cur_pc , this_object );
738
751
739
752
done :
740
753
info -> is_debugging = 0 ;
@@ -850,7 +863,7 @@ void js_debugger_build_backtrace(JSContext* ctx, const uint8_t* cur_pc, StackTra
850
863
851
864
init_stackframe (& stack_frames [id ]);
852
865
853
- stack_frames [id ].id = id ;
866
+ stack_frames [id ].id = id + 1 ;
854
867
func_name_str = get_func_name (ctx , sf -> cur_func );
855
868
if (!func_name_str || func_name_str [0 ] == '\0' ) {
856
869
stack_frames [id ].name = "<anonymous>" ;
@@ -869,7 +882,7 @@ void js_debugger_build_backtrace(JSContext* ctx, const uint8_t* cur_pc, StackTra
869
882
if (b -> has_debug ) {
870
883
const uint8_t * pc = sf != ctx -> rt -> current_stack_frame || !cur_pc ? sf -> cur_pc : cur_pc ;
871
884
line_num1 = find_line_num (ctx , b , pc - b -> byte_code_buf - 1 );
872
- column_num1 = find_column_num (ctx , b , pc - b -> byte_code_buf - 1 );
885
+ column_num1 = find_column_num (ctx , b , pc - b -> byte_code_buf - 1 ) + 1 ;
873
886
if (line_num1 != -1 ) {
874
887
stack_frames [id ].line = line_num1 ;
875
888
}
@@ -1006,7 +1019,7 @@ int js_debugger_check_breakpoint(JSContext* ctx, uint32_t current_dirty, const u
1006
1019
return b -> debugger .breakpoints [pc ];
1007
1020
}
1008
1021
1009
- JSValue js_debugger_local_variables (JSContext * ctx , int64_t stack_index ) {
1022
+ JSValue js_debugger_local_variables (JSContext * ctx , int64_t stack_index , struct DebuggerSuspendedState * state ) {
1010
1023
JSValue ret = JS_NewObject (ctx );
1011
1024
1012
1025
// put exceptions on the top stack frame
@@ -1017,25 +1030,18 @@ JSValue js_debugger_local_variables(JSContext* ctx, int64_t stack_index) {
1017
1030
int cur_index = 0 ;
1018
1031
1019
1032
for (sf = ctx -> rt -> current_stack_frame ; sf != NULL ; sf = sf -> prev_frame ) {
1020
- // this val is one frame up
1021
- if (cur_index == stack_index - 1 ) {
1022
- JSObject * f = JS_VALUE_GET_OBJ (sf -> cur_func );
1023
- if (f && js_class_has_bytecode (f -> class_id )) {
1024
- JSFunctionBytecode * b = f -> u .func .function_bytecode ;
1025
-
1026
- JSValue this_obj = sf -> var_buf [b -> var_count ];
1027
- // only provide a this if it is not the global object.
1028
- if (JS_VALUE_GET_OBJ (this_obj ) != JS_VALUE_GET_OBJ (ctx -> global_obj ))
1029
- JS_SetPropertyStr (ctx , ret , "this" , JS_DupValue (ctx , this_obj ));
1030
- }
1033
+ JSObject * f = JS_VALUE_GET_OBJ (sf -> cur_func );
1034
+ if (f && js_class_has_bytecode (f -> class_id )) {
1035
+ // only provide a this if it is not the global object.
1036
+ if (JS_VALUE_GET_OBJ (state -> this_object ) != JS_VALUE_GET_OBJ (ctx -> global_obj ))
1037
+ JS_SetPropertyStr (ctx , ret , "this" , JS_DupValue (ctx , state -> this_object ));
1031
1038
}
1032
1039
1033
1040
if (cur_index < stack_index ) {
1034
1041
cur_index ++ ;
1035
1042
continue ;
1036
1043
}
1037
1044
1038
- JSObject * f = JS_VALUE_GET_OBJ (sf -> cur_func );
1039
1045
if (!f || !js_class_has_bytecode (f -> class_id ))
1040
1046
goto done ;
1041
1047
JSFunctionBytecode * b = f -> u .func .function_bytecode ;
0 commit comments