From 65755d9c0ce513dd281c4348da3d39ec6f12e5c4 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 12 Feb 2026 17:17:12 -0600 Subject: [PATCH] fix using old mach --- internal/shop.cm | 9 ++++++++- source/cell.c | 12 ++++++++++++ source/mach.c | 40 ++++++++++++++++++++++++++++++++------- source/quickjs-internal.h | 5 ----- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/internal/shop.cm b/internal/shop.cm index aba4a917..7ac18aae 100644 --- a/internal/shop.cm +++ b/internal/shop.cm @@ -438,6 +438,7 @@ function resolve_mod_fn(path, pkg) { var compiled = null var mach_path = null var mach_blob = null + var mcode_path = null var ir = null var optimized = null @@ -446,7 +447,7 @@ function resolve_mod_fn(path, pkg) { return cached } - // Check for pre-compiled .mach file alongside .cm source + // Check for pre-compiled .mach or .mcode file alongside .cm source if (ends_with(path, '.cm')) { mach_path = text(path, 0, length(path) - 3) + '.mach' if (fd.is_file(mach_path)) { @@ -454,6 +455,12 @@ function resolve_mod_fn(path, pkg) { put_into_cache(stone(blob(content)), mach_blob) return mach_blob } + mcode_path = path + '.mcode' + if (fd.is_file(mcode_path)) { + compiled = mach_compile_mcode_bin(path, text(fd.slurp(mcode_path))) + put_into_cache(stone(blob(content)), compiled) + return compiled + } } // Compile via full pipeline: analyze → mcode → streamline → serialize diff --git a/source/cell.c b/source/cell.c index 1436b071..16e8bbc4 100644 --- a/source/cell.c +++ b/source/cell.c @@ -284,6 +284,7 @@ static void print_usage(const char *prog) printf(" --shop Set shop path (overrides CELL_SHOP)\n"); printf(" --emit-qbe Emit QBE IL (for native compilation)\n"); printf(" --dump-mach Dump MACH bytecode disassembly\n"); + printf(" --dev Dev mode (shop=.cell, core=.)\n"); printf(" --test [heap_size] Run C test suite\n"); printf(" -h, --help Show this help message\n"); printf("\nEnvironment:\n"); @@ -346,6 +347,17 @@ int cell_init(int argc, char **argv) } core_override = argv[arg_start + 1]; arg_start += 2; + } else if (strcmp(argv[arg_start], "--dev") == 0) { + shop_override = ".cell"; + core_override = "."; + mkdir(".cell", 0755); + mkdir(".cell/build", 0755); + mkdir(".cell/packages", 0755); + /* Ensure .cell/packages/core -> . symlink exists */ + struct stat lst; + if (lstat(".cell/packages/core", &lst) != 0) + symlink("../..", ".cell/packages/core"); + arg_start++; } else { break; } diff --git a/source/mach.c b/source/mach.c index 36cda201..be1d384d 100644 --- a/source/mach.c +++ b/source/mach.c @@ -1804,7 +1804,7 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code, } default: - result = JS_ThrowInternalError(ctx, "unknown register VM opcode %d", op); + result = JS_ThrowInternalError(ctx, "unknown register VM opcode %d: %s", op, mach_opcode_names[op]); goto done; } continue; @@ -1827,12 +1827,38 @@ JSValue JS_CallRegisterVM(JSContext *ctx, JSCodeRegister *code, break; } if (JS_IsNull(frame->caller)) { - if (!JS_HasException(ctx)) { - /* Bare disrupt with no error message — provide location */ - const char *fn_name = code->name_cstr ? code->name_cstr : ""; - fprintf(stderr, "unhandled disruption in %s\n", fn_name); - } else { - fprintf(stderr, "unhandled disruption\n"); + const char *fn_name = code->name_cstr ? code->name_cstr : ""; + const char *file = code->filename_cstr ? code->filename_cstr : ""; + uint16_t line = 0, col = 0; + if (code->line_table && frame_pc > 0 && frame_pc - 1 < code->instr_count) { + line = code->line_table[frame_pc - 1].line; + col = code->line_table[frame_pc - 1].col; + } + fprintf(stderr, "unhandled disruption in %s (%s:%u:%u)\n", fn_name, file, line, col); + /* Walk and print the frame chain as a stack trace */ + { + JSFrameRegister *trace_frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); + int first = 1; + while (trace_frame) { + if (!JS_IsFunction(trace_frame->function)) break; + JSFunction *trace_fn = JS_VALUE_GET_FUNCTION(trace_frame->function); + if (trace_fn->kind == JS_FUNC_KIND_REGISTER && trace_fn->u.reg.code) { + JSCodeRegister *tc = trace_fn->u.reg.code; + uint32_t tpc = first ? (frame_pc > 0 ? frame_pc - 1 : 0) + : (uint32_t)(JS_VALUE_GET_INT(trace_frame->address) >> 16); + uint16_t tl = 0, tcol = 0; + if (tc->line_table && tpc < tc->instr_count) { + tl = tc->line_table[tpc].line; + tcol = tc->line_table[tpc].col; + } + fprintf(stderr, " at %s (%s:%u:%u)\n", + tc->name_cstr ? tc->name_cstr : "", + tc->filename_cstr ? tc->filename_cstr : "", tl, tcol); + } + if (JS_IsNull(trace_frame->caller)) break; + trace_frame = (JSFrameRegister *)JS_VALUE_GET_PTR(trace_frame->caller); + first = 0; + } } result = JS_Throw(ctx, JS_NULL); frame = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_ref.val); diff --git a/source/quickjs-internal.h b/source/quickjs-internal.h index 7d6ebc59..9758c297 100644 --- a/source/quickjs-internal.h +++ b/source/quickjs-internal.h @@ -469,7 +469,6 @@ typedef enum MachOpcode { MACH_JMPNULL, /* if R(A)==null: pc += sBx */ /* Function calls — Lua-style consecutive registers (legacy .mach) */ - MACH_CALL, /* (removed — placeholder to preserve opcode numbering) */ MACH_RETURN, /* Return R(A) */ MACH_RETNIL, /* Return null */ @@ -488,8 +487,6 @@ typedef enum MachOpcode { MACH_HASPROP, /* R(A) = R(C) in R(B) — has property check */ MACH_REGEXP, /* R(A) = regexp(K(B), K(C)) — regex literal */ - MACH_CALLMETHOD, /* (removed — placeholder to preserve opcode numbering) */ - MACH_EQ_TOL, /* R(A) = eq_tol(R(B), R(B+1), R(B+2)), C=3 */ MACH_NEQ_TOL, /* R(A) = ne_tol(R(B), R(B+1), R(B+2)), C=3 */ @@ -651,7 +648,6 @@ static const char *mach_opcode_names[MACH_OP_COUNT] = { [MACH_JMPTRUE] = "jmptrue", [MACH_JMPFALSE] = "jmpfalse", [MACH_JMPNULL] = "jmpnull", - [MACH_CALL] = "call", [MACH_RETURN] = "return", [MACH_RETNIL] = "retnil", [MACH_NEWOBJECT] = "newobject", @@ -664,7 +660,6 @@ static const char *mach_opcode_names[MACH_OP_COUNT] = { [MACH_DELETEINDEX] = "deleteindex", [MACH_HASPROP] = "hasprop", [MACH_REGEXP] = "regexp", - [MACH_CALLMETHOD] = "callmethod", [MACH_EQ_TOL] = "eq_tol", [MACH_NEQ_TOL] = "neq_tol", [MACH_NOP] = "nop",