#overload
builtin.__make_overload :: macro (_: ^[] $T, count: u32, allocator := context.allocator) -> [] T {
ret := (package core.memory).make_slice(T, count, allocator);
- memory.set(ret.data, 0, sizeof T * count);
+ (package core.memory).set(ret.data, 0, sizeof T * count);
return ret;
}
// through the first thread.
ovm_program_t *prog = debug->threads[0]->ovm_state->program;
+ debug_loc_info_t loc_info;
+ u32 last_file_id = 0xffffffff;
+
while (addr < bh_arr_length(prog->code) && count--) {
send_int(debug, 0);
send_bytes(debug, instr_buf.data, instr_buf.length);
bh_buffer_clear(&instr_buf);
+ debug_info_lookup_location(debug->info, addr, &loc_info);
+ send_int(debug, loc_info.line);
+
+ if (loc_info.file_id != last_file_id) {
+ send_bool(debug, true);
+ send_string(debug, debug->info->files[loc_info.file_id].name);
+
+ last_file_id = loc_info.file_id;
+ } else {
+ send_bool(debug, false);
+ }
+
addr += 1;
}
#define PUSH_VALUE(b, r) (bh_arr_push((b)->execution_stack, r))
+#define LAST_VALUE(b) bh_arr_last((b)->execution_stack)
+
+#define IS_TEMPORARY_VALUE(b, r) (r >= (b->param_count + b->local_count))
+
static inline int NEXT_VALUE(ovm_code_builder_t *b) {
#if defined(BUILDER_DEBUG)
b->highest_value_number += 1;
}
void ovm_code_builder_add_local_set(ovm_code_builder_t *builder, i32 local_idx) {
+ // :PrimitiveOptimization
+ // Perform a simple optimization that an immediate temporary moved to
+ // a local can be optimized as an immediate loaded directly to a local.
+ {
+ ovm_instr_t *last_instr = &bh_arr_last(builder->program->code);
+ if (OVM_INSTR_INSTR(*last_instr) == OVMI_IMM) {
+ if (IS_TEMPORARY_VALUE(builder, last_instr->r)
+ && last_instr->r == LAST_VALUE(builder)) {
+ last_instr->r = local_idx;
+ POP_VALUE(builder);
+ return;
+ }
+ }
+ }
+
ovm_instr_t instr = {0};
instr.full_instr = OVM_TYPED_INSTR(OVMI_MOV, OVM_TYPE_NONE);
instr.r = local_idx; // This makes the assumption that the params will be in
case instr_format_idx_arr: formatted = snprintf(buf, 255, "%%%d, __global_arr_%d[%%%d]", instr->r, instr->a, instr->b); break;
- case instr_format_br: formatted = snprintf(buf, 255, "%d", instr_addr + instr->a); break;
- case instr_format_br_cond: formatted = snprintf(buf, 255, "%d, %%%d", instr_addr + instr->a, instr->b); break;
+ case instr_format_br: formatted = snprintf(buf, 255, "%d", instr_addr + instr->a + 1); break;
+ case instr_format_br_cond: formatted = snprintf(buf, 255, "%d, %%%d", instr_addr + instr->a + 1, instr->b); break;
case instr_format_bri: formatted = snprintf(buf, 255, "ip + %%%d", instr->a); break;
case instr_format_bri_cond: formatted = snprintf(buf, 255, "ip + %%%d, %%%d", instr->a, instr->b); break;
// But Onyx does not do this, so I don't care at the moment.
module->program->register_count = module->globaltypes.size;
+ #if 0
+ printf("Program instruction count: %d\n", bh_arr_length(module->program->code));
+ #endif
+
return true;
}
this._variableReferences.reset();
response.body = {
stackFrames: frames.map((f, i) => {
- let source = new debugadapter_1.Source(this.fileNameToShortName(f.filename), this.convertDebuggerPathToClient(f.filename), undefined, undefined, "ovm-debug-src");
- if (!this._loadedSources.has(source.name)) {
- this._loadedSources.set(source.name, source);
- this.sendEvent(new debugadapter_1.LoadedSourceEvent("new", source));
- }
+ let source = this.loadSource(f.filename);
let frameRef = this._frameReferences.create({
threadId: args.threadId,
frameIndex: i
}
disassembleRequest(response, args, request) {
return __awaiter(this, void 0, void 0, function* () {
- console.log(args);
let addr = parseInt(args.memoryReference) + args.offset;
let instrs = yield this.debugger.disassemble(addr, args.instructionCount);
response.body = {
instructions: instrs.map((i, index) => {
+ let source;
+ if (i.newSource != null) {
+ source = this.loadSource(i.newSource);
+ }
return {
address: (index + addr).toString(),
- instruction: i.instr
+ instruction: i.instr,
+ line: i.line,
+ location: source,
};
})
};
fileNameToShortName(filename) {
return filename.substring(filename.lastIndexOf("/") + 1);
}
+ loadSource(filename) {
+ let source = new debugadapter_1.Source(this.fileNameToShortName(filename), this.convertDebuggerPathToClient(filename), undefined, undefined, "ovm-debug-src");
+ if (!this._loadedSources.has(source.name)) {
+ this._loadedSources.set(source.name, source);
+ this.sendEvent(new debugadapter_1.LoadedSourceEvent("new", source));
+ }
+ return source;
+ }
}
exports.OVMDebugSession = OVMDebugSession;
var OVMCommand;
let result = new Array();
while (parser.parseInt32() == 0) {
let instr = parser.parseString();
- result.push({ instr });
+ let line = parser.parseUint32();
+ let newSource = null;
+ if (parser.parseBool()) {
+ newSource = parser.parseString();
+ }
+ result.push({ instr, line, newSource });
}
this.resolvePromise(msg_id, result);
break;
response.body = {
stackFrames: frames.map((f, i) => {
- let source = new Source(
- this.fileNameToShortName(f.filename),
- this.convertDebuggerPathToClient(f.filename),
- undefined, undefined, "ovm-debug-src"
- );
-
- if (!this._loadedSources.has(source.name)) {
- this._loadedSources.set(source.name, source);
-
- this.sendEvent(new LoadedSourceEvent("new", source));
- }
-
+ let source = this.loadSource(f.filename);
+
let frameRef = this._frameReferences.create({
threadId: args.threadId,
frameIndex: i
response.body = {
instructions: instrs.map((i, index) => {
+ let source: DebugProtocol.Source | null;
+ if (i.newSource != null) {
+ source = this.loadSource(i.newSource);
+ }
+
return {
- address: (index + addr - 1).toString(),
+ address: (index + addr).toString(),
instruction: i.instr,
+ line: i.line,
+ location: source,
};
})
};
private fileNameToShortName(filename: string): string {
return filename.substring(filename.lastIndexOf("/") + 1);
}
+
+ private loadSource(filename: string): Source {
+ let source = new Source(
+ this.fileNameToShortName(filename),
+ this.convertDebuggerPathToClient(filename),
+ undefined, undefined, "ovm-debug-src"
+ );
+
+ if (!this._loadedSources.has(source.name)) {
+ this._loadedSources.set(source.name, source);
+
+ this.sendEvent(new LoadedSourceEvent("new", source));
+ }
+
+ return source;
+ }
}
interface IFileLocation {
interface IDisassembledInstruction {
instr: string;
+ line: number;
+ newSource?: string;
}
enum OVMCommand {
while (parser.parseInt32() == 0) {
let instr = parser.parseString();
- result.push({ instr });
+ let line = parser.parseUint32();
+
+ let newSource: string | null = null;
+ if (parser.parseBool()) {
+ newSource = parser.parseString();
+ }
+
+ result.push({ instr, line, newSource });
}
this.resolvePromise(msg_id, result);
"name": "onyx",
"displayName": "Onyx",
"description": "Onyx syntax highlighting.",
- "version": "0.1.1",
+ "version": "0.1.3",
"publisher": "brendanfh",
"license": "BSD-2-Clause",
"engines": {