aot compile vm_suite
This commit is contained in:
@@ -282,12 +282,25 @@ void cell_rt_set_native_env(JSContext *ctx, JSValue env) {
|
||||
}
|
||||
|
||||
JSValue cell_rt_get_intrinsic(JSContext *ctx, const char *name) {
|
||||
/* Check native env first (runtime-provided functions like starts_with) */
|
||||
/* Check native env first (runtime-provided functions like log) */
|
||||
if (g_has_native_env) {
|
||||
JSValue v = JS_GetPropertyStr(ctx, g_native_env_ref.val, name);
|
||||
if (!JS_IsNull(v)) return v;
|
||||
if (!JS_IsNull(v))
|
||||
return v;
|
||||
}
|
||||
return JS_GetPropertyStr(ctx, ctx->global_obj, name);
|
||||
/* Linear scan of global object — avoids hash mismatch issues with
|
||||
stoned records whose keys may be in cold storage */
|
||||
JSValue gobj = ctx->global_obj;
|
||||
if (JS_IsRecord(gobj)) {
|
||||
JSRecord *rec = (JSRecord *)chase(gobj);
|
||||
uint64_t mask = objhdr_cap56(rec->mist_hdr);
|
||||
for (uint64_t i = 1; i <= mask; i++) {
|
||||
if (js_key_equal_str(rec->slots[i].key, name))
|
||||
return rec->slots[i].val;
|
||||
}
|
||||
}
|
||||
JS_ThrowReferenceError(ctx, "'%s' is not defined", name);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
/* --- Closure access ---
|
||||
@@ -349,8 +362,36 @@ JSValue *cell_rt_enter_frame(JSContext *ctx, int64_t nr_slots) {
|
||||
|
||||
JSValue *cell_rt_refresh_fp(JSContext *ctx) {
|
||||
(void)ctx;
|
||||
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(
|
||||
g_aot_gc_refs[g_aot_depth - 1].val);
|
||||
if (g_aot_depth <= 0) {
|
||||
fprintf(stderr, "[BUG] cell_rt_refresh_fp: g_aot_depth=%d\n", g_aot_depth);
|
||||
abort();
|
||||
}
|
||||
JSValue val = g_aot_gc_refs[g_aot_depth - 1].val;
|
||||
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(val);
|
||||
if (!frame) {
|
||||
fprintf(stderr, "[BUG] cell_rt_refresh_fp: frame is NULL at depth=%d val=%lld\n",
|
||||
g_aot_depth, (long long)val);
|
||||
abort();
|
||||
}
|
||||
return (JSValue *)frame->slots;
|
||||
}
|
||||
|
||||
/* Combined refresh + exception check in a single call.
|
||||
Returns the refreshed fp, or NULL if there is a pending exception.
|
||||
This avoids QBE register-allocation issues from two consecutive calls. */
|
||||
JSValue *cell_rt_refresh_fp_checked(JSContext *ctx) {
|
||||
if (JS_HasException(ctx))
|
||||
return NULL;
|
||||
if (g_aot_depth <= 0) {
|
||||
fprintf(stderr, "[BUG] cell_rt_refresh_fp_checked: g_aot_depth=%d\n", g_aot_depth);
|
||||
abort();
|
||||
}
|
||||
JSValue val = g_aot_gc_refs[g_aot_depth - 1].val;
|
||||
JSFrameRegister *frame = (JSFrameRegister *)JS_VALUE_GET_PTR(val);
|
||||
if (!frame) {
|
||||
fprintf(stderr, "[BUG] cell_rt_refresh_fp_checked: frame is NULL\n");
|
||||
abort();
|
||||
}
|
||||
return (JSValue *)frame->slots;
|
||||
}
|
||||
|
||||
@@ -464,12 +505,13 @@ JSValue cell_rt_frame(JSContext *ctx, JSValue fn, int64_t nargs) {
|
||||
}
|
||||
|
||||
void cell_rt_setarg(JSValue frame_val, int64_t idx, JSValue val) {
|
||||
if (frame_val == JS_EXCEPTION) return;
|
||||
if (frame_val == JS_EXCEPTION || frame_val == JS_NULL) return;
|
||||
JSFrameRegister *fr = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_val);
|
||||
fr->slots[idx] = val;
|
||||
}
|
||||
|
||||
JSValue cell_rt_invoke(JSContext *ctx, JSValue frame_val) {
|
||||
if (frame_val == JS_EXCEPTION) return JS_EXCEPTION;
|
||||
JSFrameRegister *fr = (JSFrameRegister *)JS_VALUE_GET_PTR(frame_val);
|
||||
int nr_slots = (int)objhdr_cap56(fr->header);
|
||||
int c_argc = (nr_slots >= 2) ? nr_slots - 2 : 0;
|
||||
@@ -580,6 +622,15 @@ JSValue cell_rt_or(JSContext *ctx, JSValue left, JSValue right) {
|
||||
return JS_ToBool(ctx, left) ? left : right;
|
||||
}
|
||||
|
||||
/* --- Exception checking ---
|
||||
After potentially-throwing runtime calls, QBE-generated code needs to
|
||||
check for pending exceptions and branch to the disruption handler. */
|
||||
|
||||
void cell_rt_clear_exception(JSContext *ctx) {
|
||||
if (JS_HasException(ctx))
|
||||
JS_GetException(ctx);
|
||||
}
|
||||
|
||||
/* --- Disruption --- */
|
||||
|
||||
void cell_rt_disrupt(JSContext *ctx) {
|
||||
@@ -630,6 +681,10 @@ JSValue cell_rt_native_module_load(JSContext *ctx, void *dl_handle, JSValue env)
|
||||
return JS_ThrowTypeError(ctx, "frame allocation failed");
|
||||
}
|
||||
|
||||
/* Clear any stale exception left by a previous interpreted run */
|
||||
if (JS_HasException(ctx))
|
||||
JS_GetException(ctx);
|
||||
|
||||
JSValue result = fn(ctx, fp);
|
||||
cell_rt_leave_frame(ctx); /* safe — closures have independent GC refs */
|
||||
g_current_dl_handle = prev_handle;
|
||||
|
||||
Reference in New Issue
Block a user