rm old function as object code

This commit is contained in:
2026-01-24 09:55:24 -06:00
parent 20f10ab887
commit f9170b33e5

View File

@@ -172,10 +172,6 @@ enum {
/* classid tag */ /* union usage | properties */
JS_CLASS_OBJECT = 1, /* must be first */
JS_CLASS_ERROR,
JS_CLASS_C_FUNCTION, /* u.cfunc */
JS_CLASS_BYTECODE_FUNCTION, /* u.func */
JS_CLASS_BOUND_FUNCTION, /* u.bound_function */
JS_CLASS_C_FUNCTION_DATA, /* u.c_function_data_record */
JS_CLASS_REGEXP, /* u.regexp */
JS_CLASS_FINALIZATION_REGISTRY,
JS_CLASS_BLOB, /* u.opaque (blob *) */
@@ -933,19 +929,6 @@ struct JSObject {
uint32_t objkey_size; /* allocated size (power of 2, 0 if none) */
union {
void *opaque;
struct JSBoundFunction *bound_function; /* JS_CLASS_BOUND_FUNCTION */
struct JSCFunctionDataRecord *c_function_data_record; /* JS_CLASS_C_FUNCTION_DATA */
struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */
struct JSFunctionBytecode *function_bytecode;
JSVarRef **var_refs;
} func;
struct { /* JS_CLASS_C_FUNCTION: 12/20 bytes */
JSContext *realm;
JSCFunctionType c_function;
uint8_t length;
uint8_t cproto;
int16_t magic;
} cfunc;
JSRegExp regexp; /* JS_CLASS_REGEXP: 8/16 bytes */
} u;
};
@@ -1039,14 +1022,6 @@ static void js_dump_value_write(void *opaque, const char *buf, size_t len);
static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic);
static void free_array(JSRuntime *rt, JSArray *arr);
static void js_c_function_finalizer(JSRuntime *rt, JSValue val);
static void js_c_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val);
static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func);
static void js_bound_function_finalizer(JSRuntime *rt, JSValue val);
static void js_bound_function_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func);
static void js_regexp_finalizer(JSRuntime *rt, JSValue val);
static JSValue js_new_function(JSContext *ctx, JSFunctionKind kind);
static void free_function(JSRuntime *rt, JSFunction *func);
@@ -1129,9 +1104,6 @@ static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen,
JSValueConst array_arg);
static BOOL js_get_fast_array(JSContext *ctx, JSValueConst obj,
JSValue **arrpp, uint32_t *countp);
static void js_c_function_data_finalizer(JSRuntime *rt, JSValue val);
static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func);
static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_val,
int argc, JSValueConst *argv, int flags);
@@ -1332,10 +1304,6 @@ typedef struct JSClassShortDef {
static JSClassShortDef const js_std_class_def[] = {
{ JS_ATOM_Object, NULL, NULL }, /* JS_CLASS_OBJECT */
{ JS_ATOM_Error, NULL, NULL }, /* JS_CLASS_ERROR */
{ JS_ATOM_Function, js_c_function_finalizer, js_c_function_mark }, /* JS_CLASS_C_FUNCTION */
{ JS_ATOM_Function, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_BYTECODE_FUNCTION */
{ JS_ATOM_Function, js_bound_function_finalizer, js_bound_function_mark }, /* JS_CLASS_BOUND_FUNCTION */
{ JS_ATOM_Function, js_c_function_data_finalizer, js_c_function_data_mark }, /* JS_CLASS_C_FUNCTION_DATA */
{ JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */
};
@@ -1419,9 +1387,6 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
if (init_class_range(rt, js_std_class_def, JS_CLASS_OBJECT,
countof(js_std_class_def)) < 0)
goto fail;
rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function;
rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call;
rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function;
if (init_shape_hash(rt))
goto fail;
@@ -4837,9 +4802,6 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas
switch(class_id) {
case JS_CLASS_OBJECT:
break;
case JS_CLASS_C_FUNCTION:
p->prop[0].u.value = JS_NULL;
break;
case JS_CLASS_REGEXP:
p->u.regexp.pattern = NULL;
p->u.regexp.bytecode = NULL;
@@ -4936,9 +4898,13 @@ static void js_function_set_properties(JSContext *ctx, JSValueConst func_obj,
JS_SetPropertyInternal(ctx, func_obj, JS_ATOM_name, JS_AtomToString(ctx, name));
}
static BOOL js_class_has_bytecode(JSClassID class_id)
/* Helper to check if a value is a bytecode function */
static BOOL js_is_bytecode_function(JSValueConst val)
{
return class_id == JS_CLASS_BYTECODE_FUNCTION;
if (JS_VALUE_GET_TAG(val) != JS_TAG_FUNCTION)
return FALSE;
JSFunction *f = JS_VALUE_GET_FUNCTION(val);
return f->kind == JS_FUNC_KIND_BYTECODE;
}
/* Check if a value is a function that uses proxy-call syntax (fn.a -> fn("a")) */
@@ -4977,13 +4943,10 @@ static JSValue js_get_function_name(JSContext *ctx, JSAtom name)
static int js_method_set_properties(JSContext *ctx, JSValueConst func_obj,
JSAtom name, int flags, JSValueConst home_obj)
{
JSValue name_str;
name_str = js_get_function_name(ctx, name);
if (JS_IsException(name_str))
return -1;
if (JS_SetPropertyInternal(ctx, func_obj, JS_ATOM_name, name_str) < 0)
if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_FUNCTION)
return -1;
JSFunction *f = JS_VALUE_GET_FUNCTION(func_obj);
f->name = JS_DupAtom(ctx, name);
return 0;
}
@@ -5036,32 +4999,6 @@ typedef struct JSCFunctionDataRecord {
JSValue data[0];
} JSCFunctionDataRecord;
static void js_c_function_data_finalizer(JSRuntime *rt, JSValue val)
{
JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA);
int i;
if (s) {
for(i = 0; i < s->data_len; i++) {
JS_FreeValueRT(rt, s->data[i]);
}
js_free_rt(rt, s);
}
}
static void js_c_function_data_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func)
{
JSCFunctionDataRecord *s = JS_GetOpaque(val, JS_CLASS_C_FUNCTION_DATA);
int i;
if (s) {
for(i = 0; i < s->data_len; i++) {
JS_MarkValue(rt, s->data[i], mark_func);
}
}
}
static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_val,
int argc, JSValueConst *argv, int flags)
@@ -5277,23 +5214,6 @@ static int js_intrinsic_array_set(JSContext *ctx, JSArray *arr, uint32_t idx, JS
return TRUE;
}
static void js_c_function_finalizer(JSRuntime *rt, JSValue val)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
if (p->u.cfunc.realm)
JS_FreeContext(p->u.cfunc.realm);
}
static void js_c_function_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
if (p->u.cfunc.realm)
mark_func(rt, &p->u.cfunc.realm->header);
}
/* Allocate intrinsic function (JS_TAG_FUNCTION) */
static JSValue js_new_function(JSContext *ctx, JSFunctionKind kind)
{
@@ -5475,75 +5395,6 @@ static void mark_function_children_decref(JSRuntime *rt, JSFunction *func)
}
}
static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
JSFunctionBytecode *b;
JSVarRef **var_refs;
int i;
b = p->u.func.function_bytecode;
if (b) {
var_refs = p->u.func.var_refs;
if (var_refs) {
for(i = 0; i < b->closure_var_count; i++)
free_var_ref(rt, var_refs[i]);
js_free_rt(rt, var_refs);
}
JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b));
}
}
static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
JSVarRef **var_refs = p->u.func.var_refs;
JSFunctionBytecode *b = p->u.func.function_bytecode;
int i;
if (b) {
if (var_refs) {
for(i = 0; i < b->closure_var_count; i++) {
JSVarRef *var_ref = var_refs[i];
if (var_ref) {
mark_func(rt, &var_ref->header);
}
}
}
/* must mark the function bytecode because template objects may be
part of a cycle */
JS_MarkValue(rt, JS_MKPTR(JS_TAG_FUNCTION_BYTECODE, b), mark_func);
}
}
static void js_bound_function_finalizer(JSRuntime *rt, JSValue val)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
JSBoundFunction *bf = p->u.bound_function;
int i;
JS_FreeValueRT(rt, bf->func_obj);
JS_FreeValueRT(rt, bf->this_val);
for(i = 0; i < bf->argc; i++) {
JS_FreeValueRT(rt, bf->argv[i]);
}
js_free_rt(rt, bf);
}
static void js_bound_function_mark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func)
{
JSObject *p = JS_VALUE_GET_OBJ(val);
JSBoundFunction *bf = p->u.bound_function;
int i;
JS_MarkValue(rt, bf->func_obj, mark_func);
JS_MarkValue(rt, bf->this_val, mark_func);
for(i = 0; i < bf->argc; i++)
JS_MarkValue(rt, bf->argv[i], mark_func);
}
static void free_object(JSRuntime *rt, JSObject *p)
{
int i;
@@ -5591,7 +5442,6 @@ static void free_object(JSRuntime *rt, JSObject *p)
/* fail safe */
p->class_id = 0;
p->u.opaque = NULL;
p->u.func.var_refs = NULL;
remove_gc_object(&p->header);
/* no more weakrefs: free if no strong refs, else queue for zero-ref processing */
@@ -6372,55 +6222,6 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s)
}
switch(p->class_id) {
case JS_CLASS_C_FUNCTION: /* u.cfunc */
s->c_func_count++;
break;
case JS_CLASS_BYTECODE_FUNCTION: /* u.func */
{
JSFunctionBytecode *b = p->u.func.function_bytecode;
JSVarRef **var_refs = p->u.func.var_refs;
/* home_object: object will be accounted for in list scan */
if (var_refs) {
s->memory_used_count++;
s->js_func_size += b->closure_var_count * sizeof(*var_refs);
for (i = 0; i < b->closure_var_count; i++) {
if (var_refs[i]) {
double ref_count = var_refs[i]->header.ref_count;
s->memory_used_count += 1 / ref_count;
s->js_func_size += sizeof(*var_refs[i]) / ref_count;
/* handle non object closed values */
if (var_refs[i]->pvalue == &var_refs[i]->value) {
/* potential multiple count */
compute_value_size(var_refs[i]->value, hp);
}
}
}
}
}
break;
case JS_CLASS_BOUND_FUNCTION: /* u.bound_function */
{
JSBoundFunction *bf = p->u.bound_function;
/* func_obj and this_val are objects */
for (i = 0; i < bf->argc; i++) {
compute_value_size(bf->argv[i], hp);
}
s->memory_used_count += 1;
s->memory_used_size += sizeof(*bf) + bf->argc * sizeof(*bf->argv);
}
break;
case JS_CLASS_C_FUNCTION_DATA: /* u.c_function_data_record */
{
JSCFunctionDataRecord *fd = p->u.c_function_data_record;
if (fd) {
for (i = 0; i < fd->data_len; i++) {
compute_value_size(fd->data[i], hp);
}
s->memory_used_count += 1;
s->memory_used_size += sizeof(*fd) + fd->data_len * sizeof(*fd->data);
}
}
break;
case JS_CLASS_REGEXP: /* u.regexp */
compute_jsstring_size(p->u.regexp.pattern, hp);
compute_jsstring_size(p->u.regexp.bytecode, hp);
@@ -9351,22 +9152,7 @@ static void js_print_object(JSPrintValueState *s, JSObject *p)
comma_state = 0;
is_array = FALSE;
if (p->class_id == JS_CLASS_BYTECODE_FUNCTION || rt->class_array[p->class_id].call != NULL) {
js_printf(s, "[Function");
/* XXX: allow dump without ctx */
if (!s->options.raw_dump && s->ctx) {
const char *func_name_str;
js_putc(s, ' ');
func_name_str = get_func_name(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p));
if (!func_name_str || func_name_str[0] == '\0')
js_puts(s, "(anonymous)");
else
js_puts(s, func_name_str);
JS_FreeCString(s->ctx, func_name_str);
}
js_printf(s, "]");
comma_state = 2;
} else if (p->class_id == JS_CLASS_REGEXP && s->ctx && !s->options.raw_dump) {
if (p->class_id == JS_CLASS_REGEXP && s->ctx && !s->options.raw_dump) {
JSValue str = js_regexp_toString(s->ctx, JS_MKPTR(JS_TAG_OBJECT, p), 0, NULL);
if (JS_IsException(str))
goto default_obj;
@@ -9428,22 +9214,6 @@ static void js_print_object(JSPrintValueState *s, JSObject *p)
if (j > s->options.max_item_count)
js_print_more_items(s, &comma_state, j - s->options.max_item_count);
}
if (s->options.raw_dump && js_class_has_bytecode(p->class_id)) {
JSFunctionBytecode *b = p->u.func.function_bytecode;
if (b->closure_var_count) {
JSVarRef **var_refs;
var_refs = p->u.func.var_refs;
js_print_comma(s, &comma_state);
js_printf(s, "[[Closure]]: [");
for(i = 0; i < b->closure_var_count; i++) {
if (i != 0)
js_printf(s, ", ");
js_print_value(s, var_refs[i]->value);
}
js_printf(s, " ]");
}
}
if (!is_array) {
if (comma_state != 2) {
@@ -10649,219 +10419,6 @@ static void profile_record_prop_site(JSRuntime *rt, JSFunctionBytecode *b, uint3
}
#endif
/* VM frame management for trampoline - no malloc/free! */
static struct VMFrame *vm_push_frame(JSContext *ctx,
JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValue *argv, int flags,
const uint8_t *ret_pc, int ret_sp_offset,
int call_argc, int call_has_this)
{
JSFunction *f;
JSFunctionBytecode *b;
struct VMFrame *frame;
int total_slots, i, arg_allocated_size;
JSValue *stack_base, *arg_buf, *var_buf;
f = JS_VALUE_GET_FUNCTION(func_obj);
b = f->u.func.function_bytecode;
/* Check frame stack capacity */
if (ctx->frame_stack_top + 1 >= ctx->frame_stack_capacity) {
/* TODO: grow frame stack (for now, fail) */
return NULL;
}
/* Calculate space needed: args + vars + operand stack */
if (argc < b->arg_count || (flags & JS_CALL_FLAG_COPY_ARGV)) {
arg_allocated_size = b->arg_count;
} else {
arg_allocated_size = 0;
}
total_slots = arg_allocated_size + b->var_count + b->stack_size;
/* Check value stack capacity */
if (ctx->value_stack_top + total_slots > ctx->value_stack_capacity) {
/* TODO: grow value stack (for now, fail) */
return NULL;
}
/* Push frame */
ctx->frame_stack_top++;
frame = &ctx->frame_stack[ctx->frame_stack_top];
/* Store offsets (safe with realloc) */
frame->value_stack_base = ctx->value_stack_top;
frame->stack_size_allocated = total_slots;
/* Get pointers for initialization (only used locally) */
stack_base = &ctx->value_stack[frame->value_stack_base];
if (arg_allocated_size) {
frame->arg_buf_offset = 0;
arg_buf = stack_base;
for (i = 0; i < min_int(argc, b->arg_count); i++)
arg_buf[i] = JS_DupValue(ctx, argv[i]);
for (; i < b->arg_count; i++)
arg_buf[i] = JS_NULL;
frame->arg_count = b->arg_count;
} else {
frame->arg_buf_offset = -1; /* signal: args are aliased from caller */
frame->arg_count = argc;
}
frame->var_buf_offset = arg_allocated_size;
var_buf = stack_base + arg_allocated_size;
for (i = 0; i < b->var_count; i++)
var_buf[i] = JS_NULL;
frame->sp_offset = arg_allocated_size + b->var_count;
/* Initialize frame metadata */
frame->cur_func = JS_DupValue(ctx, func_obj);
frame->this_obj = JS_DupValue(ctx, this_obj);
frame->b = b;
frame->ctx = b->realm;
frame->pc = b->byte_code_buf;
frame->js_mode = b->js_mode;
frame->var_refs = f->u.func.var_refs;
init_list_head(&frame->var_ref_list);
/* Continuation info for return */
frame->ret_pc = ret_pc;
frame->ret_sp_offset = ret_sp_offset;
frame->call_argc = call_argc;
frame->call_has_this = call_has_this;
/* Bump value stack top */
ctx->value_stack_top += total_slots;
return frame;
}
static void vm_pop_frame(JSContext *ctx)
{
struct VMFrame *frame;
int i;
struct list_head *el, *el1;
JSValue *stack_base;
if (ctx->frame_stack_top < 0)
return;
frame = &ctx->frame_stack[ctx->frame_stack_top];
stack_base = &ctx->value_stack[frame->value_stack_base];
/* Close variable references */
if (!list_empty(&frame->var_ref_list)) {
list_for_each_safe(el, el1, &frame->var_ref_list) {
struct JSVarRef *var_ref = list_entry(el, struct JSVarRef, var_ref_link);
var_ref->value = JS_DupValue(ctx, *var_ref->pvalue);
var_ref->pvalue = &var_ref->value;
var_ref->is_detached = TRUE;
list_del(&var_ref->var_ref_link);
}
}
/* Free all values in this frame's value stack region */
for (i = 0; i < frame->stack_size_allocated; i++)
JS_FreeValue(ctx, stack_base[i]);
/* Free frame values */
JS_FreeValue(ctx, frame->cur_func);
JS_FreeValue(ctx, frame->this_obj);
/* Pop frame and value stack */
ctx->value_stack_top -= frame->stack_size_allocated;
ctx->frame_stack_top--;
}
/* Helper: get pointer from offset (used in hot path) */
static inline JSValue *vm_frame_get_stack_ptr(JSContext *ctx, struct VMFrame *frame, int offset)
{
return &ctx->value_stack[frame->value_stack_base + offset];
}
/* Helper: get current sp pointer for a frame */
static inline JSValue *vm_frame_get_sp(JSContext *ctx, struct VMFrame *frame)
{
return &ctx->value_stack[frame->value_stack_base + frame->sp_offset];
}
/* Helper: get var_buf pointer for a frame */
static inline JSValue *vm_frame_get_var_buf(JSContext *ctx, struct VMFrame *frame)
{
return &ctx->value_stack[frame->value_stack_base + frame->var_buf_offset];
}
/* Helper: get arg_buf pointer for a frame (or NULL if aliased) */
static inline JSValue *vm_frame_get_arg_buf(JSContext *ctx, struct VMFrame *frame)
{
if (frame->arg_buf_offset < 0)
return NULL; /* aliased */
return &ctx->value_stack[frame->value_stack_base + frame->arg_buf_offset];
}
/* Trampoline VM dispatcher - runs frames without C recursion */
static JSValue JS_CallTrampoline(JSContext *caller_ctx, JSValueConst func_obj,
JSValueConst this_obj,
int argc, JSValue *argv, int flags)
{
JSRuntime *rt = caller_ctx->rt;
JSObject *p;
JSValue ret_val = JS_NULL;
struct VMFrame *frame;
/* Check if function is callable */
if (js_poll_interrupts(caller_ctx))
return JS_EXCEPTION;
if (unlikely(JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT))
return JS_ThrowTypeError(caller_ctx, "not a function");
p = JS_VALUE_GET_OBJ(func_obj);
if (unlikely(p->class_id != JS_CLASS_BYTECODE_FUNCTION)) {
JSClassCall *call_func;
call_func = rt->class_array[p->class_id].call;
if (!call_func)
return JS_ThrowTypeError(caller_ctx, "not a function");
return call_func(caller_ctx, func_obj, this_obj, argc,
(JSValueConst *)argv, flags);
}
/* Push initial frame (entry point, no continuation) */
frame = vm_push_frame(caller_ctx, func_obj, this_obj,
argc, argv, flags,
NULL, 0, 0, 0);
if (!frame)
return JS_ThrowStackOverflow(caller_ctx);
/* Trampoline loop - execute frames without C recursion */
while (caller_ctx->frame_stack_top >= 0) {
/* For now, fall back to old JS_CallInternal for the actual execution */
/* This is a stub - we'll implement vm_execute_frame next */
/* TODO: call vm_execute_frame(caller_ctx, frame) here */
/* For now, just return and clean up */
vm_pop_frame(caller_ctx);
break;
}
return ret_val;
}
/* Execute a single frame (delegates to OLD implementation for now) */
static VMExecState vm_execute_frame(JSContext *ctx, struct VMFrame *frame,
JSValue *ret_val, VMCallInfo *call_info)
{
/* TODO: Replace with proper bytecode loop extraction */
/* For now, delegate to the old recursive implementation */
*ret_val = JS_CallInternal(ctx, frame->cur_func, frame->this_obj,
frame->arg_count,
vm_frame_get_arg_buf(ctx, frame), 0);
if (JS_IsException(*ret_val))
return VM_EXEC_EXCEPTION;
return VM_EXEC_RETURN;
}
static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JSValueConst this_obj,
int argc, JSValue *argv, int flags)
@@ -30707,10 +30264,10 @@ static void JS_AddIntrinsicBasicObjects(JSContext *ctx)
ctx->class_proto[JS_CLASS_OBJECT] = JS_NewObjectProto(ctx, JS_NULL);
/* function_proto is kept for API compatibility but functions are now intrinsic types */
ctx->function_proto = JS_NewCFunction3(ctx, js_function_proto, "", 0,
JS_CFUNC_generic, 0,
ctx->class_proto[JS_CLASS_OBJECT]);
ctx->class_proto[JS_CLASS_BYTECODE_FUNCTION] = JS_DupValue(ctx, ctx->function_proto);
ctx->class_proto[JS_CLASS_ERROR] = JS_NewObject(ctx);
for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) {
@@ -31072,10 +30629,10 @@ JSValue js_debugger_build_backtrace(JSContext *ctx, const uint8_t *cur_pc)
JSValue js_debugger_fn_info(JSContext *ctx, JSValue fn)
{
JSValue ret = JS_NewObject(ctx);
JSObject *f = JS_VALUE_GET_OBJ(fn);
if (!f || !js_class_has_bytecode(f->class_id))
if (!js_is_bytecode_function(fn))
goto done;
JSFunction *f = JS_VALUE_GET_FUNCTION(fn);
JSFunctionBytecode *b = f->u.func.function_bytecode;
char atom_buf[ATOM_GET_STR_BUF_SIZE];
const char *str;
@@ -31177,10 +30734,10 @@ static const char *opcode_names[] = {
JSValue js_debugger_fn_bytecode(JSContext *ctx, JSValue fn)
{
JSObject *f = JS_VALUE_GET_OBJ(fn);
if (!f || !js_class_has_bytecode(f->class_id))
if (!js_is_bytecode_function(fn))
return JS_NULL;
JSFunction *f = JS_VALUE_GET_FUNCTION(fn);
JSFunctionBytecode *b = f->u.func.function_bytecode;
JSValue ret = JS_NewArray(ctx);
@@ -31493,8 +31050,8 @@ JSValue js_debugger_local_variables(JSContext *ctx, int stack_index) {
for(sf = ctx->rt->current_stack_frame; sf != NULL; sf = sf->prev_frame) {
// this val is one frame up
if (cur_index == stack_index - 1) {
JSObject *f = JS_VALUE_GET_OBJ(sf->cur_func);
if (f && js_class_has_bytecode(f->class_id)) {
if (js_is_bytecode_function(sf->cur_func)) {
JSFunction *f = JS_VALUE_GET_FUNCTION(sf->cur_func);
JSFunctionBytecode *b = f->u.func.function_bytecode;
JSValue this_obj = sf->var_buf[b->var_count];
@@ -31509,9 +31066,9 @@ JSValue js_debugger_local_variables(JSContext *ctx, int stack_index) {
continue;
}
JSObject *f = JS_VALUE_GET_OBJ(sf->cur_func);
if (!f || !js_class_has_bytecode(f->class_id))
if (!js_is_bytecode_function(sf->cur_func))
goto done;
JSFunction *f = JS_VALUE_GET_FUNCTION(sf->cur_func);
JSFunctionBytecode *b = f->u.func.function_bytecode;
for (uint32_t i = 0; i < b->arg_count + b->var_count; i++) {
@@ -31537,10 +31094,10 @@ done:
void js_debugger_set_closure_variable(JSContext *ctx, JSValue fn, JSValue var_name, JSValue val)
{
JSObject *f = JS_VALUE_GET_OBJ(fn);
if (!f || !js_class_has_bytecode(f->class_id))
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)
@@ -31571,10 +31128,10 @@ void js_debugger_set_closure_variable(JSContext *ctx, JSValue fn, JSValue var_na
JSValue js_debugger_closure_variables(JSContext *ctx, JSValue fn) {
JSValue ret = JS_NewObject(ctx);
JSObject *f = JS_VALUE_GET_OBJ(fn);
if (!f || !js_class_has_bytecode(f->class_id))
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++) {