varref cleanup

This commit is contained in:
2026-02-03 20:09:35 -06:00
parent e734353722
commit fd5e4d155e
2 changed files with 74 additions and 312 deletions

View File

@@ -28,7 +28,6 @@ FMT(none)
FMT(none_int)
FMT(none_loc)
FMT(none_arg)
FMT(none_var_ref)
FMT(u8)
FMT(i8)
FMT(loc8)
@@ -42,7 +41,6 @@ FMT(npopx)
FMT(npop_u16)
FMT(loc)
FMT(arg)
FMT(var_ref)
FMT(u32)
FMT(i32)
FMT(const)
@@ -108,16 +106,18 @@ DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
bytecode string */
DEF( check_var, 5, 0, 1, key) /* check if a variable exists */
DEF( get_var_undef, 5, 0, 1, key) /* push undefined if the variable does not exist */
DEF( get_var, 5, 0, 1, key) /* throw an exception if the variable does not exist */
DEF( put_var, 5, 1, 0, key) /* must come after get_var */
DEF( put_var_init, 5, 1, 0, key) /* must come after put_var. Used to initialize a global lexical variable */
DEF( put_var_strict, 5, 2, 0, key) /* for strict mode variable write */
/* Global variable access - resolved by linker to get/set_global_slot */
DEF( check_var, 5, 0, 1, key) /* check if a variable exists - resolved by linker */
DEF( get_var_undef, 5, 0, 1, key) /* resolved by linker to get_global_slot */
DEF( get_var, 5, 0, 1, key) /* resolved by linker to get_global_slot */
DEF( put_var, 5, 1, 0, key) /* resolved by linker to set_global_slot */
DEF( put_var_init, 5, 1, 0, key) /* resolved by linker to set_global_slot */
DEF( put_var_strict, 5, 2, 0, key) /* resolved by linker to set_global_slot */
DEF( get_ref_value, 1, 2, 3, none)
DEF( put_ref_value, 1, 3, 0, none)
/* Global variable opcodes - resolved by linker to get/set_global_slot */
DEF( define_var, 6, 0, 0, key_u8)
DEF(check_define_var, 6, 0, 0, key_u8)
DEF( define_func, 6, 1, 0, key_u8)
@@ -144,18 +144,19 @@ DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
DEF( get_arg, 3, 0, 1, arg)
DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */
DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */
DEF( get_var_ref, 3, 0, 1, var_ref)
DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
/* Var ref opcodes - deprecated, resolved to get_up/set_up during scope resolution */
DEF( get_var_ref, 3, 0, 1, loc) /* deprecated - use get_up */
DEF( put_var_ref, 3, 1, 0, loc) /* deprecated - use set_up */
DEF( set_var_ref, 3, 1, 1, loc) /* deprecated - use set_up */
DEF(set_loc_uninitialized, 3, 0, 0, loc)
DEF( get_loc_check, 3, 0, 1, loc)
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
DEF( put_loc_check_init, 3, 1, 0, loc)
DEF(get_loc_checkthis, 3, 0, 1, loc)
DEF(get_var_ref_check, 3, 0, 1, var_ref)
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
DEF( close_loc, 3, 0, 0, loc)
DEF(get_var_ref_check, 3, 0, 1, loc) /* deprecated - use get_up */
DEF(put_var_ref_check, 3, 1, 0, loc) /* deprecated - use set_up */
DEF(put_var_ref_check_init, 3, 1, 0, loc) /* deprecated - use set_up */
DEF( close_loc, 3, 0, 0, loc) /* deprecated - no longer needed */
DEF( if_false, 5, 1, 0, label)
DEF( if_true, 5, 1, 0, label) /* must come after if_false */
DEF( goto, 5, 0, 0, label) /* must come after if_true */
@@ -166,10 +167,11 @@ DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
DEF( to_propkey, 1, 1, 1, none)
DEF( make_loc_ref, 7, 0, 2, key_u16)
DEF( make_arg_ref, 7, 0, 2, key_u16)
DEF(make_var_ref_ref, 7, 0, 2, key_u16)
DEF( make_var_ref, 5, 0, 2, key)
/* Deprecated make_*_ref opcodes - no longer needed with outer_frame model */
DEF( make_loc_ref, 7, 0, 2, key_u16) /* deprecated */
DEF( make_arg_ref, 7, 0, 2, key_u16) /* deprecated */
DEF(make_var_ref_ref, 7, 0, 2, key_u16) /* deprecated */
DEF( make_var_ref, 5, 0, 2, key) /* deprecated */
/* arithmetic/logic operations */
DEF( neg, 1, 1, 1, none)
@@ -184,7 +186,7 @@ DEF( add_loc, 2, 1, 0, loc8)
DEF( not, 1, 1, 1, none)
DEF( lnot, 1, 1, 1, none)
DEF( delete, 1, 2, 1, none)
DEF( delete_var, 5, 0, 1, key)
DEF( delete_var, 5, 0, 1, key) /* deprecated - global object is immutable */
DEF( mul, 1, 2, 1, none)
DEF( mul_float, 1, 2, 1, none)
@@ -292,18 +294,6 @@ DEF( set_arg0, 1, 1, 1, none_arg)
DEF( set_arg1, 1, 1, 1, none_arg)
DEF( set_arg2, 1, 1, 1, none_arg)
DEF( set_arg3, 1, 1, 1, none_arg)
DEF( get_var_ref0, 1, 0, 1, none_var_ref)
DEF( get_var_ref1, 1, 0, 1, none_var_ref)
DEF( get_var_ref2, 1, 0, 1, none_var_ref)
DEF( get_var_ref3, 1, 0, 1, none_var_ref)
DEF( put_var_ref0, 1, 1, 0, none_var_ref)
DEF( put_var_ref1, 1, 1, 0, none_var_ref)
DEF( put_var_ref2, 1, 1, 0, none_var_ref)
DEF( put_var_ref3, 1, 1, 0, none_var_ref)
DEF( set_var_ref0, 1, 1, 1, none_var_ref)
DEF( set_var_ref1, 1, 1, 1, none_var_ref)
DEF( set_var_ref2, 1, 1, 1, none_var_ref)
DEF( set_var_ref3, 1, 1, 1, none_var_ref)
DEF( if_false8, 2, 1, 0, label8)
DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */

