mcode to mach
This commit is contained in:
Binary file not shown.
BIN
mcode.mach
BIN
mcode.mach
Binary file not shown.
BIN
parse.mach
BIN
parse.mach
Binary file not shown.
BIN
qbe_emit.mach
BIN
qbe_emit.mach
Binary file not shown.
@@ -207,7 +207,6 @@ void script_startup(cell_rt *prt)
|
|||||||
|
|
||||||
// Set args to null for actor spawn (not CLI mode)
|
// Set args to null for actor spawn (not CLI mode)
|
||||||
JS_SetPropertyStr(js, hidden_env, "args", JS_NULL);
|
JS_SetPropertyStr(js, hidden_env, "args", JS_NULL);
|
||||||
/* use_mcode no longer needed — new bootstrap always uses mcode pipeline */
|
|
||||||
|
|
||||||
if (core_path)
|
if (core_path)
|
||||||
JS_SetPropertyStr(js, hidden_env, "core_path", JS_NewString(js, core_path));
|
JS_SetPropertyStr(js, hidden_env, "core_path", JS_NewString(js, core_path));
|
||||||
@@ -398,7 +397,6 @@ int cell_init(int argc, char **argv)
|
|||||||
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "shop_path",
|
JS_SetPropertyStr(ctx, hidden_env, "shop_path",
|
||||||
shop_path ? JS_NewString(ctx, shop_path) : JS_NULL);
|
shop_path ? JS_NewString(ctx, shop_path) : JS_NULL);
|
||||||
/* use_mcode no longer needed — new bootstrap always uses mcode pipeline */
|
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "emit_qbe", JS_NewBool(ctx, emit_qbe));
|
JS_SetPropertyStr(ctx, hidden_env, "emit_qbe", JS_NewBool(ctx, emit_qbe));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
|
JS_SetPropertyStr(ctx, hidden_env, "actorsym", JS_DupValue(ctx, cli_rt->actor_sym_ref.val));
|
||||||
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
|
JS_SetPropertyStr(ctx, hidden_env, "json", js_json_use(ctx));
|
||||||
|
|||||||
@@ -2224,7 +2224,6 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
cJSON *nr_slots_j = cJSON_GetObjectItemCaseSensitive(fobj, "nr_slots");
|
cJSON *nr_slots_j = cJSON_GetObjectItemCaseSensitive(fobj, "nr_slots");
|
||||||
int nr_slots = (int)cJSON_GetNumberValue(nr_slots_j);
|
int nr_slots = (int)cJSON_GetNumberValue(nr_slots_j);
|
||||||
*out_old_nr_slots = nr_slots;
|
*out_old_nr_slots = nr_slots;
|
||||||
return NULL; /* TEMP: disable compression to test */
|
|
||||||
if (nr_slots <= 255) return NULL;
|
if (nr_slots <= 255) return NULL;
|
||||||
|
|
||||||
int nr_args = (int)cJSON_GetNumberValue(
|
int nr_args = (int)cJSON_GetNumberValue(
|
||||||
@@ -2237,8 +2236,9 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
int *last_ref = sys_malloc(nr_slots * sizeof(int));
|
int *last_ref = sys_malloc(nr_slots * sizeof(int));
|
||||||
for (int i = 0; i < nr_slots; i++) { first_ref[i] = -1; last_ref[i] = -1; }
|
for (int i = 0; i < nr_slots; i++) { first_ref[i] = -1; last_ref[i] = -1; }
|
||||||
|
|
||||||
/* Args are live for the whole function */
|
/* this + args are live for the whole function */
|
||||||
for (int i = 0; i < nr_args; i++) { first_ref[i] = 0; last_ref[i] = n; }
|
int pinned = 1 + nr_args;
|
||||||
|
for (int i = 0; i < pinned; i++) { first_ref[i] = 0; last_ref[i] = n; }
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
cJSON *it = cJSON_GetArrayItem(instrs, i);
|
cJSON *it = cJSON_GetArrayItem(instrs, i);
|
||||||
@@ -2310,7 +2310,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
/* Backward jump: extend registers that are live INTO the loop
|
/* Backward jump: extend registers that are live INTO the loop
|
||||||
(first_ref < loop start but used inside). Temporaries born
|
(first_ref < loop start but used inside). Temporaries born
|
||||||
inside the loop body don't need extension — they are per-iteration. */
|
inside the loop body don't need extension — they are per-iteration. */
|
||||||
for (int s = nr_args; s < nr_slots; s++) {
|
for (int s = pinned; s < nr_slots; s++) {
|
||||||
if (first_ref[s] < 0) continue;
|
if (first_ref[s] < 0) continue;
|
||||||
if (first_ref[s] >= tpos) continue; /* born inside loop — skip */
|
if (first_ref[s] >= tpos) continue; /* born inside loop — skip */
|
||||||
if (last_ref[s] < tpos) continue; /* dead before loop — skip */
|
if (last_ref[s] < tpos) continue; /* dead before loop — skip */
|
||||||
@@ -2326,7 +2326,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
typedef struct { int slot, first, last; } SlotInfo;
|
typedef struct { int slot, first, last; } SlotInfo;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
SlotInfo *sorted = sys_malloc(nr_slots * sizeof(SlotInfo));
|
SlotInfo *sorted = sys_malloc(nr_slots * sizeof(SlotInfo));
|
||||||
for (int s = nr_args; s < nr_slots; s++)
|
for (int s = pinned; s < nr_slots; s++)
|
||||||
if (first_ref[s] >= 0)
|
if (first_ref[s] >= 0)
|
||||||
sorted[cnt++] = (SlotInfo){s, first_ref[s], last_ref[s]};
|
sorted[cnt++] = (SlotInfo){s, first_ref[s], last_ref[s]};
|
||||||
|
|
||||||
@@ -2348,7 +2348,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
/* Free-register pool (min-heap would be ideal but a flat scan is fine) */
|
/* Free-register pool (min-heap would be ideal but a flat scan is fine) */
|
||||||
int *pool = sys_malloc(nr_slots * sizeof(int));
|
int *pool = sys_malloc(nr_slots * sizeof(int));
|
||||||
int pool_n = 0;
|
int pool_n = 0;
|
||||||
int next_phys = nr_args;
|
int next_phys = pinned;
|
||||||
|
|
||||||
typedef struct { int phys, last; } ActiveAlloc;
|
typedef struct { int phys, last; } ActiveAlloc;
|
||||||
ActiveAlloc *active = sys_malloc(cnt * sizeof(ActiveAlloc));
|
ActiveAlloc *active = sys_malloc(cnt * sizeof(ActiveAlloc));
|
||||||
@@ -2381,7 +2381,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute new nr_slots */
|
/* Compute new nr_slots */
|
||||||
int new_max = nr_args;
|
int new_max = pinned;
|
||||||
for (int s = 0; s < nr_slots; s++)
|
for (int s = 0; s < nr_slots; s++)
|
||||||
if (first_ref[s] >= 0 && remap[s] >= new_max)
|
if (first_ref[s] >= 0 && remap[s] >= new_max)
|
||||||
new_max = remap[s] + 1;
|
new_max = remap[s] + 1;
|
||||||
@@ -2391,7 +2391,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
|
|||||||
fprintf(stderr, " WARNING: %d live regs still exceeds 255\n", new_max);
|
fprintf(stderr, " WARNING: %d live regs still exceeds 255\n", new_max);
|
||||||
|
|
||||||
/* Verify: check no two registers with overlapping live ranges share phys */
|
/* Verify: check no two registers with overlapping live ranges share phys */
|
||||||
for (int a = nr_args; a < nr_slots; a++) {
|
for (int a = pinned; a < nr_slots; a++) {
|
||||||
if (first_ref[a] < 0) continue;
|
if (first_ref[a] < 0) continue;
|
||||||
for (int b = a + 1; b < nr_slots; b++) {
|
for (int b = a + 1; b < nr_slots; b++) {
|
||||||
if (first_ref[b] < 0) continue;
|
if (first_ref[b] < 0) continue;
|
||||||
@@ -2846,9 +2846,9 @@ void verify_getup(MachCode *mc, const char *path) {
|
|||||||
MachInstr32 instr = mc->instructions[i];
|
MachInstr32 instr = mc->instructions[i];
|
||||||
if (MACH_GET_OP(instr) == MACH_GETUP) {
|
if (MACH_GET_OP(instr) == MACH_GETUP) {
|
||||||
int depth = MACH_GET_B(instr);
|
int depth = MACH_GET_B(instr);
|
||||||
if (depth > 2)
|
if (depth > 10)
|
||||||
fprintf(stderr, "VERIFY: bad GETUP at %s[%d]: depth=%d slot=%d dest=%d instr=0x%08x nr_slots=%d\n",
|
fprintf(stderr, "VERIFY: suspicious GETUP at %s[%d]: depth=%d slot=%d dest=%d\n",
|
||||||
path, i, depth, MACH_GET_C(instr), MACH_GET_A(instr), instr, mc->nr_slots);
|
path, i, depth, MACH_GET_C(instr), MACH_GET_A(instr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < mc->func_count; i++) {
|
for (uint32_t i = 0; i < mc->func_count; i++) {
|
||||||
@@ -3309,16 +3309,6 @@ JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue
|
|||||||
if (!mc)
|
if (!mc)
|
||||||
return JS_ThrowSyntaxError(ctx, "failed to deserialize MACH bytecode");
|
return JS_ThrowSyntaxError(ctx, "failed to deserialize MACH bytecode");
|
||||||
|
|
||||||
fprintf(stderr, "DEBUG RunMachBin: mc=%p instr_count=%d cpool_count=%d func_count=%d nr_slots=%d\n",
|
|
||||||
(void*)mc, mc->instr_count, mc->cpool_count, mc->func_count, mc->nr_slots);
|
|
||||||
verify_getup(mc, "DESER_BOOT");
|
|
||||||
if (mc->instr_count > 0) {
|
|
||||||
fprintf(stderr, "DEBUG first 5 instrs:");
|
|
||||||
for (uint32_t i = 0; i < 5 && i < mc->instr_count; i++)
|
|
||||||
fprintf(stderr, " 0x%08x", mc->instructions[i]);
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
JSGCRef env_ref;
|
JSGCRef env_ref;
|
||||||
JS_PushGCRef(ctx, &env_ref);
|
JS_PushGCRef(ctx, &env_ref);
|
||||||
env_ref.val = env;
|
env_ref.val = env;
|
||||||
@@ -3326,9 +3316,6 @@ JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue
|
|||||||
JSCodeRegister *code = JS_LoadMachCode(ctx, mc, env_ref.val);
|
JSCodeRegister *code = JS_LoadMachCode(ctx, mc, env_ref.val);
|
||||||
JS_FreeMachCode(mc);
|
JS_FreeMachCode(mc);
|
||||||
|
|
||||||
fprintf(stderr, "DEBUG LoadMachCode: code=%p instr_count=%d cpool_count=%d func_count=%d\n",
|
|
||||||
(void*)code, code->instr_count, code->cpool_count, code->func_count);
|
|
||||||
|
|
||||||
JSValue result = JS_CallRegisterVM(ctx, code, ctx->global_obj, 0, NULL, env_ref.val, JS_NULL);
|
JSValue result = JS_CallRegisterVM(ctx, code, ctx->global_obj, 0, NULL, env_ref.val, JS_NULL);
|
||||||
JS_PopGCRef(ctx, &env_ref);
|
JS_PopGCRef(ctx, &env_ref);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
BIN
streamline.mach
BIN
streamline.mach
Binary file not shown.
BIN
tokenize.mach
BIN
tokenize.mach
Binary file not shown.
Reference in New Issue
Block a user