rm constructor

This commit is contained in:
2026-01-21 13:38:38 -06:00
parent bfdd920178
commit 4da63db16e
3 changed files with 183 additions and 324 deletions

View File

@@ -35,7 +35,7 @@ function replace_sigils(str) {
function replace_sigils_array(flags) {
var result = []
arrfor(flags, function(flag) {
resultpush(replace_sigils(flag))
push(result, replace_sigils(flag))
})
return result
}
@@ -121,30 +121,30 @@ Build.compile_file = function(pkg, file, target, buildtype = 'release') {
// Add buildtype-specific flags
if (buildtype == 'release') {
cmd_partspush('-O3', '-DNDEBUG')
push(cmd_parts, '-O3', '-DNDEBUG')
} else if (buildtype == 'debug') {
cmd_partspush('-O2', '-g')
push(cmd_parts, '-O2', '-g')
} else if (buildtype == 'minsize') {
cmd_partspush('-Os', '-DNDEBUG')
push(cmd_parts, '-Os', '-DNDEBUG')
}
cmd_partspush('-DCELL_USE_NAME=' + sym_name)
cmd_partspush('-I"' + pkg_dir + '"')
push(cmd_parts, '-DCELL_USE_NAME=' + sym_name)
push(cmd_parts, '-I"' + pkg_dir + '"')
// Add package CFLAGS (resolve relative -I paths)
arrfor(cflags, function(flag) {
if (starts_with(flag, '-I') && !starts_with(flag, '-I/')) {
flag = '-I"' + pkg_dir + '/' + text(flag, 2) + '"'
}
cmd_partspush(flag)
push(cmd_parts, flag)
})
// Add target CFLAGS
arrfor(target_cflags, function(flag) {
cmd_partspush(flag)
push(cmd_parts, flag)
})
cmd_partspush('"' + src_path + '"')
push(cmd_parts, '"' + src_path + '"')
var cmd_str = text(cmd_parts, ' ')
@@ -181,7 +181,7 @@ Build.build_package = function(pkg, target = Build.detect_host_target(), exclude
arrfor(c_files, function(file) {
var obj = Build.compile_file(pkg, file, target, buildtype)
objectspush(obj)
push(objects, obj)
})
return objects
@@ -198,17 +198,17 @@ function compute_link_key(objects, ldflags, target_ldflags, target, cc) {
// Build a string representing all link inputs
var parts = []
partspush('target:' + target)
partspush('cc:' + cc)
push(parts, 'target:' + target)
push(parts, 'cc:' + cc)
arrfor(sorted_objects, function(obj) {
// Object paths are content-addressed, so the path itself is the hash
partspush('obj:' + obj)
push(parts, 'obj:' + obj)
})
arrfor(ldflags, function(flag) {
partspush('ldflag:' + flag)
push(parts, 'ldflag:' + flag)
})
arrfor(target_ldflags, function(flag) {
partspush('target_ldflag:' + flag)
push(parts, 'target_ldflag:' + flag)
})
return content_hash(text(parts, '\n'))
@@ -249,7 +249,7 @@ Build.build_dynamic = function(pkg, target = Build.detect_host_target(), buildty
if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"'
}
resolved_ldflagspush(flag)
push(resolved_ldflags, flag)
})
// Compute link key
@@ -279,46 +279,46 @@ Build.build_dynamic = function(pkg, target = Build.detect_host_target(), buildty
// Platform-specific flags for undefined symbols (resolved at dlopen) and size optimization
if (tc.system == 'darwin') {
// Allow undefined symbols - they will be resolved when dlopen'd into the main executable
cmd_partspush('-undefined', 'dynamic_lookup')
push(cmd_parts, '-undefined', 'dynamic_lookup')
// Dead-strip unused code
cmd_partspush('-Wl,-dead_strip')
push(cmd_parts, '-Wl,-dead_strip')
// Set install_name to stable path so runtime finds it correctly
cmd_partspush('-Wl,-install_name,' + stable_path)
push(cmd_parts, '-Wl,-install_name,' + stable_path)
// rpath for .cell/local libraries
cmd_partspush('-Wl,-rpath,@loader_path/../local')
cmd_partspush('-Wl,-rpath,' + local_dir)
push(cmd_parts, '-Wl,-rpath,@loader_path/../local')
push(cmd_parts, '-Wl,-rpath,' + local_dir)
} else if (tc.system == 'linux') {
// Allow undefined symbols at link time
cmd_partspush('-Wl,--allow-shlib-undefined')
push(cmd_parts, '-Wl,--allow-shlib-undefined')
// Garbage collect unused sections
cmd_partspush('-Wl,--gc-sections')
push(cmd_parts, '-Wl,--gc-sections')
// rpath for .cell/local libraries
cmd_partspush('-Wl,-rpath,$ORIGIN/../local')
cmd_partspush('-Wl,-rpath,' + local_dir)
push(cmd_parts, '-Wl,-rpath,$ORIGIN/../local')
push(cmd_parts, '-Wl,-rpath,' + local_dir)
} else if (tc.system == 'windows') {
// Windows DLLs: use --allow-shlib-undefined for mingw
cmd_partspush('-Wl,--allow-shlib-undefined')
push(cmd_parts, '-Wl,--allow-shlib-undefined')
}
// Add .cell/local to library search path
cmd_partspush('-L"' + local_dir + '"')
push(cmd_parts, '-L"' + local_dir + '"')
arrfor(objects, function(obj) {
cmd_partspush('"' + obj + '"')
push(cmd_parts, '"' + obj + '"')
})
// Do NOT link against core library - symbols resolved at dlopen time
// Add LDFLAGS
arrfor(resolved_ldflags, function(flag) {
cmd_partspush(flag)
push(cmd_parts, flag)
})
arrfor(target_ldflags, function(flag) {
cmd_partspush(flag)
push(cmd_parts, flag)
})
cmd_partspush('-o', '"' + store_path + '"')
push(cmd_parts, '-o', '"' + store_path + '"')
var cmd_str = text(cmd_parts, ' ')
@@ -359,7 +359,7 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
var objects = Build.build_package(pkg, target, !is_core, buildtype)
arrfor(objects, function(obj) {
all_objectspush(obj)
push(all_objects, obj)
})
// Collect LDFLAGS (with sigil replacement)
@@ -375,7 +375,7 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"'
}
all_ldflagspush(flag)
push(all_ldflags, flag)
})
}
})
@@ -396,18 +396,18 @@ Build.build_static = function(packages, target = Build.detect_host_target(), out
var cmd_parts = [cc]
arrfor(all_objects, function(obj) {
cmd_partspush('"' + obj + '"')
push(cmd_parts, '"' + obj + '"')
})
arrfor(all_ldflags, function(flag) {
cmd_partspush(flag)
push(cmd_parts, flag)
})
arrfor(target_ldflags, function(flag) {
cmd_partspush(flag)
push(cmd_parts, flag)
})
cmd_partspush('-o', '"' + output + '"')
push(cmd_parts, '-o', '"' + output + '"')
var cmd_str = text(cmd_parts, ' ')
@@ -436,10 +436,10 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
if (find(packages, 'core') != null) {
try {
var lib = Build.build_dynamic('core', target, buildtype)
resultspush({ package: 'core', library: lib })
push(results, { package: 'core', library: lib })
} catch (e) {
log.error('Failed to build core: ' + text(e))
resultspush({ package: 'core', error: e })
push(results, { package: 'core', error: e })
}
}
@@ -449,11 +449,12 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
try {
var lib = Build.build_dynamic(pkg, target, buildtype)
resultspush({ package: pkg, library: lib })
push(results, { package: pkg, library: lib })
} catch (e) {
log.error('Failed to build ' + pkg + ': ')
log.error(e)
resultspush({ package: pkg, error: e })
log.error(e.message)
log.error(e.stack)
push(results, { package: pkg, error: e })
}
})