View File

@@ -129,7 +129,6 @@ typedef struct JSRecord JSRecord;
typedef struct JSFunction JSFunction;
typedef struct JSFrame JSFrame;
typedef struct JSCode JSCode;
typedef struct JSVarRef JSVarRef;
#define OBJHDR_CAP_SHIFT 8u
#define OBJHDR_CAP_MASK (((objhdr_t)1ull << 56) - 1ull)
@@ -147,14 +146,6 @@ typedef struct JSVarRef JSVarRef;
/* Extract pointer (clear low bits) */
#define JS_VALUE_GET_PTR(v) ((void *)((v) & ~((JSValue)(JSW - 1))))
/* JSVarRef - variable reference for closures */
struct JSVarRef {
uint8_t is_detached; /* TRUE if pvalue points to value field */
uint8_t pad[7];
JSValue *pvalue; /* pointer to the value (stack or &value) */
JSValue value; /* captured value when detached */
struct list_head var_ref_link; /* link in frame's var_ref_list */
};
static inline JS_BOOL JS_VALUE_IS_TEXT (JSValue v) {
int tag = JS_VALUE_GET_TAG (v);
@@ -278,7 +269,6 @@ enum {
JS_CLASS_ERROR,
JS_CLASS_REGEXP, /* u.regexp */
JS_CLASS_BLOB, /* u.opaque (blob *) */
JS_CLASS_VAR_REF_OBJECT, /* u.opaque (JSVarRef *) - for var ref objects */
JS_CLASS_INIT_COUNT, /* last entry for predefined classes */
};
@@ -414,7 +404,6 @@ typedef struct JSStackFrame {
JSValue cur_func; /* current function, JS_NULL if the frame is detached */
JSValue *arg_buf; /* arguments */
JSValue *var_buf; /* variables */
struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */
const uint8_t *cur_pc; /* only used in bytecode functions : PC of the
instruction after the call */
int arg_count;
@@ -444,8 +433,6 @@ struct VMFrame {
JSValue cur_func; /* current function object */
JSValue this_obj; /* this binding */
struct JSVarRef **var_refs; /* closure variable references */
struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */
int arg_count;
int js_mode;
int stack_size_allocated; /* total size allocated for this frame */
@@ -1630,7 +1617,6 @@ typedef struct JSFunction {
} cfunc;
struct {
struct JSFunctionBytecode *function_bytecode;
JSVarRef **var_refs; /* legacy closure refs (to be removed) */
JSValue outer_frame; /* JSFrame JSValue, lexical parent for closures */
JSValue env_record; /* stone record, module environment */
} func;
@@ -1748,10 +1734,7 @@ typedef struct JSBoundFunction {
} JSBoundFunction;
typedef struct JSProperty {
union {
JSValue value; /* JS_PROP_NORMAL */
JSVarRef *var_ref; /* JS_PROP_VARREF */
} u;
JSValue value;
} JSProperty;
#define JS_PROP_INITIAL_SIZE 2
@@ -1810,8 +1793,6 @@ static __maybe_unused void JS_DumpValue (JSContext *ctx, const char *str, JSValu
static void js_dump_value_write (void *opaque, const char *buf, size_t len);
static JSValue js_function_apply (JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
static void js_regexp_finalizer (JSRuntime *rt, JSValue val);
static void js_varref_object_finalizer (JSRuntime *rt, JSValue val);
static void js_varref_object_gc_mark (JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func);
static JSValue js_new_function (JSContext *ctx, JSFunctionKind kind);
static void mark_function_children (JSRuntime *rt, JSFunction *func, JS_MarkFunc *mark_func);
static void mark_function_children_decref (JSRuntime *rt, JSFunction *func);
@@ -2102,7 +2083,6 @@ static JSClass const js_std_class_def[] = {
{ "error", NULL, NULL }, /* JS_CLASS_ERROR */
{ "regexp", js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */
{ "blob", NULL, NULL }, /* JS_CLASS_BLOB - registered separately */
{ "varref", js_varref_object_finalizer, js_varref_object_gc_mark }, /* JS_CLASS_VAR_REF_OBJECT */
};
static int init_class_range (JSRuntime *rt, JSClass const *tab, int start, int count) {
@@ -3889,31 +3869,6 @@ JSValue JS_NewCFunction2 (JSContext *ctx, JSCFunction *func, const char *name, i
/* free_property is defined earlier as a stub since shapes are removed */
static void free_var_ref (JSRuntime *rt, JSVarRef *var_ref) {
/* With copying GC, var_ref lifetime is managed by the GC.
We still do bookkeeping for the var_ref_link list. */
if (var_ref && !var_ref->is_detached) {
list_del (&var_ref->var_ref_link);
}
/* The actual memory is reclaimed by the copying GC */
}
/* Finalizer for JS_CLASS_VAR_REF_OBJECT - frees the stored var_ref */
static void js_varref_object_finalizer (JSRuntime *rt, JSValue val) {
JSVarRef *var_ref = JS_GetOpaque (val, JS_CLASS_VAR_REF_OBJECT);
if (var_ref) {
free_var_ref (rt, var_ref);
}
}
/* GC mark for JS_CLASS_VAR_REF_OBJECT - marks the value if detached */
static void js_varref_object_gc_mark (JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func) {
JSVarRef *var_ref = JS_GetOpaque (val, JS_CLASS_VAR_REF_OBJECT);
if (var_ref && var_ref->is_detached) {
JS_MarkValue (rt, var_ref->value, mark_func);
}
}
/* GC-safe array growth function.
Takes JSValue* pointer to a GC-tracked location (like &argv[n]).
Allocates new array, copies data, installs forward header at old location. */
@@ -6796,7 +6751,6 @@ static JSValue js_closure2 (JSContext *ctx, JSValue func_obj, JSFunctionBytecode
JSFunction *f;
f = JS_VALUE_GET_FUNCTION (func_obj);
f->u.func.function_bytecode = b;
f->u.func.var_refs = NULL;
/* Set outer_frame to parent's JSFrame for the new closure model.
This allows OP_get_up/OP_set_up to access captured variables via frame chain. */
@@ -7479,61 +7433,43 @@ restart:
}
BREAK;
CASE (OP_check_var) : {
/* Global object is immutable - linker should have resolved or removed this */
/* Global variable opcodes - resolved by linker to get/set_global_slot */
CASE (OP_check_var) :
pc += 4;
JS_ThrowInternalError (ctx, "OP_check_var: linker should have resolved this");
goto exception;
}
BREAK;
CASE (OP_get_var_undef) : CASE (OP_get_var) : {
/* Global object is immutable - linker should have resolved this */
CASE (OP_get_var_undef) :
CASE (OP_get_var) :
pc += 4;
JS_ThrowInternalError (ctx, "OP_get_var: linker should have resolved to get_global_slot");
goto exception;
}
BREAK;
CASE (OP_put_var) : CASE (OP_put_var_init) : {
/* Global object is immutable - linker should have resolved this */
CASE (OP_put_var) :
CASE (OP_put_var_init) :
pc += 4;
sp--;
JS_ThrowInternalError (ctx, "OP_put_var: global object is immutable, linker should resolve");
goto exception;
}
BREAK;
CASE (OP_put_var_strict) : {
/* Global object is immutable - linker should have resolved this */
CASE (OP_put_var_strict) :
pc += 4;
sp -= 2;
JS_ThrowInternalError (ctx, "OP_put_var_strict: global object is immutable, linker should resolve");
goto exception;
}
BREAK;
CASE (OP_check_define_var) : {
/* Global object is immutable - this opcode should not be emitted */
CASE (OP_define_var) :
CASE (OP_check_define_var) :
pc += 5;
JS_ThrowInternalError (ctx, "OP_check_define_var: global object is immutable");
JS_ThrowInternalError (ctx, "global object is immutable - cannot define variables at runtime");
goto exception;
}
BREAK;
CASE (OP_define_var) : {
/* Global object is immutable - this opcode should not be emitted */
pc += 5;
JS_ThrowInternalError (ctx, "OP_define_var: global object is immutable");
goto exception;
}
BREAK;
CASE (OP_define_func) : {
/* Global object is immutable - this opcode should not be emitted */
CASE (OP_define_func) :
pc += 5;
sp--;
JS_ThrowInternalError (ctx, "OP_define_func: global object is immutable");
JS_ThrowInternalError (ctx, "global object is immutable - cannot define functions at runtime");
goto exception;
}
BREAK;
CASE (OP_get_loc) : {
@@ -7648,33 +7584,7 @@ restart:
CASE (OP_set_arg3)
: set_value (ctx, &arg_buf[3], sp[-1]);
BREAK;
/* Legacy var_ref opcodes - deprecated, replaced by OP_get_up/OP_set_up */
CASE (OP_get_var_ref0) :
CASE (OP_get_var_ref1) :
CASE (OP_get_var_ref2) :
CASE (OP_get_var_ref3) :
CASE (OP_put_var_ref0) :
CASE (OP_put_var_ref1) :
CASE (OP_put_var_ref2) :
CASE (OP_put_var_ref3) :
CASE (OP_set_var_ref0) :
CASE (OP_set_var_ref1) :
CASE (OP_set_var_ref2) :
CASE (OP_set_var_ref3) :
JS_ThrowInternalError(ctx, "deprecated var_ref opcode (use OP_get_up/OP_set_up)");
goto exception;
BREAK;
#endif
CASE (OP_get_var_ref) :
CASE (OP_put_var_ref) :
CASE (OP_set_var_ref) :
CASE (OP_get_var_ref_check) :
CASE (OP_put_var_ref_check) :
CASE (OP_put_var_ref_check_init) :
pc += 2; /* skip the index */
JS_ThrowInternalError(ctx, "deprecated var_ref opcode (use OP_get_up/OP_set_up)");
goto exception;
BREAK;
CASE (OP_set_loc_uninitialized) : {
int idx;
idx = get_u16 (pc);
@@ -7730,24 +7640,24 @@ restart:
sp--;
}
BREAK;
/* Legacy var_ref reference creation - deprecated, replaced by OP_get_up/OP_set_up */
/* Deprecated var_ref opcodes - should be resolved to get_up/set_up during scope resolution */
CASE (OP_get_var_ref) :
CASE (OP_put_var_ref) :
CASE (OP_set_var_ref) :
CASE (OP_get_var_ref_check) :
CASE (OP_put_var_ref_check) :
CASE (OP_put_var_ref_check_init) :
pc += 2; /* skip the index */
JS_ThrowInternalError(ctx, "deprecated var_ref opcode (use OP_get_up/OP_set_up)");
goto exception;
BREAK;
CASE (OP_close_loc) :
pc += 2;
JS_ThrowInternalError(ctx, "deprecated close_loc opcode");
goto exception;
BREAK;
CASE (OP_make_loc_ref) :
CASE (OP_make_arg_ref) :
CASE (OP_make_var_ref_ref) :
pc += 6;
JS_ThrowInternalError(ctx, "deprecated make_*_ref opcode");
goto exception;
BREAK;
CASE (OP_make_var_ref) :
pc += 4;
JS_ThrowInternalError(ctx, "deprecated make_var_ref opcode");
goto exception;
BREAK;
CASE (OP_goto) : pc += (int32_t)get_u32 (pc);
if (unlikely (js_poll_interrupts (ctx))) goto exception;
@@ -8110,20 +8020,6 @@ restart:
sf->cur_pc = pc;
/* Check if this is a var ref object */
if (JS_VALUE_GET_TAG (ref_obj) == JS_TAG_PTR) {
JSRecord *p = JS_VALUE_GET_OBJ (ref_obj);
if (REC_GET_CLASS_ID(p) == JS_CLASS_VAR_REF_OBJECT) {
JSVarRef *var_ref = (JSVarRef *)REC_GET_OPAQUE(p);
if (var_ref) {
val = var_ref->is_detached ? var_ref->value : *var_ref->pvalue;
*sp++ = val;
break;
}
}
}
/* Fall through to standard property lookup */
if (JS_IsText (key)) { key = js_key_from_string (ctx, key); }
if (unlikely (JS_IsNull (ref_obj))) {
JS_ThrowReferenceErrorNotDefined (ctx, key);
@@ -8166,22 +8062,6 @@ restart:
sf->cur_pc = pc;
/* Check if this is a var ref object */
if (JS_VALUE_GET_TAG (ref_obj) == JS_TAG_PTR) {
JSRecord *p = JS_VALUE_GET_OBJ (ref_obj);
if (REC_GET_CLASS_ID(p) == JS_CLASS_VAR_REF_OBJECT) {
JSVarRef *var_ref = (JSVarRef *)REC_GET_OPAQUE(p);
if (var_ref) {
JSValue *pval = var_ref->is_detached ? &var_ref->value
: var_ref->pvalue;
set_value (ctx, pval, val);
sp -= 3;
break;
}
}
}
/* Fall through to standard property lookup */
if (JS_IsText (key)) { key = js_key_from_string (ctx, key); }
if (unlikely (JS_IsNull (ref_obj))) {
JS_ThrowReferenceErrorNotDefined (ctx, key);
@@ -8747,12 +8627,11 @@ restart:
if (js_operator_delete (ctx, sp)) goto exception;
sp--;
BREAK;
CASE (OP_delete_var) : {
/* Global object is immutable - cannot delete globals */
CASE (OP_delete_var) :
pc += 4;
JS_ThrowInternalError (ctx, "OP_delete_var: global object is immutable");
goto exception;
}
BREAK;
CASE (OP_to_propkey) : switch (JS_VALUE_GET_TAG (sp[-1])) {
@@ -8767,6 +8646,21 @@ restart:
break;
}
BREAK;
/* Deprecated make_*_ref opcodes - no longer needed with outer_frame model */
CASE (OP_make_loc_ref) :
CASE (OP_make_arg_ref) :
CASE (OP_make_var_ref_ref) :
pc += 6;
JS_ThrowInternalError(ctx, "deprecated make_*_ref opcode");
goto exception;
BREAK;
CASE (OP_make_var_ref) :
pc += 4;
JS_ThrowInternalError(ctx, "deprecated make_var_ref opcode");
goto exception;
BREAK;
CASE (OP_template_concat) : {
int n, i;
JSValue out;
@@ -14652,17 +14546,6 @@ static void dump_byte_code (JSContext *ctx, int pass, const uint8_t *tab, int le
printf (" %d: ", idx);
if (idx < arg_count) { print_atom (ctx, args[idx].var_name); }
break;
case OP_FMT_none_var_ref:
idx = (op - OP_get_var_ref0) % 4;
goto has_var_ref;
case OP_FMT_var_ref:
idx = get_u16 (tab + pos);
has_var_ref:
printf (" %d: ", idx);
if (idx < closure_var_count) {
print_atom (ctx, closure_var[idx].var_name);
}
break;
default:
break;
}
@@ -15693,8 +15576,7 @@ static BOOL code_match (CodeContext *s, int pos, ...) {
case OP_FMT_u16:
case OP_FMT_npop:
case OP_FMT_loc:
case OP_FMT_arg:
case OP_FMT_var_ref: {
case OP_FMT_arg: {
int idx = get_u16 (tab + pos);
int arg = va_arg (ap, int);
if (arg == -1) {
@@ -16442,15 +16324,6 @@ static void put_short_code (DynBuf *bc_out, int op, int idx) {
case OP_set_arg:
dbuf_putc (bc_out, OP_set_arg0 + idx);
return;
case OP_get_var_ref:
dbuf_putc (bc_out, OP_get_var_ref0 + idx);
return;
case OP_put_var_ref:
dbuf_putc (bc_out, OP_put_var_ref0 + idx);
return;
case OP_set_var_ref:
dbuf_putc (bc_out, OP_set_var_ref0 + idx);
return;
case OP_call:
dbuf_putc (bc_out, OP_call0 + idx);
return;
@@ -18101,7 +17974,7 @@ static void js_parse_init (JSContext *ctx, JSParseState *s, const char *input, s
s->get_line_col_cache.col_num = 0;
}
static JSValue JS_EvalFunctionInternal (JSContext *ctx, JSValue fun_obj, JSValue this_obj, JSVarRef **var_refs, JSStackFrame *sf) {
static JSValue JS_EvalFunctionInternal (JSContext *ctx, JSValue fun_obj, JSValue this_obj, JSStackFrame *sf) {
JSValue ret_val;
uint32_t tag;
@@ -18117,7 +17990,7 @@ static JSValue JS_EvalFunctionInternal (JSContext *ctx, JSValue fun_obj, JSValue
}
JSValue JS_EvalFunction (JSContext *ctx, JSValue fun_obj) {
return JS_EvalFunctionInternal (ctx, fun_obj, ctx->global_obj, NULL, NULL);
return JS_EvalFunctionInternal (ctx, fun_obj, ctx->global_obj, NULL);
}
/* Link compiled bytecode to context - resolves global references.
@@ -18145,7 +18018,6 @@ static JSValue __JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *
int err, js_mode, eval_type;
JSValue fun_obj, ret_val;
JSStackFrame *sf;
JSVarRef **var_refs;
JSFunctionBytecode *b;
JSFunctionDef *fd;
@@ -18160,12 +18032,10 @@ static JSValue __JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *
fn = JS_VALUE_GET_FUNCTION (sf->cur_func);
assert (fn->kind == JS_FUNC_KIND_BYTECODE);
b = fn->u.func.function_bytecode;
var_refs = fn->u.func.var_refs;
js_mode = b->js_mode;
} else {
sf = NULL;
b = NULL;
var_refs = NULL;
js_mode = 0;
}
fd = js_new_function_def (ctx, NULL, TRUE, FALSE, filename, s->buf_start, &s->get_line_col_cache);
@@ -18200,7 +18070,7 @@ static JSValue __JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *
if (flags & JS_EVAL_FLAG_COMPILE_ONLY) {
ret_val = fun_obj;
} else {
ret_val = JS_EvalFunctionInternal (ctx, fun_obj, this_obj, var_refs, sf);
ret_val = JS_EvalFunctionInternal (ctx, fun_obj, this_obj, sf);
}
return ret_val;
fail1:
@@ -18507,7 +18377,6 @@ static void bc_byte_swap (uint8_t *bc_buf, int bc_len) {
case OP_FMT_npop:
case OP_FMT_loc:
case OP_FMT_arg:
case OP_FMT_var_ref:
put_u16 (bc_buf + pos + 1, bswap16 (get_u16 (bc_buf + pos + 1)));
break;
case OP_FMT_i32:
@@ -23147,12 +23016,6 @@ static void dump_bytecode_opcodes (JSContext *ctx, JSFunctionBytecode *b) {
case OP_FMT_arg:
printf (" arg%d", get_u16 (tab + pos));
break;
case OP_FMT_none_var_ref:
printf (" var_ref%d", (op - OP_get_var_ref0) % 4);
break;
case OP_FMT_var_ref:
printf (" var_ref%d", get_u16 (tab + pos));
break;
default:
break;
}
@@ -26686,56 +26549,6 @@ JSValue js_debugger_fn_bytecode (JSContext *ctx, JSValue fn) {
idx);
}
} break;
case OP_FMT_none_var_ref: {
int idx = (op - OP_get_var_ref0) % 4;
if (idx < b->closure_var_count) {
const char *var_name
= JS_ToCString (ctx, b->closure_var[idx].var_name);
if (var_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d: %s",
idx,
var_name);
JS_FreeCString (ctx, var_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %d",
idx);
}
} break;
case OP_FMT_var_ref: {
int idx = get_u16 (tab + arg_pos);
if (idx < b->closure_var_count) {
const char *var_name
= JS_ToCString (ctx, b->closure_var[idx].var_name);
if (var_name) {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u: %s",
idx,
var_name);
JS_FreeCString (ctx, var_name);
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} else {
snprintf (opcode_str + strlen (opcode_str),
sizeof (opcode_str) - strlen (opcode_str),
" %u",
idx);
}
} break;
default:
break;
}
@@ -26800,55 +26613,14 @@ done:
}
void js_debugger_set_closure_variable (JSContext *ctx, JSValue fn, JSValue var_name, JSValue val) {
if (!js_is_bytecode_function (fn)) return;
JSFunction *f = JS_VALUE_GET_FUNCTION (fn);
JSFunctionBytecode *b = f->u.func.function_bytecode;
const char *name_str = JS_ToCString (ctx, var_name);
if (!name_str) return;
for (uint32_t i = 0; i < b->closure_var_count; i++) {
JSClosureVar *cvar = b->closure_var + i;
const char *cvar_name = JS_ToCString (ctx, cvar->var_name);
if (!cvar_name) continue;
if (strcmp (name_str, cvar_name) == 0) {
JS_FreeCString (ctx, cvar_name);
JSVarRef *var_ref = NULL;
if (f->u.func.var_refs) var_ref = f->u.func.var_refs[i];
if (var_ref && var_ref->pvalue) {
*var_ref->pvalue = val;
}
break;
}
JS_FreeCString (ctx, cvar_name);
}
JS_FreeCString (ctx, name_str);
/* TODO: Reimplement using outer_frame mechanism if debugging is needed */
(void)ctx; (void)fn; (void)var_name; (void)val;
}
JSValue js_debugger_closure_variables (JSContext *ctx, JSValue fn) {
JSValue ret = JS_NewObject (ctx);
if (!js_is_bytecode_function (fn)) goto done;
JSFunction *f = JS_VALUE_GET_FUNCTION (fn);
JSFunctionBytecode *b = f->u.func.function_bytecode;
for (uint32_t i = 0; i < b->closure_var_count; i++) {
JSClosureVar *cvar = b->closure_var + i;
JSValue var_val;
JSVarRef *var_ref = NULL;
if (f->u.func.var_refs) var_ref = f->u.func.var_refs[i];
if (!var_ref || !var_ref->pvalue) continue;
var_val = *var_ref->pvalue;
if (JS_IsUninitialized (var_val)) continue;
JS_SetProperty (ctx, ret, cvar->var_name, var_val);
}
done:
return ret;
/* TODO: Reimplement using outer_frame mechanism if debugging is needed */
(void)fn;
return JS_NewObject (ctx);
}
void *js_debugger_val_address (JSContext *ctx, JSValue val) {