Begin removal of varref
This commit is contained in:
282
source/quickjs.c
282
source/quickjs.c
@@ -1885,9 +1885,7 @@ static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSVal
|
|||||||
static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||||
static JSValue js_print (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
static JSValue js_print (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
|
||||||
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
|
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
|
||||||
static JSVarRef *get_var_ref (JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg);
|
|
||||||
static JSValue JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx);
|
static JSValue JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx);
|
||||||
static void free_var_ref (JSRuntime *rt, JSVarRef *var_ref);
|
|
||||||
|
|
||||||
static int js_string_compare (JSContext *ctx, const JSText *p1, const JSText *p2);
|
static int js_string_compare (JSContext *ctx, const JSText *p1, const JSText *p2);
|
||||||
static JSValue JS_ToNumber (JSContext *ctx, JSValue val);
|
static JSValue JS_ToNumber (JSContext *ctx, JSValue val);
|
||||||
@@ -6794,81 +6792,20 @@ static JSValue JS_GetActiveFunction (JSContext *ctx) {
|
|||||||
return ctx->rt->current_stack_frame->cur_func;
|
return ctx->rt->current_stack_frame->cur_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSVarRef *get_var_ref (JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg) {
|
static JSValue js_closure2 (JSContext *ctx, JSValue func_obj, JSFunctionBytecode *b, JSStackFrame *sf) {
|
||||||
JSVarRef *var_ref;
|
|
||||||
struct list_head *el;
|
|
||||||
JSValue *pvalue;
|
|
||||||
|
|
||||||
if (is_arg)
|
|
||||||
pvalue = &sf->arg_buf[var_idx];
|
|
||||||
else
|
|
||||||
pvalue = &sf->var_buf[var_idx];
|
|
||||||
|
|
||||||
list_for_each (el, &sf->var_ref_list) {
|
|
||||||
var_ref = list_entry (el, JSVarRef, var_ref_link);
|
|
||||||
if (var_ref->pvalue == pvalue) {
|
|
||||||
/* With copying GC, no need to increment ref_count */
|
|
||||||
return var_ref;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* create a new one - use regular heap, not GC heap, to avoid pointer invalidation */
|
|
||||||
var_ref = pjs_mallocz (sizeof (JSVarRef));
|
|
||||||
if (!var_ref) return NULL;
|
|
||||||
var_ref->is_detached = FALSE;
|
|
||||||
list_add_tail (&var_ref->var_ref_link, &sf->var_ref_list);
|
|
||||||
var_ref->pvalue = pvalue;
|
|
||||||
return var_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_closure2 (JSContext *ctx, JSValue func_obj, JSFunctionBytecode *b, JSVarRef **cur_var_refs, JSStackFrame *sf) {
|
|
||||||
JSFunction *f;
|
JSFunction *f;
|
||||||
JSVarRef **var_refs;
|
|
||||||
JSGCRef func_obj_ref;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
f = JS_VALUE_GET_FUNCTION (func_obj);
|
f = JS_VALUE_GET_FUNCTION (func_obj);
|
||||||
f->u.func.function_bytecode = b;
|
f->u.func.function_bytecode = b;
|
||||||
f->u.func.var_refs = NULL;
|
f->u.func.var_refs = NULL;
|
||||||
f->u.func.outer_frame = JS_NULL; /* Will be set after GC-safe operations */
|
|
||||||
|
|
||||||
/* Also populate var_refs for backward compatibility with existing bytecode
|
/* Set outer_frame to parent's JSFrame for the new closure model.
|
||||||
that uses OP_get_var_ref/OP_put_var_ref opcodes. */
|
This allows OP_get_up/OP_set_up to access captured variables via frame chain. */
|
||||||
if (b->closure_var_count) {
|
|
||||||
/* Use pjs_mallocz for var_refs - regular heap, not GC-managed */
|
|
||||||
var_refs = pjs_mallocz(sizeof(var_refs[0]) * b->closure_var_count);
|
|
||||||
if (!var_refs) goto fail;
|
|
||||||
f->u.func.var_refs = var_refs;
|
|
||||||
for (i = 0; i < b->closure_var_count; i++) {
|
|
||||||
JSClosureVar *cv = &b->closure_var[i];
|
|
||||||
JSVarRef *var_ref;
|
|
||||||
if (cv->is_local) {
|
|
||||||
/* reuse the existing variable reference if it already exists */
|
|
||||||
/* Protect func_obj from GC during get_var_ref */
|
|
||||||
JS_PUSH_VALUE(ctx, func_obj);
|
|
||||||
var_ref = get_var_ref (ctx, sf, cv->var_idx, cv->is_arg);
|
|
||||||
JS_POP_VALUE(ctx, func_obj);
|
|
||||||
if (!var_ref) goto fail;
|
|
||||||
/* Re-fetch f and var_refs after potential GC */
|
|
||||||
f = JS_VALUE_GET_FUNCTION (func_obj);
|
|
||||||
var_refs = f->u.func.var_refs;
|
|
||||||
} else {
|
|
||||||
var_ref = cur_var_refs[cv->var_idx];
|
|
||||||
}
|
|
||||||
var_refs[i] = var_ref;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set outer_frame AFTER all GC-triggering operations.
|
|
||||||
sf->js_frame may have been updated by GC, so we read it here. */
|
|
||||||
f = JS_VALUE_GET_FUNCTION (func_obj);
|
|
||||||
f->u.func.outer_frame = sf ? sf->js_frame : JS_NULL;
|
f->u.func.outer_frame = sf ? sf->js_frame : JS_NULL;
|
||||||
|
|
||||||
return func_obj;
|
return func_obj;
|
||||||
fail:
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_closure (JSContext *ctx, JSValue bfunc, JSVarRef **cur_var_refs, JSStackFrame *sf) {
|
static JSValue js_closure (JSContext *ctx, JSValue bfunc, JSStackFrame *sf) {
|
||||||
JSFunctionBytecode *b;
|
JSFunctionBytecode *b;
|
||||||
JSValue func_obj;
|
JSValue func_obj;
|
||||||
JSFunction *f;
|
JSFunction *f;
|
||||||
@@ -6886,7 +6823,7 @@ static JSValue js_closure (JSContext *ctx, JSValue bfunc, JSVarRef **cur_var_ref
|
|||||||
JS_POP_VALUE (ctx, bfunc);
|
JS_POP_VALUE (ctx, bfunc);
|
||||||
b = JS_VALUE_GET_PTR (bfunc);
|
b = JS_VALUE_GET_PTR (bfunc);
|
||||||
|
|
||||||
func_obj = js_closure2 (ctx, func_obj, b, cur_var_refs, sf);
|
func_obj = js_closure2 (ctx, func_obj, b, sf);
|
||||||
if (JS_IsException (func_obj)) {
|
if (JS_IsException (func_obj)) {
|
||||||
/* bfunc has been freed */
|
/* bfunc has been freed */
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -6902,38 +6839,6 @@ fail:
|
|||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_var_refs (JSRuntime *rt, JSStackFrame *sf) {
|
|
||||||
struct list_head *el, *el1;
|
|
||||||
JSVarRef *var_ref;
|
|
||||||
|
|
||||||
list_for_each_safe (el, el1, &sf->var_ref_list) {
|
|
||||||
var_ref = list_entry (el, JSVarRef, var_ref_link);
|
|
||||||
/* no need to unlink var_ref->var_ref_link as the list is never used
|
|
||||||
* afterwards */
|
|
||||||
var_ref->value = *var_ref->pvalue;
|
|
||||||
var_ref->pvalue = &var_ref->value;
|
|
||||||
/* the reference is no longer to a local variable */
|
|
||||||
var_ref->is_detached = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_lexical_var (JSContext *ctx, JSStackFrame *sf, int var_idx) {
|
|
||||||
JSValue *pvalue;
|
|
||||||
struct list_head *el, *el1;
|
|
||||||
JSVarRef *var_ref;
|
|
||||||
|
|
||||||
pvalue = &sf->var_buf[var_idx];
|
|
||||||
list_for_each_safe (el, el1, &sf->var_ref_list) {
|
|
||||||
var_ref = list_entry (el, JSVarRef, var_ref_link);
|
|
||||||
if (var_ref->pvalue == pvalue) {
|
|
||||||
list_del (&var_ref->var_ref_link);
|
|
||||||
var_ref->value = *var_ref->pvalue;
|
|
||||||
var_ref->pvalue = &var_ref->value;
|
|
||||||
/* the reference is no longer to a local variable */
|
|
||||||
var_ref->is_detached = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define JS_CALL_FLAG_COPY_ARGV (1 << 1)
|
#define JS_CALL_FLAG_COPY_ARGV (1 << 1)
|
||||||
|
|
||||||
@@ -7079,7 +6984,6 @@ static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue
|
|||||||
const uint8_t *pc;
|
const uint8_t *pc;
|
||||||
int opcode, arg_allocated_size, i;
|
int opcode, arg_allocated_size, i;
|
||||||
JSValue *local_buf, *stack_buf, *var_buf, *arg_buf, *sp, ret_val, *pval;
|
JSValue *local_buf, *stack_buf, *var_buf, *arg_buf, *sp, ret_val, *pval;
|
||||||
JSVarRef **var_refs;
|
|
||||||
size_t alloca_size;
|
size_t alloca_size;
|
||||||
|
|
||||||
#if !DIRECT_DISPATCH
|
#if !DIRECT_DISPATCH
|
||||||
@@ -7157,8 +7061,6 @@ static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue
|
|||||||
sf->js_mode = b->js_mode;
|
sf->js_mode = b->js_mode;
|
||||||
sf->arg_count = argc;
|
sf->arg_count = argc;
|
||||||
sf->cur_func = (JSValue)func_obj;
|
sf->cur_func = (JSValue)func_obj;
|
||||||
init_list_head (&sf->var_ref_list);
|
|
||||||
var_refs = f->u.func.var_refs;
|
|
||||||
|
|
||||||
/* Allocate JSFrame for args + vars on regular heap (stable pointers).
|
/* Allocate JSFrame for args + vars on regular heap (stable pointers).
|
||||||
This enables the outer_frame closure model. */
|
This enables the outer_frame closure model. */
|
||||||
@@ -7236,7 +7138,7 @@ restart:
|
|||||||
CASE (OP_push_const8) : *sp++ = b->cpool[*pc++];
|
CASE (OP_push_const8) : *sp++ = b->cpool[*pc++];
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_fclosure8)
|
CASE (OP_fclosure8)
|
||||||
: *sp++ = js_closure (ctx, b->cpool[*pc++], var_refs, sf);
|
: *sp++ = js_closure (ctx, b->cpool[*pc++], sf);
|
||||||
if (unlikely (JS_IsException (sp[-1]))) goto exception;
|
if (unlikely (JS_IsException (sp[-1]))) goto exception;
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_push_empty_string) : *sp++ = JS_KEY_empty;
|
CASE (OP_push_empty_string) : *sp++ = JS_KEY_empty;
|
||||||
@@ -7430,7 +7332,7 @@ restart:
|
|||||||
CASE (OP_fclosure) : {
|
CASE (OP_fclosure) : {
|
||||||
JSValue bfunc = b->cpool[get_u32 (pc)];
|
JSValue bfunc = b->cpool[get_u32 (pc)];
|
||||||
pc += 4;
|
pc += 4;
|
||||||
*sp++ = js_closure (ctx, bfunc, var_refs, sf);
|
*sp++ = js_closure (ctx, bfunc, sf);
|
||||||
if (unlikely (JS_IsException (sp[-1]))) goto exception;
|
if (unlikely (JS_IsException (sp[-1]))) goto exception;
|
||||||
}
|
}
|
||||||
BREAK;
|
BREAK;
|
||||||
@@ -7746,98 +7648,32 @@ restart:
|
|||||||
CASE (OP_set_arg3)
|
CASE (OP_set_arg3)
|
||||||
: set_value (ctx, &arg_buf[3], sp[-1]);
|
: set_value (ctx, &arg_buf[3], sp[-1]);
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_get_var_ref0) : *sp++ = *var_refs[0]->pvalue;
|
/* Legacy var_ref opcodes - deprecated, replaced by OP_get_up/OP_set_up */
|
||||||
BREAK;
|
CASE (OP_get_var_ref0) :
|
||||||
CASE (OP_get_var_ref1) : *sp++ = *var_refs[1]->pvalue;
|
CASE (OP_get_var_ref1) :
|
||||||
BREAK;
|
CASE (OP_get_var_ref2) :
|
||||||
CASE (OP_get_var_ref2) : *sp++ = *var_refs[2]->pvalue;
|
CASE (OP_get_var_ref3) :
|
||||||
BREAK;
|
CASE (OP_put_var_ref0) :
|
||||||
CASE (OP_get_var_ref3) : *sp++ = *var_refs[3]->pvalue;
|
CASE (OP_put_var_ref1) :
|
||||||
BREAK;
|
CASE (OP_put_var_ref2) :
|
||||||
CASE (OP_put_var_ref0) : set_value (ctx, var_refs[0]->pvalue, *--sp);
|
CASE (OP_put_var_ref3) :
|
||||||
BREAK;
|
CASE (OP_set_var_ref0) :
|
||||||
CASE (OP_put_var_ref1) : set_value (ctx, var_refs[1]->pvalue, *--sp);
|
CASE (OP_set_var_ref1) :
|
||||||
BREAK;
|
CASE (OP_set_var_ref2) :
|
||||||
CASE (OP_put_var_ref2) : set_value (ctx, var_refs[2]->pvalue, *--sp);
|
CASE (OP_set_var_ref3) :
|
||||||
BREAK;
|
JS_ThrowInternalError(ctx, "deprecated var_ref opcode (use OP_get_up/OP_set_up)");
|
||||||
CASE (OP_put_var_ref3) : set_value (ctx, var_refs[3]->pvalue, *--sp);
|
goto exception;
|
||||||
BREAK;
|
|
||||||
CASE (OP_set_var_ref0)
|
|
||||||
: set_value (ctx, var_refs[0]->pvalue, sp[-1]);
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_set_var_ref1)
|
|
||||||
: set_value (ctx, var_refs[1]->pvalue, sp[-1]);
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_set_var_ref2)
|
|
||||||
: set_value (ctx, var_refs[2]->pvalue, sp[-1]);
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_set_var_ref3)
|
|
||||||
: set_value (ctx, var_refs[3]->pvalue, sp[-1]);
|
|
||||||
BREAK;
|
BREAK;
|
||||||
#endif
|
#endif
|
||||||
|
CASE (OP_get_var_ref) :
|
||||||
CASE (OP_get_var_ref) : {
|
CASE (OP_put_var_ref) :
|
||||||
int idx;
|
CASE (OP_set_var_ref) :
|
||||||
JSValue val;
|
CASE (OP_get_var_ref_check) :
|
||||||
idx = get_u16 (pc);
|
CASE (OP_put_var_ref_check) :
|
||||||
pc += 2;
|
CASE (OP_put_var_ref_check_init) :
|
||||||
val = *var_refs[idx]->pvalue;
|
pc += 2; /* skip the index */
|
||||||
sp[0] = val;
|
JS_ThrowInternalError(ctx, "deprecated var_ref opcode (use OP_get_up/OP_set_up)");
|
||||||
sp++;
|
goto exception;
|
||||||
}
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_put_var_ref) : {
|
|
||||||
int idx;
|
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
|
||||||
set_value (ctx, var_refs[idx]->pvalue, sp[-1]);
|
|
||||||
sp--;
|
|
||||||
}
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_set_var_ref) : {
|
|
||||||
int idx;
|
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
|
||||||
set_value (ctx, var_refs[idx]->pvalue, sp[-1]);
|
|
||||||
}
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_get_var_ref_check) : {
|
|
||||||
int idx;
|
|
||||||
JSValue val;
|
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
|
||||||
val = *var_refs[idx]->pvalue;
|
|
||||||
if (unlikely (JS_IsUninitialized (val))) {
|
|
||||||
JS_ThrowReferenceErrorUninitialized2 (ctx, b, idx, TRUE);
|
|
||||||
goto exception;
|
|
||||||
}
|
|
||||||
sp[0] = val;
|
|
||||||
sp++;
|
|
||||||
}
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_put_var_ref_check) : {
|
|
||||||
int idx;
|
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
|
||||||
if (unlikely (JS_IsUninitialized (*var_refs[idx]->pvalue))) {
|
|
||||||
JS_ThrowReferenceErrorUninitialized2 (ctx, b, idx, TRUE);
|
|
||||||
goto exception;
|
|
||||||
}
|
|
||||||
set_value (ctx, var_refs[idx]->pvalue, sp[-1]);
|
|
||||||
sp--;
|
|
||||||
}
|
|
||||||
BREAK;
|
|
||||||
CASE (OP_put_var_ref_check_init) : {
|
|
||||||
int idx;
|
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
|
||||||
if (unlikely (!JS_IsUninitialized (*var_refs[idx]->pvalue))) {
|
|
||||||
JS_ThrowReferenceErrorUninitialized2 (ctx, b, idx, TRUE);
|
|
||||||
goto exception;
|
|
||||||
}
|
|
||||||
set_value (ctx, var_refs[idx]->pvalue, sp[-1]);
|
|
||||||
sp--;
|
|
||||||
}
|
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_set_loc_uninitialized) : {
|
CASE (OP_set_loc_uninitialized) : {
|
||||||
int idx;
|
int idx;
|
||||||
@@ -7894,49 +7730,23 @@ restart:
|
|||||||
sp--;
|
sp--;
|
||||||
}
|
}
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_close_loc) : {
|
/* Legacy var_ref reference creation - deprecated, replaced by OP_get_up/OP_set_up */
|
||||||
int idx;
|
CASE (OP_close_loc) :
|
||||||
idx = get_u16 (pc);
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
close_lexical_var (ctx, sf, idx);
|
JS_ThrowInternalError(ctx, "deprecated close_loc opcode");
|
||||||
}
|
goto exception;
|
||||||
BREAK;
|
BREAK;
|
||||||
|
CASE (OP_make_loc_ref) :
|
||||||
CASE (OP_make_loc_ref)
|
CASE (OP_make_arg_ref) :
|
||||||
: CASE (OP_make_arg_ref) : CASE (OP_make_var_ref_ref) : {
|
CASE (OP_make_var_ref_ref) :
|
||||||
JSVarRef *var_ref;
|
|
||||||
JSValue key;
|
|
||||||
int idx;
|
|
||||||
key = b->cpool[get_u32 (pc)];
|
|
||||||
idx = get_u16 (pc + 4);
|
|
||||||
pc += 6;
|
pc += 6;
|
||||||
|
JS_ThrowInternalError(ctx, "deprecated make_*_ref opcode");
|
||||||
/* Create var ref object with dedicated class */
|
goto exception;
|
||||||
*sp++ = JS_NewObjectClass (ctx, JS_CLASS_VAR_REF_OBJECT);
|
|
||||||
if (unlikely (JS_IsException (sp[-1]))) goto exception;
|
|
||||||
|
|
||||||
if (opcode == OP_make_var_ref_ref) {
|
|
||||||
var_ref = var_refs[idx];
|
|
||||||
/* No ref_count increment needed with copying GC */
|
|
||||||
} else {
|
|
||||||
var_ref = get_var_ref (ctx, sf, idx, opcode == OP_make_arg_ref);
|
|
||||||
if (!var_ref) goto exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store var_ref as opaque data */
|
|
||||||
JS_SetOpaque (sp[-1], var_ref);
|
|
||||||
*sp++ = key;
|
|
||||||
}
|
|
||||||
BREAK;
|
BREAK;
|
||||||
CASE (OP_make_var_ref) : {
|
CASE (OP_make_var_ref) :
|
||||||
JSValue key;
|
|
||||||
key = b->cpool[get_u32 (pc)];
|
|
||||||
pc += 4;
|
pc += 4;
|
||||||
sf->cur_pc = pc;
|
JS_ThrowInternalError(ctx, "deprecated make_var_ref opcode");
|
||||||
|
goto exception;
|
||||||
if (JS_GetGlobalVarRef (ctx, key, sp)) goto exception;
|
|
||||||
sp += 2;
|
|
||||||
}
|
|
||||||
BREAK;
|
BREAK;
|
||||||
|
|
||||||
CASE (OP_goto) : pc += (int32_t)get_u32 (pc);
|
CASE (OP_goto) : pc += (int32_t)get_u32 (pc);
|
||||||
@@ -9094,10 +8904,6 @@ exception:
|
|||||||
}
|
}
|
||||||
ret_val = JS_EXCEPTION;
|
ret_val = JS_EXCEPTION;
|
||||||
done:
|
done:
|
||||||
if (unlikely (!list_empty (&sf->var_ref_list))) {
|
|
||||||
/* variable references reference the stack: must close them */
|
|
||||||
close_var_refs (rt, sf);
|
|
||||||
}
|
|
||||||
/* free the local variables and stack */
|
/* free the local variables and stack */
|
||||||
for (pval = local_buf; pval < sp; pval++) {
|
for (pval = local_buf; pval < sp; pval++) {
|
||||||
}
|
}
|
||||||
@@ -18302,7 +18108,7 @@ static JSValue JS_EvalFunctionInternal (JSContext *ctx, JSValue fun_obj, JSValue
|
|||||||
tag = JS_VALUE_GET_TAG (fun_obj);
|
tag = JS_VALUE_GET_TAG (fun_obj);
|
||||||
/* JSFunctionBytecode uses OBJ_CODE type with JS_TAG_PTR */
|
/* JSFunctionBytecode uses OBJ_CODE type with JS_TAG_PTR */
|
||||||
if (tag == JS_TAG_PTR && objhdr_type (*(objhdr_t *)JS_VALUE_GET_PTR (fun_obj)) == OBJ_CODE) {
|
if (tag == JS_TAG_PTR && objhdr_type (*(objhdr_t *)JS_VALUE_GET_PTR (fun_obj)) == OBJ_CODE) {
|
||||||
fun_obj = js_closure (ctx, fun_obj, var_refs, sf);
|
fun_obj = js_closure (ctx, fun_obj, sf);
|
||||||
ret_val = JS_Call (ctx, fun_obj, this_obj, 0, NULL);
|
ret_val = JS_Call (ctx, fun_obj, this_obj, 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
ret_val = JS_ThrowTypeError (ctx, "bytecode function expected");
|
ret_val = JS_ThrowTypeError (ctx, "bytecode function expected");
|
||||||
|
|||||||
Reference in New Issue
Block a user