View File

@@ -338,7 +338,6 @@ struct VMFrame {
JSValue cur_func; /* current function object */
JSValue this_obj; /* this binding */
JSValue new_target; /* new.target binding */
struct JSVarRef **var_refs; /* closure variable references */
struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */
int arg_count;
@@ -358,7 +357,6 @@ typedef enum {
typedef struct {
JSValue func_obj;
JSValue this_obj;
JSValue new_target;
int argc;
JSValue *argv;
const uint8_t *ret_pc;
@@ -408,7 +406,6 @@ typedef struct JSVarRef {
} JSVarRef;
typedef enum {
JS_AUTOINIT_ID_PROTOTYPE,
JS_AUTOINIT_ID_PROP,
} JSAutoInitIDEnum;
@@ -428,7 +425,6 @@ struct JSContext {
JSValue *class_proto;
JSValue function_proto;
JSValue function_ctor;
JSValue array_ctor;
JSValue regexp_ctor;
JSValue native_error_proto[JS_NATIVE_ERROR_COUNT];
@@ -907,10 +903,7 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_obj,
int argc, JSValueConst *argv, int flags);
static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
int argc, JSValue *argv, int flags);
static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
JSValueConst this_obj,
int argc, JSValue *argv, int flags);
static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv);
@@ -958,7 +951,7 @@ static int JS_ToFloat64Free(JSContext *ctx, double *pres, JSValue val);
static JSValue js_new_string8_len(JSContext *ctx, const char *buf, int len);
static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
JSValueConst flags);
static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor,
static JSValue js_regexp_constructor_internal(JSContext *ctx,
JSValue pattern, JSValue bc);
static void gc_decref(JSRuntime *rt);
static int JS_NewClass1(JSRuntime *rt, JSClassID class_id,
@@ -1029,7 +1022,6 @@ static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val);
static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h,
JSGCObjectTypeEnum type);
static void remove_gc_object(JSGCObjectHeader *h);
static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque);
static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p,
JSAtom atom, void *opaque);
static void JS_RunGCInternal(JSRuntime *rt);
@@ -1945,7 +1937,6 @@ static void JS_MarkContext(JSRuntime *rt, JSContext *ctx,
}
JS_MarkValue(rt, ctx->array_ctor, mark_func);
JS_MarkValue(rt, ctx->regexp_ctor, mark_func);
JS_MarkValue(rt, ctx->function_ctor, mark_func);
if (ctx->array_shape)
mark_func(rt, &ctx->array_shape->header);
@@ -2003,7 +1994,6 @@ void JS_FreeContext(JSContext *ctx)
js_free_rt(rt, ctx->class_proto);
JS_FreeValue(ctx, ctx->array_ctor);
JS_FreeValue(ctx, ctx->regexp_ctor);
JS_FreeValue(ctx, ctx->function_ctor);
js_free_shape_null(ctx->rt, ctx->array_shape);
@@ -4905,6 +4895,18 @@ static BOOL js_class_has_bytecode(JSClassID class_id)
return class_id == JS_CLASS_BYTECODE_FUNCTION;
}
/* Check if a value is a function that uses proxy-call syntax (fn.a -> fn("a")) */
static BOOL js_is_proxy_callable(JSValueConst v)
{
JSObject *p;
if (JS_VALUE_GET_TAG(v) != JS_TAG_OBJECT)
return FALSE;
p = JS_VALUE_GET_OBJ(v);
return p->class_id == JS_CLASS_BYTECODE_FUNCTION ||
p->class_id == JS_CLASS_C_FUNCTION ||
p->class_id == JS_CLASS_C_FUNCTION_DATA;
}
/* return NULL without exception if not a function or no bytecode */
static JSFunctionBytecode *JS_GetFunctionBytecode(JSValueConst val)
{
@@ -6739,7 +6741,6 @@ static JSValue JS_GetPrototypeFree(JSContext *ctx, JSValue obj)
typedef JSValue JSAutoInitFunc(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque);
static JSAutoInitFunc *js_autoinit_func_table[] = {
js_instantiate_prototype, /* JS_AUTOINIT_ID_PROTOTYPE */
JS_InstantiateFunctionListItem2, /* JS_AUTOINIT_ID_PROP */
};
@@ -11369,27 +11370,6 @@ static JSValue js_closure2(JSContext *ctx, JSValue func_obj,
return JS_EXCEPTION;
}
static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque)
{
JSValue obj, this_val;
int ret;
this_val = JS_MKPTR(JS_TAG_OBJECT, p);
obj = JS_NewObject(ctx);
if (JS_IsException(obj))
return JS_EXCEPTION;
set_cycle_flag(ctx, obj);
set_cycle_flag(ctx, this_val);
ret = JS_DefinePropertyValue(ctx, obj, JS_ATOM_constructor,
JS_DupValue(ctx, this_val),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
if (ret < 0) {
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}
return obj;
}
static JSValue js_closure(JSContext *ctx, JSValue bfunc,
JSVarRef **cur_var_refs,
JSStackFrame *sf)
@@ -11510,19 +11490,9 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
}
switch(cproto) {
case JS_CFUNC_constructor:
case JS_CFUNC_constructor_or_func:
/* Constructors are called as regular functions with JS_NULL this */
this_obj = JS_NULL;
/* fall thru */
case JS_CFUNC_generic:
ret_val = func.generic(ctx, this_obj, argc, arg_buf);
break;
case JS_CFUNC_constructor_magic:
case JS_CFUNC_constructor_or_func_magic:
/* Constructors are called as regular functions with JS_NULL this */
this_obj = JS_NULL;
/* fall thru */
case JS_CFUNC_generic_magic:
ret_val = func.generic_magic(ctx, this_obj, argc, arg_buf,
p->u.cfunc.magic);
@@ -11587,7 +11557,7 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj,
{
JSObject *p;
JSBoundFunction *bf;
JSValueConst *arg_buf, new_target;
JSValueConst *arg_buf;
int arg_count, i;
p = JS_VALUE_GET_OBJ(func_obj);
@@ -11690,7 +11660,6 @@ static void profile_record_prop_site(JSRuntime *rt, JSFunctionBytecode *b, uint3
/* VM frame management for trampoline - no malloc/free! */
static struct VMFrame *vm_push_frame(JSContext *ctx,
JSValueConst func_obj, JSValueConst this_obj,
JSValueConst new_target,
int argc, JSValue *argv, int flags,
const uint8_t *ret_pc, int ret_sp_offset,
int call_argc, int call_has_this)
@@ -11758,7 +11727,6 @@ static struct VMFrame *vm_push_frame(JSContext *ctx,
/* Initialize frame metadata */
frame->cur_func = JS_DupValue(ctx, func_obj);
frame->this_obj = JS_DupValue(ctx, this_obj);
frame->new_target = JS_DupValue(ctx, new_target);
frame->b = b;
frame->ctx = b->realm;
frame->pc = b->byte_code_buf;
@@ -11809,7 +11777,6 @@ static void vm_pop_frame(JSContext *ctx)
/* Free frame values */
JS_FreeValue(ctx, frame->cur_func);
JS_FreeValue(ctx, frame->this_obj);
JS_FreeValue(ctx, frame->new_target);
/* Pop frame and value stack */
ctx->value_stack_top -= frame->stack_size_allocated;
@@ -11844,7 +11811,7 @@ static inline JSValue *vm_frame_get_arg_buf(JSContext *ctx, struct VMFrame *fram
/* Trampoline VM dispatcher - runs frames without C recursion */
static JSValue JS_CallTrampoline(JSContext *caller_ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
JSValueConst this_obj,
int argc, JSValue *argv, int flags)
{
JSRuntime *rt = caller_ctx->rt;
@@ -11869,7 +11836,7 @@ static JSValue JS_CallTrampoline(JSContext *caller_ctx, JSValueConst func_obj,
}
/* Push initial frame (entry point, no continuation) */
frame = vm_push_frame(caller_ctx, func_obj, this_obj, new_target,
frame = vm_push_frame(caller_ctx, func_obj, this_obj,
argc, argv, flags,
NULL, 0, 0, 0);
if (!frame)
@@ -11896,7 +11863,7 @@ static VMExecState vm_execute_frame(JSContext *ctx, struct VMFrame *frame,
/* 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->new_target, frame->arg_count,
frame->arg_count,
vm_frame_get_arg_buf(ctx, frame), 0);
if (JS_IsException(*ret_val))
return VM_EXEC_EXCEPTION;
@@ -11904,7 +11871,7 @@ static VMExecState vm_execute_frame(JSContext *ctx, struct VMFrame *frame,
}
static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
JSValueConst this_obj,
int argc, JSValue *argv, int flags)
{
JSRuntime *rt = caller_ctx->rt;
@@ -12076,13 +12043,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{
JSValue val;
/* User-defined functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-1]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
/* Functions don't support property access in cell script */
if (js_is_proxy_callable(sp[-1])) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
sf->cur_pc = pc;
@@ -12127,7 +12091,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
*sp++ = JS_DupValue(ctx, sf->cur_func);
break;
case OP_SPECIAL_OBJECT_NEW_TARGET:
*sp++ = JS_DupValue(ctx, new_target);
/* new.target is always null (constructors not supported) */
*sp++ = JS_NULL;
break;
case OP_SPECIAL_OBJECT_VAR_OBJECT:
*sp++ = JS_NewObjectProto(ctx, JS_NULL);
@@ -12323,7 +12288,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
#endif
/* TODO: Use trampoline - for now keep recursive */
ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL,
JS_NULL, call_argc, call_argv, 0);
call_argc, call_argv, 0);
if (unlikely(JS_IsException(ret_val)))
goto exception;
if (opcode == OP_tail_call)
@@ -12347,16 +12312,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
/* Record call site */
profile_record_call_site(rt, b, (uint32_t)(pc - b->byte_code_buf));
#endif
/* Proxy method-call: detect [bytecode_func, "name", ...args]
/* Proxy method-call: detect [func, "name", ...args]
and rewrite as func("name", [args]) */
if (JS_VALUE_GET_TAG(call_argv[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(call_argv[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
if (!JS_IsFunction(ctx, call_argv[-1])) {
int t = JS_VALUE_GET_TAG(call_argv[-1]);
if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
is_proxy = TRUE;
}
if (js_is_proxy_callable(call_argv[-2])) {
if (!JS_IsFunction(ctx, call_argv[-1])) {
int t = JS_VALUE_GET_TAG(call_argv[-1]);
if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
is_proxy = TRUE;
}
}
@@ -12383,12 +12345,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
proxy_argv[1] = args;
ret_val = JS_CallInternal(ctx, call_argv[-2], JS_NULL,
JS_NULL, 2, proxy_argv, 0);
2, proxy_argv, 0);
JS_FreeValue(ctx, args);
}
} else {
ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2],
JS_NULL, call_argc, call_argv, 0);
call_argc, call_argv, 0);
}
if (unlikely(JS_IsException(ret_val)))
goto exception;
@@ -12433,16 +12395,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
pc += 2;
sf->cur_pc = pc;
/* Proxy method-call with spread: detect ["name", bytecode_func, args_array]
/* Proxy method-call with spread: detect ["name", func, args_array]
and rewrite as func("name", args_array) */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
if (!JS_IsFunction(ctx, sp[-3])) {
int t = JS_VALUE_GET_TAG(sp[-3]);
if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
is_proxy = TRUE;
}
if (js_is_proxy_callable(sp[-2])) {
if (!JS_IsFunction(ctx, sp[-3])) {
int t = JS_VALUE_GET_TAG(sp[-3]);
if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
is_proxy = TRUE;
}
}
@@ -12452,7 +12411,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
proxy_argv[1] = sp[-1]; /* args array already built by bytecode */
ret_val = JS_CallInternal(ctx, sp[-2], JS_NULL,
JS_NULL, 2, proxy_argv, 0);
2, proxy_argv, 0);
} else {
ret_val = js_function_apply(ctx, sp[-3], 2, (JSValueConst *)&sp[-2], magic);
}
@@ -12521,7 +12480,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JS_EVAL_TYPE_DIRECT, scope_idx);
} else {
ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL,
JS_NULL, call_argc, call_argv, 0);
call_argc, call_argv, 0);
}
if (unlikely(JS_IsException(ret_val)))
goto exception;
@@ -12568,8 +12527,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_regexp):
{
sp[-2] = js_regexp_constructor_internal(ctx, JS_NULL,
sp[-2], sp[-1]);
sp[-2] = js_regexp_constructor_internal(ctx, sp[-2], sp[-1]);
sp--;
}
BREAK;
@@ -13147,13 +13105,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
#endif
obj = sp[-1];
/* User-defined functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(obj);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
/* Functions don't support property access in cell script */
if (js_is_proxy_callable(obj)) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
/* Monomorphic IC fast path: shape-guarded own-property lookup */
@@ -13238,15 +13193,12 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
/* Proxy method-call sugar: func.name(...) -> func("name", [args...])
OP_get_field2 is only emitted when a call immediately follows. */
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(obj);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
val = JS_AtomToValue(ctx, atom); /* "name" */
if (unlikely(JS_IsException(val)))
goto exception;
*sp++ = val; /* stack becomes [func, "name"] */
goto get_field2_done;
}
if (js_is_proxy_callable(obj)) {
val = JS_AtomToValue(ctx, atom); /* "name" */
if (unlikely(JS_IsException(val)))
goto exception;
*sp++ = val; /* stack becomes [func, "name"] */
goto get_field2_done;
}
/* Monomorphic IC fast path */
@@ -13315,13 +13267,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
/* Record property access site */
profile_record_prop_site(rt, b, (uint32_t)(pc - b->byte_code_buf), atom);
#endif
/* User-defined functions don't support property assignment in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
/* Functions don't support property assignment in cell script */
if (js_is_proxy_callable(sp[-2])) {
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], sp[-2],
@@ -13450,13 +13399,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{
JSValue val;
/* User-defined functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
/* Functions don't support property access in cell script */
if (js_is_proxy_callable(sp[-2])) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
sf->cur_pc = pc;
@@ -13474,34 +13420,31 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JSValue val;
/* Proxy method-call sugar for bracket calls: func[key](...) */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
/* Keep [func, key] and normalize key to property-key (string/symbol). */
switch (JS_VALUE_GET_TAG(sp[-1])) {
case JS_TAG_INT:
/* Convert integer to string */
sf->cur_pc = pc;
ret_val = JS_ToString(ctx, sp[-1]);
if (JS_IsException(ret_val))
goto exception;
JS_FreeValue(ctx, sp[-1]);
sp[-1] = ret_val;
break;
case JS_TAG_STRING:
case JS_TAG_SYMBOL:
break;
default:
sf->cur_pc = pc;
ret_val = JS_ToPropertyKey(ctx, sp[-1]);
if (JS_IsException(ret_val))
goto exception;
JS_FreeValue(ctx, sp[-1]);
sp[-1] = ret_val;
break;
}
BREAK; /* skip JS_GetPropertyValue, keep [func, key] on stack */
if (js_is_proxy_callable(sp[-2])) {
/* Keep [func, key] and normalize key to property-key (string/symbol). */
switch (JS_VALUE_GET_TAG(sp[-1])) {
case JS_TAG_INT:
/* Convert integer to string */
sf->cur_pc = pc;
ret_val = JS_ToString(ctx, sp[-1]);
if (JS_IsException(ret_val))
goto exception;
JS_FreeValue(ctx, sp[-1]);
sp[-1] = ret_val;
break;
case JS_TAG_STRING:
case JS_TAG_SYMBOL:
break;
default:
sf->cur_pc = pc;
ret_val = JS_ToPropertyKey(ctx, sp[-1]);
if (JS_IsException(ret_val))
goto exception;
JS_FreeValue(ctx, sp[-1]);
sp[-1] = ret_val;
break;
}
BREAK; /* skip JS_GetPropertyValue, keep [func, key] on stack */
}
sf->cur_pc = pc;
@@ -13516,13 +13459,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{
JSValue val;
/* User-defined functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
/* Functions don't support property access in cell script */
if (js_is_proxy_callable(sp[-2])) {
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
switch (JS_VALUE_GET_TAG(sp[-2])) {
@@ -13593,13 +13533,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{
int ret;
/* User-defined functions don't support property assignment in cell script */
if (JS_VALUE_GET_TAG(sp[-3]) == JS_TAG_OBJECT) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-3]);
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) {
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
/* Functions don't support property assignment in cell script */
if (js_is_proxy_callable(sp[-3])) {
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
sf->cur_pc = pc;
@@ -14395,14 +14332,14 @@ CASE(OP_template_concat):
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv)
{
return JS_CallInternal(ctx, func_obj, this_obj, JS_NULL,
return JS_CallInternal(ctx, func_obj, this_obj,
argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV);
}
static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv)
{
JSValue res = JS_CallInternal(ctx, func_obj, this_obj, JS_NULL,
JSValue res = JS_CallInternal(ctx, func_obj, this_obj,
argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV);
JS_FreeValue(ctx, func_obj);
return res;
@@ -26389,50 +26326,6 @@ int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
return 0;
}
/* Note: 'func_obj' is not necessarily a constructor */
static void JS_SetConstructor2(JSContext *ctx,
JSValueConst func_obj,
JSValueConst proto,
int proto_flags, int ctor_flags)
{
JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_prototype,
JS_DupValue(ctx, proto), proto_flags);
JS_DefinePropertyValue(ctx, proto, JS_ATOM_constructor,
JS_DupValue(ctx, func_obj),
ctor_flags);
set_cycle_flag(ctx, func_obj);
set_cycle_flag(ctx, proto);
}
void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
JSValueConst proto)
{
JS_SetConstructor2(ctx, func_obj, proto,
0, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
}
static void JS_NewGlobalCConstructor2(JSContext *ctx,
JSValue func_obj,
const char *name,
JSValueConst proto)
{
JS_DefinePropertyValueStr(ctx, ctx->global_obj, name,
JS_DupValue(ctx, func_obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
JS_SetConstructor(ctx, func_obj, proto);
JS_FreeValue(ctx, func_obj);
}
static JSValueConst JS_NewGlobalCConstructor(JSContext *ctx, const char *name,
JSCFunction *func, int length,
JSValueConst proto)
{
JSValue func_obj;
func_obj = JS_NewCFunction2(ctx, func, name, length, JS_CFUNC_constructor_or_func, 0);
JS_NewGlobalCConstructor2(ctx, func_obj, name, proto);
return func_obj;
}
/* Object class */
static JSValue JS_ToObject(JSContext *ctx, JSValueConst val)
@@ -26719,35 +26612,20 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
}
/* Error class */
static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target,
static JSValue js_error_constructor(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic)
{
JSValue obj, msg, proto;
JSValueConst message, options;
JSValue obj, msg;
JSValueConst message, options, proto;
int arg_index;
if (JS_IsNull(new_target))
new_target = JS_GetActiveFunction(ctx);
proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype);
if (JS_IsException(proto))
return proto;
if (!JS_IsObject(proto)) {
JSContext *realm;
JSValueConst proto1;
JS_FreeValue(ctx, proto);
realm = JS_GetFunctionRealm(ctx, new_target);
if (!realm)
return JS_EXCEPTION;
if (magic < 0) {
proto1 = realm->class_proto[JS_CLASS_ERROR];
} else {
proto1 = realm->native_error_proto[magic];
}
proto = JS_DupValue(ctx, proto1);
/* Use the appropriate error prototype based on magic */
if (magic < 0) {
proto = ctx->class_proto[JS_CLASS_ERROR];
} else {
proto = ctx->native_error_proto[magic];
}
obj = JS_NewObjectProtoClass(ctx, proto, JS_CLASS_ERROR);
JS_FreeValue(ctx, proto);
if (JS_IsException(obj))
return obj;
arg_index = (magic == JS_AGGREGATE_ERROR);
@@ -26916,13 +26794,13 @@ static int JS_CopySubArray(JSContext *ctx,
return -1;
}
static JSValue js_array_constructor(JSContext *ctx, JSValueConst new_target,
static JSValue js_array_constructor(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue obj;
int i;
obj = js_create_from_ctor(ctx, new_target, JS_CLASS_ARRAY);
obj = JS_NewArray(ctx);
if (JS_IsException(obj))
return obj;
if (argc == 1 && JS_IsNumber(argv[0])) {
@@ -27377,7 +27255,7 @@ static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
/* create a RegExp object from a string containing the RegExp bytecode
and the source pattern */
static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor,
static JSValue js_regexp_constructor_internal(JSContext *ctx,
JSValue pattern, JSValue bc)
{
JSValue obj;
@@ -27394,7 +27272,7 @@ static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor,
return JS_EXCEPTION;
}
obj = js_create_from_ctor(ctx, ctor, JS_CLASS_REGEXP);
obj = JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_REGEXP], JS_CLASS_REGEXP);
if (JS_IsException(obj))
goto fail;
p = JS_VALUE_GET_OBJ(obj);
@@ -27434,7 +27312,7 @@ static int js_is_regexp(JSContext *ctx, JSValueConst obj)
return js_get_regexp(ctx, obj, FALSE) != NULL;
}
static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue pattern, flags, bc, val;
@@ -27447,20 +27325,11 @@ static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
pat_is_regexp = js_is_regexp(ctx, pat);
if (pat_is_regexp < 0)
return JS_EXCEPTION;
if (JS_IsNull(new_target)) {
/* called as a function */
new_target = JS_GetActiveFunction(ctx);
if (pat_is_regexp && JS_IsNull(flags1)) {
JSValue ctor;
BOOL res;
ctor = JS_GetProperty(ctx, pat, JS_ATOM_constructor);
if (JS_IsException(ctor))
return ctor;
res = js_same_value(ctx, ctor, new_target);
JS_FreeValue(ctx, ctor);
if (res)
return JS_DupValue(ctx, pat);
}
/* If called with a regexp and no flags, just return a copy */
if (pat_is_regexp && JS_IsNull(flags1)) {
re = js_get_regexp(ctx, pat, FALSE);
if (re)
return JS_DupValue(ctx, pat);
}
re = js_get_regexp(ctx, pat, FALSE);
if (re) {
@@ -27505,7 +27374,7 @@ static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
goto fail;
JS_FreeValue(ctx, flags);
no_compilation:
return js_regexp_constructor_internal(ctx, new_target, pattern, bc);
return js_regexp_constructor_internal(ctx, pattern, bc);
fail:
JS_FreeValue(ctx, pattern);
JS_FreeValue(ctx, flags);
@@ -28099,9 +27968,12 @@ void JS_AddIntrinsicRegExp(JSContext *ctx)
ctx->class_proto[JS_CLASS_REGEXP] = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_REGEXP], js_regexp_proto_funcs,
countof(js_regexp_proto_funcs));
obj = JS_NewGlobalCConstructor(ctx, "RegExp", js_regexp_constructor, 2,
ctx->class_proto[JS_CLASS_REGEXP]);
ctx->regexp_ctor = JS_DupValue(ctx, obj);
obj = JS_NewCFunction2(ctx, js_regexp_constructor, "RegExp", 2,
JS_CFUNC_generic, 0);
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "RegExp",
JS_DupValue(ctx, obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
ctx->regexp_ctor = obj;
}
/* JSON */
@@ -31675,7 +31547,7 @@ static void js_blob_finalizer(JSRuntime *rt, JSValue val)
}
/* blob() constructor */
static JSValue js_blob_constructor(JSContext *ctx, JSValueConst new_target,
static JSValue js_blob_constructor(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
blob *bd = NULL;
@@ -32987,32 +32859,34 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
ctx->global_obj = JS_NewObject(ctx);
ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL);
/* Function - no constructor needed */
ctx->function_ctor = JS_NULL;
/* Error */
obj1 = JS_NewCFunctionMagic(ctx, js_error_constructor,
"Error", 1, JS_CFUNC_constructor_or_func_magic, -1);
JS_NewGlobalCConstructor2(ctx, obj1,
"Error", ctx->class_proto[JS_CLASS_ERROR]);
"Error", 1, JS_CFUNC_generic_magic, -1);
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "Error",
JS_DupValue(ctx, obj1),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, obj1);
/* Used to squelch a -Wcast-function-type warning. */
JSCFunctionType ft = { .generic_magic = js_error_constructor };
for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) {
JSValue func_obj;
int n_args;
n_args = 1 + (i == JS_AGGREGATE_ERROR);
func_obj = JS_NewCFunction3(ctx, ft.generic,
native_error_name[i], n_args,
JS_CFUNC_constructor_or_func_magic, i, obj1);
JS_NewGlobalCConstructor2(ctx, func_obj, native_error_name[i],
ctx->native_error_proto[i]);
func_obj = JS_NewCFunctionMagic(ctx, js_error_constructor,
native_error_name[i], n_args,
JS_CFUNC_generic_magic, i);
JS_DefinePropertyValueStr(ctx, ctx->global_obj, native_error_name[i],
JS_DupValue(ctx, func_obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, func_obj);
}
/* Array */
obj = JS_NewGlobalCConstructor(ctx, "Array", js_array_constructor, 1,
ctx->class_proto[JS_CLASS_ARRAY]);
ctx->array_ctor = JS_DupValue(ctx, obj);
obj = JS_NewCFunction2(ctx, js_array_constructor, "Array", 1,
JS_CFUNC_generic, 0);
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "Array",
JS_DupValue(ctx, obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
ctx->array_ctor = obj;
/* XXX: create auto_initializer */
{

View File

@@ -685,8 +685,6 @@ JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
JSValue JS_NewObject(JSContext *ctx);
JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
JSValue JS_NewArray(JSContext *ctx);
int JS_IsArray(JSContext *ctx, JSValueConst val);
@@ -751,11 +749,6 @@ JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv);
JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
int argc, JSValueConst *argv);
JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
int argc, JSValueConst *argv);
JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
JSValueConst new_target,
int argc, JSValueConst *argv);
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags);
@@ -822,13 +815,9 @@ JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
/* C function definition */
typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
typedef enum JSCFunctionEnum {
JS_CFUNC_generic,
JS_CFUNC_generic_magic,
JS_CFUNC_constructor,
JS_CFUNC_constructor_magic,
JS_CFUNC_constructor_or_func,
JS_CFUNC_constructor_or_func_magic,
JS_CFUNC_f_f,
JS_CFUNC_f_f_f,
JS_CFUNC_getter,
@@ -841,9 +830,6 @@ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
typedef union JSCFunctionType {
JSCFunction *generic;
JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor;
JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor_or_func;
double (*f_f)(double);
double (*f_f_f)(double, double);
JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
@@ -873,8 +859,6 @@ static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *fun
{
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic);
}
void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
JSValueConst proto);
/* C property definition */