step in, out, over
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 11 Aug 2022 03:25:03 +0000 (22:25 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 11 Aug 2022 03:25:03 +0000 (22:25 -0500)
include/ovm_debug.h
src/debug/debug_thread.c
src/vm/vm.c
src/wasm/module_parsing.h

index ff40cc6fdef45954317a603a6b7e2544cfe5f60c..2037b3b2e7eeaa44532436abf8eed3375d80f09b 100644 (file)
@@ -121,6 +121,8 @@ typedef struct debug_thread_state_t {
     sem_t wait_semaphore;
 
     bool pause_at_next_line;
+    i32 pause_within;
+    i32 extra_frames_since_last_pause;
     debug_pause_reason_t pause_reason;
 
     bh_arr(debug_breakpoint_t) breakpoints;
index 7de5aae27d44c242ce9d2ee1c6a5974951e2b1aa..bffe9a91d0260db9257d74edbe339a86b14d7ce7 100644 (file)
@@ -12,7 +12,6 @@
 #define CMD_RES 1
 #define CMD_BRK 2
 #define CMD_CLR_BRK 3
-#define CMD_LOC 4
 #define CMD_STEP 5
 #define CMD_TRACE 6
 
@@ -34,9 +33,15 @@ static void send_response_header(debug_state_t *debug, unsigned int message_numb
 }
 
 static void send_string(debug_state_t *debug, const char *str) {
-    unsigned int len = strlen(str);
-    send(debug->client_fd, &len, 4, 0);
-    send(debug->client_fd, str, len, 0);
+    unsigned int len;
+    if (!str) {
+        len = 0;
+        send(debug->client_fd, &len, 4, 0);
+    } else {
+        len = strlen(str);
+        send(debug->client_fd, &len, 4, 0);
+        send(debug->client_fd, str, len, 0);
+    }
 }
 
 static void send_bytes(debug_state_t *debug, const char *bytes, unsigned int len) {
@@ -86,6 +91,10 @@ static void resume_thread(debug_thread_state_t *thread) {
 }
 
 static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
+#define ON_THREAD(tid) \
+    bh_arr_each(debug_thread_state_t *, thread, debug->threads) \
+        if ((*thread)->id == tid)
+
     u32 msg_id     = parse_int(debug, ctx);
     u32 command_id = parse_int(debug, ctx);
 
@@ -195,49 +204,47 @@ static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
             break;
         }
 
-        case CMD_LOC: {
+        case CMD_STEP: {
+            u32 granularity = parse_int(debug, ctx);
             u32 thread_id = parse_int(debug, ctx);
+            
+            if (granularity == 1) {
+                ON_THREAD(thread_id) {
+                    (*thread)->pause_at_next_line = true;
+                    (*thread)->pause_within = -1;
+                    resume_thread(*thread);
+                }
+            }
 
-            bh_arr_each(debug_thread_state_t *, thread, debug->threads) {
-                if ((*thread)->id == thread_id) {
-                    bool success = true;
-
-                    debug_loc_info_t loc_info;
-                    u32 instr = (*thread)->ovm_state->pc;
-                    while (!debug_info_lookup_location(debug->info, instr, &loc_info)) {
-                        instr++;
-                    }
-
-                    debug_file_info_t file_info;
-                    success = success && debug_info_lookup_file(debug->info, loc_info.file_id, &file_info);
+            if (granularity == 2) {
+                ON_THREAD(thread_id) {
+                    (*thread)->run_count = 1;
+                    resume_thread(*thread);
+                }
+            }
 
-                    if (success) {
-                        send_response_header(debug, msg_id);
-                        send_bool(debug, true);
-                        send_string(debug, file_info.name);
-                        send_int(debug, loc_info.line);
-                        return;
-                    }
+            if (granularity == 3) {
+                ON_THREAD(thread_id) {
+                    ovm_stack_frame_t *last_frame = &bh_arr_last((*thread)->ovm_state->stack_frames);
+                    (*thread)->pause_at_next_line = true;
+                    (*thread)->pause_within = last_frame->func->id;
+                    (*thread)->extra_frames_since_last_pause = 0;
+                    resume_thread(*thread);
                 }
             }
 
-            send_response_header(debug, msg_id);
-            send_bool(debug, false);
-            send_string(debug, "");
-            send_int(debug, -1);
-            break;
-        }
-        
-        case CMD_STEP: {
-            u32 granularity = parse_int(debug, ctx);
-            u32 thread_id = parse_int(debug, ctx);
-            
-            if (granularity == 1) {
-                bh_arr_each(debug_thread_state_t *, thread, debug->threads) {
-                    if ((*thread)->id == thread_id) {
-                        (*thread)->pause_at_next_line = true;
-                        resume_thread(*thread);
+            if (granularity == 4) {
+                ON_THREAD(thread_id) {
+                    if (bh_arr_length((*thread)->ovm_state->stack_frames) == 1) {
+                        (*thread)->pause_within = -1;
+                    } else {
+                        ovm_stack_frame_t *last_frame = &bh_arr_last((*thread)->ovm_state->stack_frames);
+                        (*thread)->pause_within = (last_frame - 1)->func->id;
                     }
+
+                    (*thread)->pause_at_next_line = true;
+                    (*thread)->extra_frames_since_last_pause = 0;
+                    resume_thread(*thread);
                 }
             }
 
@@ -276,7 +283,6 @@ static void process_command(debug_state_t *debug, struct msg_parse_ctx_t *ctx) {
                 assert(debug_info_lookup_func(debug->info, func->id, &func_info));
                 send_string(debug, func_info.name);
 
-                // :CopyPaste from CMD_LOC case
                 debug_loc_info_t loc_info;
                 debug_file_info_t file_info;
 
index 63561a59a57c2c14bfaae63317351b33c4325983..150644a2f8ddc4a91db2c7f96cc6179c8e8f3b0a 100644 (file)
@@ -691,15 +691,18 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
             }
 
             if (state->debug->pause_at_next_line) {
-                debug_loc_info_t l1, l2;
-                debug_info_lookup_location(engine->debug->info, state->pc - 1, &l1);
-                debug_info_lookup_location(engine->debug->info, state->pc,     &l2);
-
-                if (l1.file_id != l2.file_id || l1.line != l2.line) {
-                    state->debug->pause_at_next_line = false;
-                    state->debug->pause_reason = debug_pause_step;
-                    state->debug->state = debug_state_pausing;
-                    goto should_wait;
+                if (state->debug->pause_within == -1 || state->debug->pause_within == bh_arr_last(state->stack_frames).func->id) {
+
+                    debug_loc_info_t l1, l2;
+                    debug_info_lookup_location(engine->debug->info, state->pc - 1, &l1);
+                    debug_info_lookup_location(engine->debug->info, state->pc,     &l2);
+
+                    if (l1.file_id != l2.file_id || l1.line != l2.line) {
+                        state->debug->pause_at_next_line = false;
+                        state->debug->pause_reason = debug_pause_step;
+                        state->debug->state = debug_state_pausing;
+                        goto should_wait;
+                    }
                 }
             }
 
@@ -1079,6 +1082,13 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 ovm_stack_frame_t frame = ovm__func_teardown_stack_frame(engine, state, program);
                 state->pc = frame.return_address;
 
+                if (state->debug) {
+                    state->debug->extra_frames_since_last_pause--;
+                    if (state->debug->extra_frames_since_last_pause < 0) {
+                        state->debug->pause_within = -1;
+                    }
+                }
+
                 if (bh_arr_length(state->stack_frames) == 0) {
                     return val;
                 }
@@ -1114,6 +1124,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 } \
                 bh_arr_fastdeleten(state->params, func->param_count); \
  \
+                if (state->debug) state->debug->extra_frames_since_last_pause++; \
                 state->pc = func->start_instr; \
             } else { \
                 ovm__func_setup_stack_frame(engine, state, program, fidx, instr.r); \
index 8d1e2efcc5daf32be08e2addc5ea4e852d3ab393..29d01d2799acd65fba7b5db145ec7672d3c5e981 100644 (file)
@@ -509,8 +509,13 @@ static void parse_instruction(build_context *ctx) {
 
     unsigned char instr_byte = CONSUME_BYTE(ctx);
     switch (instr_byte) {
-        case 0x00: break;
-        case 0x01: break;
+        case 0x00:
+            break;
+
+        case 0x01:
+            ovm_code_builder_add_nop(&ctx->builder);
+            break;
+
         case 0x02: {
             // Currently, only "void" block types are valid.
             assert(CONSUME_BYTE(ctx) == 0x40);