From: Brendan Hansen Date: Sun, 18 Sep 2022 21:13:11 +0000 (-0500) Subject: fixed major issue with debugger X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=ead5282f26a5434434c7aad06bbd7dfa924fc66e;p=onyx.git fixed major issue with debugger --- diff --git a/compiler/include/wasm_emit.h b/compiler/include/wasm_emit.h index 3a79e549..d057f5a9 100644 --- a/compiler/include/wasm_emit.h +++ b/compiler/include/wasm_emit.h @@ -810,7 +810,7 @@ typedef struct DebugFuncContext { u32 file_id; u32 line; u32 op_offset; - u32 stack_ptr_idx; + u64 stack_ptr_idx; u32 name_length; char *name; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 83427bf3..8c7fd5df 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -391,6 +391,14 @@ static void debug_begin_function(OnyxWasmModule *mod, u32 func_idx, OnyxToken *t debug_set_position(mod, token); } +static void debug_function_set_ptr_idx(OnyxWasmModule *mod, u32 func_idx, u64 ptr_idx) { + bh_arr_each(DebugFuncContext, func, mod->debug_context->funcs) { + if (func->func_index == func_idx) { + func->stack_ptr_idx = ptr_idx; + } + } +} + static void debug_end_function(OnyxWasmModule *mod) { bh_buffer_write_byte(&mod->debug_context->op_buffer, DOT_POPF); bh_buffer_write_byte(&mod->debug_context->op_buffer, DOT_END); @@ -415,6 +423,7 @@ static void debug_leave_symbol_frame(OnyxWasmModule *mod) { #define debug_set_position(mod, token) (void)0 #define debug_emit_instruction(mod, token) (void)0 #define debug_begin_function(mod, idx, token, name) (void)0 +#define debug_function_set_ptr_idx(mod, func_idx, ptr_idx) (void)0 #define debug_end_function(mod) (void)0 #define debug_enter_symbol_frame(mod) (void)0 #define debug_leave_symbol_frame(mod) (void)0 @@ -3815,6 +3824,7 @@ static void emit_function(OnyxWasmModule* mod, AstFunction* fd) { // TODO: Emit debug info for the above instructions mod->stack_base_idx = local_raw_allocate(mod->local_alloc, WASM_TYPE_PTR); + debug_function_set_ptr_idx(mod, func_idx, mod->stack_base_idx); // Generate code emit_function_body(mod, &wasm_func.code, fd); diff --git a/interpreter/src/vm/code_builder.c b/interpreter/src/vm/code_builder.c index ec84b473..eb27a810 100644 --- a/interpreter/src/vm/code_builder.c +++ b/interpreter/src/vm/code_builder.c @@ -123,6 +123,18 @@ void ovm_code_builder_patch_else(ovm_code_builder_t *builder, label_target_t if_ } void ovm_code_builder_add_nop(ovm_code_builder_t *builder) { + // + // If debugging info was not present in the binary, + // do not create NOP instructions. NOP instructions are + // normally used as placeholders / special instructions + // to signify something weird happened, such as an expanded + // macro or operator overload. When this happens, it is + // nice to have the correct location in the source tree + // so you don't magically jump from one place to another. + // HOWEVER, if there is no debug info, then this is not + // a concern, and NOPs can be ommited. + if (builder->debug_builder->data == NULL) return; + ovm_instr_t nop = {0}; nop.full_instr = OVMI_NOP; diff --git a/interpreter/src/vm/vm.c b/interpreter/src/vm/vm.c index 28a42627..aa7e8d32 100644 --- a/interpreter/src/vm/vm.c +++ b/interpreter/src/vm/vm.c @@ -675,19 +675,6 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t ovm_value_t tmp_val; while (state->pc < bh_arr_length(program->code)) { - // This will become the line change detection - // debug_loc_info_t loc_info; - // debug_info_lookup_location(engine->debug->info, state->pc, &loc_info); - // if (loc_info.file_id != last_file || loc_info.line != last_line) { - // last_file = loc_info.file_id; - // last_line = loc_info.line; - - // debug_file_info_t file_info; - // debug_info_lookup_file(engine->debug->info, last_file, &file_info); - // - // printf("(%d, %d) %s:%d\n", last_file, last_line, file_info.name, last_line); - // } - #ifdef OVM_VERBOSE ovm_program_print_instructions(program, state->pc, 1); #endif diff --git a/misc/vscode/onyx-0.0.3.vsix b/misc/vscode/onyx-0.0.3.vsix index ba5d5157..59266f93 100644 Binary files a/misc/vscode/onyx-0.0.3.vsix and b/misc/vscode/onyx-0.0.3.vsix differ diff --git a/misc/vscode/out/ovmDebug.js b/misc/vscode/out/ovmDebug.js index 5c66268d..5fdde9ed 100644 --- a/misc/vscode/out/ovmDebug.js +++ b/misc/vscode/out/ovmDebug.js @@ -188,14 +188,30 @@ class OVMDebugSession extends debugadapter_1.LoggingDebugSession { }); } launchRequest(response, args, request) { - this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { - "cwd": args.workingDir, - }); - this.running_process.stdout.setEncoding("utf-8"); - this.running_process.stdout.on("data", (chunk) => { - this.sendEvent(new debugadapter_1.OutputEvent(chunk, "console")); + return __awaiter(this, void 0, void 0, function* () { + if (args.wasmFile) { + this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { + "cwd": args.workingDir, + }); + } + else if (args.onyxFiles) { + this.running_process = child_process.spawn("onyx", ["run", "--debug", ...args.onyxFiles], { + "cwd": args.workingDir, + }); + } + else { + this.sendErrorResponse(response, { + format: "Expected either wasmFile or onyxFiles in launch configuration.", + id: 1 + }); + return; + } + this.running_process.stdout.setEncoding("utf-8"); + this.running_process.stdout.on("data", (chunk) => { + this.sendEvent(new debugadapter_1.OutputEvent(chunk, "console")); + }); + this.attachRequest(response, { "socketPath": "/tmp/ovm-debug.0000", "stopOnEntry": args.stopOnEntry }); }); - this.attachRequest(response, { "socketPath": "/tmp/ovm-debug.0000", "stopOnEntry": args.stopOnEntry }); } attachRequest(response, args, request) { return __awaiter(this, void 0, void 0, function* () { @@ -279,6 +295,8 @@ class OVMDebugger extends EventEmitter { }); } pause(thread_id = 0xffffffff) { + if (this.client == null) + return; let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -289,6 +307,8 @@ class OVMDebugger extends EventEmitter { this.pending_responses[cmd_id] = OVMCommand.PAUSE; } resume(thread_id = 0xffffffff) { + if (this.client == null) + return; let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -300,6 +320,8 @@ class OVMDebugger extends EventEmitter { } set_breakpoint(filename, line) { return __awaiter(this, void 0, void 0, function* () { + if (this.client == null) + return Promise.resolve({}); let data = new ArrayBuffer(16 + filename.length); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -317,6 +339,8 @@ class OVMDebugger extends EventEmitter { } remove_breakpoints_in_file(filename) { return __awaiter(this, void 0, void 0, function* () { + if (this.client == null) + return Promise.resolve(false); let data = new ArrayBuffer(12 + filename.length); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -332,6 +356,8 @@ class OVMDebugger extends EventEmitter { }); } step(granularity, thread_id) { + if (this.client == null) + return; let data = new ArrayBuffer(16); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -356,6 +382,8 @@ class OVMDebugger extends EventEmitter { this.pending_responses[cmd_id] = OVMCommand.STEP; } trace(thread_id) { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(12); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -367,6 +395,8 @@ class OVMDebugger extends EventEmitter { return this.preparePromise(cmd_id); } threads() { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(8); let view = new DataView(data); let cmd_id = this.next_command_id; @@ -377,6 +407,8 @@ class OVMDebugger extends EventEmitter { return this.preparePromise(cmd_id); } variables(frame_index, thread_id) { + if (this.client == null) + return Promise.resolve([]); let data = new ArrayBuffer(16); let view = new DataView(data); let cmd_id = this.next_command_id; diff --git a/misc/vscode/ovmDebug.ts b/misc/vscode/ovmDebug.ts index 08d85494..f646927f 100644 --- a/misc/vscode/ovmDebug.ts +++ b/misc/vscode/ovmDebug.ts @@ -12,6 +12,7 @@ import { Subject } from "await-notify"; import * as net from "node:net"; import * as child_process from "node:child_process"; import { ChildProcess } from 'node:child_process'; +import { openStdin } from 'node:process'; interface IOVMAttachRequestArguments extends DebugProtocol.AttachRequestArguments { @@ -20,7 +21,8 @@ interface IOVMAttachRequestArguments extends DebugProtocol.AttachRequestArgument } interface IOVMLaunchRequestArguments extends DebugProtocol.AttachRequestArguments { - wasmFile: string; + wasmFile?: string; + onyxFiles?: [string]; workingDir: string; stopOnEntry?: boolean; } @@ -257,10 +259,25 @@ export class OVMDebugSession extends LoggingDebugSession { this.sendResponse(response); } - protected launchRequest(response: DebugProtocol.LaunchResponse, args: IOVMLaunchRequestArguments, request?: DebugProtocol.Request): void { - this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { - "cwd": args.workingDir, - }); + protected async launchRequest(response: DebugProtocol.LaunchResponse, args: IOVMLaunchRequestArguments, request?: DebugProtocol.Request): Promise { + if (args.wasmFile) { + this.running_process = child_process.spawn("onyx-run", ["--debug", args.wasmFile], { + "cwd": args.workingDir, + }); + + } else if (args.onyxFiles) { + this.running_process = child_process.spawn("onyx", ["run", "--debug", ...args.onyxFiles], { + "cwd": args.workingDir, + }); + + } else { + this.sendErrorResponse(response, { + format: "Expected either wasmFile or onyxFiles in launch configuration.", + id: 1 + } as DebugProtocol.Message); + + return; + } this.running_process.stdout.setEncoding("utf-8"); this.running_process.stdout.on("data", (chunk) => { @@ -398,6 +415,8 @@ class OVMDebugger extends EventEmitter { } pause(thread_id: number = 0xffffffff): void { + if (this.client == null) return; + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -413,6 +432,8 @@ class OVMDebugger extends EventEmitter { } resume(thread_id: number = 0xffffffff): void { + if (this.client == null) return; + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -428,6 +449,8 @@ class OVMDebugger extends EventEmitter { } async set_breakpoint(filename: string, line: number): Promise { + if (this.client == null) return Promise.resolve({} as IBreakpointValidation); + let data = new ArrayBuffer(16+filename.length); let view = new DataView(data); @@ -450,6 +473,8 @@ class OVMDebugger extends EventEmitter { } async remove_breakpoints_in_file(filename: string): Promise { + if (this.client == null) return Promise.resolve(false); + let data = new ArrayBuffer(12+filename.length); let view = new DataView(data); @@ -471,6 +496,8 @@ class OVMDebugger extends EventEmitter { } step(granularity: "line" | "instruction" | "over" | "out", thread_id: number): void { + if (this.client == null) return; + let data = new ArrayBuffer(16); let view = new DataView(data); @@ -493,6 +520,8 @@ class OVMDebugger extends EventEmitter { } trace(thread_id: number): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(12); let view = new DataView(data); @@ -510,6 +539,8 @@ class OVMDebugger extends EventEmitter { } threads(): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(8); let view = new DataView(data); @@ -526,6 +557,8 @@ class OVMDebugger extends EventEmitter { } variables(frame_index: number, thread_id: number): Promise { + if (this.client == null) return Promise.resolve([]); + let data = new ArrayBuffer(16); let view = new DataView(data); diff --git a/misc/vscode/package.json b/misc/vscode/package.json index 8ad40eaa..7bbd3ff0 100644 --- a/misc/vscode/package.json +++ b/misc/vscode/package.json @@ -14,6 +14,9 @@ "activationEvents": [ "onLanguage:onyx" ], + "repository": { + "url": "https://github.com/onyx-lang/onyx" + }, "icon": "logo.png", "main": "./out/extension.js", "contributes": { @@ -88,6 +91,11 @@ "description": "The WASM file for debugging, compiled with the --debug flag.", "default": "out.wasm" }, + "onyxFiles": { + "type": "array", + "description": "The Onyx files for compiling.", + "default": "[]" + }, "workingDir": { "type": "string", "description": "The working directory for the execution", @@ -103,11 +111,14 @@ }, "initialConfigurations": [ { + "name": "Onyx Attach", "type": "onyx", "request": "attach", - "stopOnEntry": true + "stopOnEntry": true, + "socketPath": "/tmp/ovm-debug.0000" }, { + "name": "Onyx Launch", "type": "onyx", "request": "launch", "wasmFile": "out.wasm",