asserts only for frame gets
This commit is contained in:
@@ -150,7 +150,6 @@ JSValue qbe_bitwise_xor(JSContext *ctx, JSValue a, JSValue b) {
|
||||
/* Concat helper matching MACH_CONCAT semantics exactly. */
|
||||
JSValue cell_rt_concat(JSContext *ctx, JSValue left, JSValue right, int self_assign) {
|
||||
if (self_assign) {
|
||||
/* Self-assign pattern: slot[a] = slot[a] + slot[c]. */
|
||||
if (JS_IsPtr(left)) {
|
||||
JSText *s = (JSText *)chase(left);
|
||||
int slen = (int)s->length;
|
||||
@@ -159,21 +158,18 @@ JSValue cell_rt_concat(JSContext *ctx, JSValue left, JSValue right, int self_ass
|
||||
if (objhdr_type(s->hdr) == OBJ_TEXT
|
||||
&& !(s->hdr & OBJHDR_S_MASK)
|
||||
&& slen + rlen <= cap) {
|
||||
/* In-place append, no allocation. */
|
||||
for (int i = 0; i < rlen; i++)
|
||||
string_put(s, slen + i, js_string_value_get(right, i));
|
||||
s->length = slen + rlen;
|
||||
return left;
|
||||
}
|
||||
}
|
||||
/* Allocate with growth factor, leave unstoned. */
|
||||
JSValue res = JS_ConcatStringGrow(ctx, left, right);
|
||||
if (JS_IsException(res))
|
||||
return JS_EXCEPTION;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Different target: exact-fit stoned path. */
|
||||
JSValue res = JS_ConcatString(ctx, left, right);
|
||||
if (JS_IsException(res))
|
||||
return JS_EXCEPTION;
|
||||
@@ -468,52 +464,6 @@ JSValue cell_rt_get_intrinsic_lit(JSContext *ctx, int64_t lit_idx) {
|
||||
return cell_rt_get_intrinsic_key(ctx, key);
|
||||
}
|
||||
|
||||
/* --- Closure access ---
|
||||
Walk the outer_frame chain on JSFunction (JS_FUNC_KIND_NATIVE).
|
||||
The frame's function field links to the JSFunction, whose
|
||||
u.native.outer_frame points to the enclosing frame.
|
||||
GC traces outer_frame naturally — no registry needed. */
|
||||
|
||||
/* Get the outer frame's slots from a frame pointer.
|
||||
The frame's function must be JS_FUNC_KIND_NATIVE. */
|
||||
static JSValue *get_outer_frame_slots(JSValue *fp) {
|
||||
/* fp points to frame->slots[0]; frame header is before it */
|
||||
JSFrameRegister *frame = (JSFrameRegister *)((char *)fp - offsetof(JSFrameRegister, slots));
|
||||
if (JS_IsNull(frame->function))
|
||||
return NULL;
|
||||
JSFunction *fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
if (fn->kind != JS_FUNC_KIND_NATIVE)
|
||||
return NULL;
|
||||
JSValue outer = fn->u.cell.outer_frame;
|
||||
if (JS_IsNull(outer))
|
||||
return NULL;
|
||||
JSFrameRegister *outer_frame = (JSFrameRegister *)JS_VALUE_GET_PTR(outer);
|
||||
return (JSValue *)outer_frame->slots;
|
||||
}
|
||||
|
||||
JSValue cell_rt_get_closure(JSContext *ctx, void *fp, int64_t depth,
|
||||
int64_t slot) {
|
||||
(void)ctx;
|
||||
JSValue *frame = (JSValue *)fp;
|
||||
for (int64_t d = 0; d < depth; d++) {
|
||||
frame = get_outer_frame_slots(frame);
|
||||
if (!frame)
|
||||
return JS_NULL;
|
||||
}
|
||||
return frame[slot];
|
||||
}
|
||||
|
||||
void cell_rt_put_closure(JSContext *ctx, void *fp, JSValue val, int64_t depth,
|
||||
int64_t slot) {
|
||||
(void)ctx;
|
||||
JSValue *frame = (JSValue *)fp;
|
||||
for (int64_t d = 0; d < depth; d++) {
|
||||
frame = get_outer_frame_slots(frame);
|
||||
if (!frame) return;
|
||||
}
|
||||
frame[slot] = val;
|
||||
}
|
||||
|
||||
/* --- GC-managed AOT frame stack ---
|
||||
Each native dispatch loop pushes a GC ref so the GC can find and
|
||||
update the current frame pointer when it moves objects.
|
||||
@@ -662,18 +612,6 @@ typedef JSValue (*cell_compiled_fn)(JSContext *ctx, void *fp);
|
||||
to call another function (instead of recursing via C stack).
|
||||
============================================================ */
|
||||
|
||||
/* Poll pause state on taken backward jumps (AOT backedges).
|
||||
MACH can suspend/resume a register VM frame at pc granularity; native AOT
|
||||
does not currently have an equivalent resume point, so we acknowledge timer
|
||||
pauses by clearing pause_flag and continuing the current turn. */
|
||||
int cell_rt_check_backedge(JSContext *ctx) {
|
||||
int pf = atomic_load_explicit(&ctx->pause_flag, memory_order_relaxed);
|
||||
if (pf >= 1) {
|
||||
atomic_store_explicit(&ctx->pause_flag, 0, memory_order_relaxed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cell_rt_signal_call(JSContext *ctx, void *fp, int64_t frame_slot) {
|
||||
NativeRTState *st = native_state(ctx);
|
||||
if (!st) return;
|
||||
@@ -1194,101 +1132,6 @@ JSValue cell_rt_ne_tol(JSContext *ctx, JSValue a, JSValue b, JSValue tol) {
|
||||
return JS_NewBool(ctx, !cell_rt_tol_eq_inner(ctx, a, b, tol));
|
||||
}
|
||||
|
||||
/* --- Extended type checks and text stoning --- */
|
||||
|
||||
void cell_rt_stone_text(JSValue v) {
|
||||
stone_mutable_text(v);
|
||||
}
|
||||
|
||||
int cell_rt_is_blob(JSValue v) {
|
||||
return mist_is_blob(v);
|
||||
}
|
||||
|
||||
int cell_rt_is_data(JSValue v) {
|
||||
return mist_is_gc_object(v) && !mist_is_array(v)
|
||||
&& !mist_is_function(v) && !mist_is_blob(v);
|
||||
}
|
||||
|
||||
int cell_rt_is_fit(JSValue v) {
|
||||
if (JS_IsInt(v))
|
||||
return 1;
|
||||
if (JS_IsShortFloat(v)) {
|
||||
double d = JS_VALUE_GET_FLOAT64(v);
|
||||
return isfinite(d) && trunc(d) == d && fabs(d) <= 9007199254740992.0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_char(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v))
|
||||
return MIST_GetImmediateASCIILen(v) == 1;
|
||||
if (mist_is_text(v))
|
||||
return js_string_value_len(v) == 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_digit(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v) && MIST_GetImmediateASCIILen(v) == 1) {
|
||||
int ch = MIST_GetImmediateASCIIChar(v, 0);
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
if (mist_is_text(v) && js_string_value_len(v) == 1) {
|
||||
uint32_t ch = js_string_value_get(v, 0);
|
||||
return ch >= '0' && ch <= '9';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_letter(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v) && MIST_GetImmediateASCIILen(v) == 1) {
|
||||
int ch = MIST_GetImmediateASCIIChar(v, 0);
|
||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
}
|
||||
if (mist_is_text(v) && js_string_value_len(v) == 1) {
|
||||
uint32_t ch = js_string_value_get(v, 0);
|
||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_lower(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v) && MIST_GetImmediateASCIILen(v) == 1) {
|
||||
int ch = MIST_GetImmediateASCIIChar(v, 0);
|
||||
return ch >= 'a' && ch <= 'z';
|
||||
}
|
||||
if (mist_is_text(v) && js_string_value_len(v) == 1) {
|
||||
uint32_t ch = js_string_value_get(v, 0);
|
||||
return ch >= 'a' && ch <= 'z';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_upper(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v) && MIST_GetImmediateASCIILen(v) == 1) {
|
||||
int ch = MIST_GetImmediateASCIIChar(v, 0);
|
||||
return ch >= 'A' && ch <= 'Z';
|
||||
}
|
||||
if (mist_is_text(v) && js_string_value_len(v) == 1) {
|
||||
uint32_t ch = js_string_value_get(v, 0);
|
||||
return ch >= 'A' && ch <= 'Z';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_ws(JSValue v) {
|
||||
if (MIST_IsImmediateASCII(v) && MIST_GetImmediateASCIILen(v) == 1) {
|
||||
int ch = MIST_GetImmediateASCIIChar(v, 0);
|
||||
return ch == ' ' || ch == '\t' || ch == '\n'
|
||||
|| ch == '\r' || ch == '\f' || ch == '\v';
|
||||
}
|
||||
if (mist_is_text(v) && js_string_value_len(v) == 1) {
|
||||
uint32_t ch = js_string_value_get(v, 0);
|
||||
return ch == ' ' || ch == '\t' || ch == '\n'
|
||||
|| ch == '\r' || ch == '\f' || ch == '\v';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cell_rt_is_actor(JSContext *ctx, JSValue v) {
|
||||
int result = 0;
|
||||
if (mist_is_record(v) && !JS_IsNull(ctx->actor_sym))
|
||||
@@ -1296,25 +1139,6 @@ int cell_rt_is_actor(JSContext *ctx, JSValue v) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --- Type check: is_proxy (function with arity 2) --- */
|
||||
|
||||
int cell_rt_is_proxy(JSContext *ctx, JSValue v) {
|
||||
(void)ctx;
|
||||
if (!JS_IsFunction(v)) return 0;
|
||||
JSFunction *fn = JS_VALUE_GET_FUNCTION(v);
|
||||
return fn->length == 2;
|
||||
}
|
||||
|
||||
/* --- Short-circuit and/or (non-allocating) --- */
|
||||
|
||||
JSValue cell_rt_and(JSContext *ctx, JSValue left, JSValue right) {
|
||||
return JS_ToBool(ctx, left) ? right : left;
|
||||
}
|
||||
|
||||
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. */
|
||||
|
||||
Reference in New Issue
Block a user