@@ -971,6 +971,131 @@ static void get_uint8array(void)
971971 JS_FreeRuntime (rt );
972972}
973973
974+ static struct {
975+ int call_count ;
976+ int last_line ;
977+ int last_col ;
978+ char last_filename [256 ];
979+ char last_funcname [256 ];
980+ int stack_depth ;
981+ int max_local_count ;
982+ int abort_at ; /* abort (return -1) on this call, 0 = never */
983+ } trace_state ;
984+
985+ static int debug_trace_cb (JSContext * ctx ,
986+ const char * filename ,
987+ const char * funcname ,
988+ int line ,
989+ int col ,
990+ void * opaque )
991+ {
992+ trace_state .call_count ++ ;
993+ trace_state .last_line = line ;
994+ trace_state .last_col = col ;
995+ snprintf (trace_state .last_filename , sizeof (trace_state .last_filename ),
996+ "%s" , filename );
997+ snprintf (trace_state .last_funcname , sizeof (trace_state .last_funcname ),
998+ "%s" , funcname );
999+ trace_state .stack_depth = JS_GetStackDepth (ctx );
1000+ int count = 0 ;
1001+ JSDebugLocalVar * vars = NULL ;
1002+ assert (JS_GetLocalVariablesAtLevel (ctx , 0 , & vars , & count ) == 0 );
1003+ if (count > trace_state .max_local_count )
1004+ trace_state .max_local_count = count ;
1005+ if (vars )
1006+ JS_FreeLocalVariables (ctx , vars , count );
1007+ if (trace_state .abort_at > 0 &&
1008+ trace_state .call_count >= trace_state .abort_at )
1009+ return -1 ;
1010+ return 0 ;
1011+ }
1012+
1013+ static void debug_trace (void )
1014+ {
1015+ JSRuntime * rt = JS_NewRuntime ();
1016+ JSContext * ctx = JS_NewContext (rt );
1017+
1018+ memset (& trace_state , 0 , sizeof (trace_state ));
1019+ {
1020+ JSValue ret = eval (ctx , "1+2" );
1021+ assert (!JS_IsException (ret ));
1022+ JS_FreeValue (ctx , ret );
1023+ assert (trace_state .call_count == 0 );
1024+ }
1025+
1026+ JS_SetDebugTraceHandler (ctx , debug_trace_cb , NULL );
1027+ memset (& trace_state , 0 , sizeof (trace_state ));
1028+ {
1029+ JSValue ret = eval (ctx , "var x = 1; x + 2" );
1030+ assert (!JS_IsException (ret ));
1031+ JS_FreeValue (ctx , ret );
1032+ assert (trace_state .call_count > 0 );
1033+ assert (!strcmp (trace_state .last_filename , "<input>" ));
1034+ }
1035+
1036+ {
1037+ JSDebugLocalVar * vars = NULL ;
1038+ int count = -1 ;
1039+ assert (JS_GetLocalVariablesAtLevel (ctx , 0 , & vars , & count ) == 0 );
1040+ assert (vars == NULL );
1041+ assert (count == 0 );
1042+ }
1043+
1044+ memset (& trace_state , 0 , sizeof (trace_state ));
1045+ {
1046+ static const char code [] =
1047+ "function outer() {\n"
1048+ " function inner() {\n"
1049+ " return 42;\n"
1050+ " }\n"
1051+ " return inner();\n"
1052+ "}\n"
1053+ "outer();\n" ;
1054+ JSValue ret = eval (ctx , code );
1055+ assert (!JS_IsException (ret ));
1056+ JS_FreeValue (ctx , ret );
1057+ assert (trace_state .call_count > 0 );
1058+ assert (trace_state .stack_depth >= 1 );
1059+ }
1060+
1061+ memset (& trace_state , 0 , sizeof (trace_state ));
1062+ {
1063+ static const char code [] =
1064+ "function f(a, b) {\n"
1065+ " var c = a + b;\n"
1066+ " return c;\n"
1067+ "}\n"
1068+ "f(10, 20);\n" ;
1069+ JSValue ret = eval (ctx , code );
1070+ assert (!JS_IsException (ret ));
1071+ JS_FreeValue (ctx , ret );
1072+ assert (trace_state .call_count > 0 );
1073+ assert (trace_state .max_local_count >= 2 );
1074+ }
1075+
1076+ memset (& trace_state , 0 , sizeof (trace_state ));
1077+ trace_state .abort_at = 1 ;
1078+ {
1079+ JSValue ret = eval (ctx , "1+2; 3+4" );
1080+ assert (JS_IsException (ret ));
1081+ JS_FreeValue (ctx , ret );
1082+ JSValue exc = JS_GetException (ctx );
1083+ JS_FreeValue (ctx , exc );
1084+ }
1085+
1086+ JS_SetDebugTraceHandler (ctx , NULL , NULL );
1087+ memset (& trace_state , 0 , sizeof (trace_state ));
1088+ {
1089+ JSValue ret = eval (ctx , "1+2" );
1090+ assert (!JS_IsException (ret ));
1091+ JS_FreeValue (ctx , ret );
1092+ assert (trace_state .call_count == 0 );
1093+ }
1094+
1095+ JS_FreeContext (ctx );
1096+ JS_FreeRuntime (rt );
1097+ }
1098+
9741099static void new_symbol (void )
9751100{
9761101 JSRuntime * rt = new_runtime ();
@@ -1046,6 +1171,7 @@ int main(void)
10461171 slice_string_tocstring ();
10471172 immutable_array_buffer ();
10481173 get_uint8array ();
1174+ debug_trace ();
10491175 new_symbol ();
10501176 return 0 ;
10511177}
0 commit comments