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) { function replace_sigils_array(flags) {
var result = [] var result = []
arrfor(flags, function(flag) { arrfor(flags, function(flag) {
resultpush(replace_sigils(flag)) push(result, replace_sigils(flag))
}) })
return result return result
} }
@@ -121,30 +121,30 @@ Build.compile_file = function(pkg, file, target, buildtype = 'release') {
// Add buildtype-specific flags // Add buildtype-specific flags
if (buildtype == 'release') { if (buildtype == 'release') {
cmd_partspush('-O3', '-DNDEBUG') push(cmd_parts, '-O3', '-DNDEBUG')
} else if (buildtype == 'debug') { } else if (buildtype == 'debug') {
cmd_partspush('-O2', '-g') push(cmd_parts, '-O2', '-g')
} else if (buildtype == 'minsize') { } else if (buildtype == 'minsize') {
cmd_partspush('-Os', '-DNDEBUG') push(cmd_parts, '-Os', '-DNDEBUG')
} }
cmd_partspush('-DCELL_USE_NAME=' + sym_name) push(cmd_parts, '-DCELL_USE_NAME=' + sym_name)
cmd_partspush('-I"' + pkg_dir + '"') push(cmd_parts, '-I"' + pkg_dir + '"')
// Add package CFLAGS (resolve relative -I paths) // Add package CFLAGS (resolve relative -I paths)
arrfor(cflags, function(flag) { arrfor(cflags, function(flag) {
if (starts_with(flag, '-I') && !starts_with(flag, '-I/')) { if (starts_with(flag, '-I') && !starts_with(flag, '-I/')) {
flag = '-I"' + pkg_dir + '/' + text(flag, 2) + '"' flag = '-I"' + pkg_dir + '/' + text(flag, 2) + '"'
} }
cmd_partspush(flag) push(cmd_parts, flag)
}) })
// Add target CFLAGS // Add target CFLAGS
arrfor(target_cflags, function(flag) { 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, ' ') 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) { arrfor(c_files, function(file) {
var obj = Build.compile_file(pkg, file, target, buildtype) var obj = Build.compile_file(pkg, file, target, buildtype)
objectspush(obj) push(objects, obj)
}) })
return objects return objects
@@ -198,17 +198,17 @@ function compute_link_key(objects, ldflags, target_ldflags, target, cc) {
// Build a string representing all link inputs // Build a string representing all link inputs
var parts = [] var parts = []
partspush('target:' + target) push(parts, 'target:' + target)
partspush('cc:' + cc) push(parts, 'cc:' + cc)
arrfor(sorted_objects, function(obj) { arrfor(sorted_objects, function(obj) {
// Object paths are content-addressed, so the path itself is the hash // Object paths are content-addressed, so the path itself is the hash
partspush('obj:' + obj) push(parts, 'obj:' + obj)
}) })
arrfor(ldflags, function(flag) { arrfor(ldflags, function(flag) {
partspush('ldflag:' + flag) push(parts, 'ldflag:' + flag)
}) })
arrfor(target_ldflags, function(flag) { arrfor(target_ldflags, function(flag) {
partspush('target_ldflag:' + flag) push(parts, 'target_ldflag:' + flag)
}) })
return content_hash(text(parts, '\n')) 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/')) { if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"' flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"'
} }
resolved_ldflagspush(flag) push(resolved_ldflags, flag)
}) })
// Compute link key // 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 // Platform-specific flags for undefined symbols (resolved at dlopen) and size optimization
if (tc.system == 'darwin') { if (tc.system == 'darwin') {
// Allow undefined symbols - they will be resolved when dlopen'd into the main executable // 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 // 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 // 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 // rpath for .cell/local libraries
cmd_partspush('-Wl,-rpath,@loader_path/../local') push(cmd_parts, '-Wl,-rpath,@loader_path/../local')
cmd_partspush('-Wl,-rpath,' + local_dir) push(cmd_parts, '-Wl,-rpath,' + local_dir)
} else if (tc.system == 'linux') { } else if (tc.system == 'linux') {
// Allow undefined symbols at link time // Allow undefined symbols at link time
cmd_partspush('-Wl,--allow-shlib-undefined') push(cmd_parts, '-Wl,--allow-shlib-undefined')
// Garbage collect unused sections // Garbage collect unused sections
cmd_partspush('-Wl,--gc-sections') push(cmd_parts, '-Wl,--gc-sections')
// rpath for .cell/local libraries // rpath for .cell/local libraries
cmd_partspush('-Wl,-rpath,$ORIGIN/../local') push(cmd_parts, '-Wl,-rpath,$ORIGIN/../local')
cmd_partspush('-Wl,-rpath,' + local_dir) push(cmd_parts, '-Wl,-rpath,' + local_dir)
} else if (tc.system == 'windows') { } else if (tc.system == 'windows') {
// Windows DLLs: use --allow-shlib-undefined for mingw // 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 // Add .cell/local to library search path
cmd_partspush('-L"' + local_dir + '"') push(cmd_parts, '-L"' + local_dir + '"')
arrfor(objects, function(obj) { arrfor(objects, function(obj) {
cmd_partspush('"' + obj + '"') push(cmd_parts, '"' + obj + '"')
}) })
// Do NOT link against core library - symbols resolved at dlopen time // Do NOT link against core library - symbols resolved at dlopen time
// Add LDFLAGS // Add LDFLAGS
arrfor(resolved_ldflags, function(flag) { arrfor(resolved_ldflags, function(flag) {
cmd_partspush(flag) push(cmd_parts, flag)
}) })
arrfor(target_ldflags, function(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, ' ') 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) var objects = Build.build_package(pkg, target, !is_core, buildtype)
arrfor(objects, function(obj) { arrfor(objects, function(obj) {
all_objectspush(obj) push(all_objects, obj)
}) })
// Collect LDFLAGS (with sigil replacement) // 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/')) { if (starts_with(flag, '-L') && !starts_with(flag, '-L/')) {
flag = '-L"' + pkg_dir + '/' + text(flag, 2) + '"' 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] var cmd_parts = [cc]
arrfor(all_objects, function(obj) { arrfor(all_objects, function(obj) {
cmd_partspush('"' + obj + '"') push(cmd_parts, '"' + obj + '"')
}) })
arrfor(all_ldflags, function(flag) { arrfor(all_ldflags, function(flag) {
cmd_partspush(flag) push(cmd_parts, flag)
}) })
arrfor(target_ldflags, function(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, ' ') var cmd_str = text(cmd_parts, ' ')
@@ -436,10 +436,10 @@ Build.build_all_dynamic = function(target, buildtype = 'release') {
if (find(packages, 'core') != null) { if (find(packages, 'core') != null) {
try { try {
var lib = Build.build_dynamic('core', target, buildtype) var lib = Build.build_dynamic('core', target, buildtype)
resultspush({ package: 'core', library: lib }) push(results, { package: 'core', library: lib })
} catch (e) { } catch (e) {
log.error('Failed to build core: ' + text(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 { try {
var lib = Build.build_dynamic(pkg, target, buildtype) var lib = Build.build_dynamic(pkg, target, buildtype)
resultspush({ package: pkg, library: lib }) push(results, { package: pkg, library: lib })
} catch (e) { } catch (e) {
log.error('Failed to build ' + pkg + ': ') log.error('Failed to build ' + pkg + ': ')
log.error(e) log.error(e.message)
resultspush({ package: pkg, error: e }) 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 cur_func; /* current function object */
JSValue this_obj; /* this binding */ JSValue this_obj; /* this binding */
JSValue new_target; /* new.target binding */
struct JSVarRef **var_refs; /* closure variable references */ struct JSVarRef **var_refs; /* closure variable references */
struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */ struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */
int arg_count; int arg_count;
@@ -358,7 +357,6 @@ typedef enum {
typedef struct { typedef struct {
JSValue func_obj; JSValue func_obj;
JSValue this_obj; JSValue this_obj;
JSValue new_target;
int argc; int argc;
JSValue *argv; JSValue *argv;
const uint8_t *ret_pc; const uint8_t *ret_pc;
@@ -408,7 +406,6 @@ typedef struct JSVarRef {
} JSVarRef; } JSVarRef;
typedef enum { typedef enum {
JS_AUTOINIT_ID_PROTOTYPE,
JS_AUTOINIT_ID_PROP, JS_AUTOINIT_ID_PROP,
} JSAutoInitIDEnum; } JSAutoInitIDEnum;
@@ -428,7 +425,6 @@ struct JSContext {
JSValue *class_proto; JSValue *class_proto;
JSValue function_proto; JSValue function_proto;
JSValue function_ctor;
JSValue array_ctor; JSValue array_ctor;
JSValue regexp_ctor; JSValue regexp_ctor;
JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; 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, JSValueConst this_obj,
int argc, JSValueConst *argv, int flags); int argc, JSValueConst *argv, int flags);
static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, 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_CallInternal(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
int argc, JSValue *argv, int flags); int argc, JSValue *argv, int flags);
static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv); 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_new_string8_len(JSContext *ctx, const char *buf, int len);
static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern, static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern,
JSValueConst flags); JSValueConst flags);
static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor, static JSValue js_regexp_constructor_internal(JSContext *ctx,
JSValue pattern, JSValue bc); JSValue pattern, JSValue bc);
static void gc_decref(JSRuntime *rt); static void gc_decref(JSRuntime *rt);
static int JS_NewClass1(JSRuntime *rt, JSClassID class_id, 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, static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h,
JSGCObjectTypeEnum type); JSGCObjectTypeEnum type);
static void remove_gc_object(JSGCObjectHeader *h); 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, static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p,
JSAtom atom, void *opaque); JSAtom atom, void *opaque);
static void JS_RunGCInternal(JSRuntime *rt); 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->array_ctor, mark_func);
JS_MarkValue(rt, ctx->regexp_ctor, mark_func); JS_MarkValue(rt, ctx->regexp_ctor, mark_func);
JS_MarkValue(rt, ctx->function_ctor, mark_func);
if (ctx->array_shape) if (ctx->array_shape)
mark_func(rt, &ctx->array_shape->header); mark_func(rt, &ctx->array_shape->header);
@@ -2003,7 +1994,6 @@ void JS_FreeContext(JSContext *ctx)
js_free_rt(rt, ctx->class_proto); js_free_rt(rt, ctx->class_proto);
JS_FreeValue(ctx, ctx->array_ctor); JS_FreeValue(ctx, ctx->array_ctor);
JS_FreeValue(ctx, ctx->regexp_ctor); JS_FreeValue(ctx, ctx->regexp_ctor);
JS_FreeValue(ctx, ctx->function_ctor);
js_free_shape_null(ctx->rt, ctx->array_shape); 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; 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 */ /* return NULL without exception if not a function or no bytecode */
static JSFunctionBytecode *JS_GetFunctionBytecode(JSValueConst val) 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); typedef JSValue JSAutoInitFunc(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque);
static JSAutoInitFunc *js_autoinit_func_table[] = { static JSAutoInitFunc *js_autoinit_func_table[] = {
js_instantiate_prototype, /* JS_AUTOINIT_ID_PROTOTYPE */
JS_InstantiateFunctionListItem2, /* JS_AUTOINIT_ID_PROP */ JS_InstantiateFunctionListItem2, /* JS_AUTOINIT_ID_PROP */
}; };
@@ -11369,27 +11370,6 @@ static JSValue js_closure2(JSContext *ctx, JSValue func_obj,
return JS_EXCEPTION; 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, static JSValue js_closure(JSContext *ctx, JSValue bfunc,
JSVarRef **cur_var_refs, JSVarRef **cur_var_refs,
JSStackFrame *sf) JSStackFrame *sf)
@@ -11510,19 +11490,9 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
} }
switch(cproto) { 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: case JS_CFUNC_generic:
ret_val = func.generic(ctx, this_obj, argc, arg_buf); ret_val = func.generic(ctx, this_obj, argc, arg_buf);
break; 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: case JS_CFUNC_generic_magic:
ret_val = func.generic_magic(ctx, this_obj, argc, arg_buf, ret_val = func.generic_magic(ctx, this_obj, argc, arg_buf,
p->u.cfunc.magic); p->u.cfunc.magic);
@@ -11587,7 +11557,7 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj,
{ {
JSObject *p; JSObject *p;
JSBoundFunction *bf; JSBoundFunction *bf;
JSValueConst *arg_buf, new_target; JSValueConst *arg_buf;
int arg_count, i; int arg_count, i;
p = JS_VALUE_GET_OBJ(func_obj); 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! */ /* VM frame management for trampoline - no malloc/free! */
static struct VMFrame *vm_push_frame(JSContext *ctx, static struct VMFrame *vm_push_frame(JSContext *ctx,
JSValueConst func_obj, JSValueConst this_obj, JSValueConst func_obj, JSValueConst this_obj,
JSValueConst new_target,
int argc, JSValue *argv, int flags, int argc, JSValue *argv, int flags,
const uint8_t *ret_pc, int ret_sp_offset, const uint8_t *ret_pc, int ret_sp_offset,
int call_argc, int call_has_this) int call_argc, int call_has_this)
@@ -11758,7 +11727,6 @@ static struct VMFrame *vm_push_frame(JSContext *ctx,
/* Initialize frame metadata */ /* Initialize frame metadata */
frame->cur_func = JS_DupValue(ctx, func_obj); frame->cur_func = JS_DupValue(ctx, func_obj);
frame->this_obj = JS_DupValue(ctx, this_obj); frame->this_obj = JS_DupValue(ctx, this_obj);
frame->new_target = JS_DupValue(ctx, new_target);
frame->b = b; frame->b = b;
frame->ctx = b->realm; frame->ctx = b->realm;
frame->pc = b->byte_code_buf; frame->pc = b->byte_code_buf;
@@ -11809,7 +11777,6 @@ static void vm_pop_frame(JSContext *ctx)
/* Free frame values */ /* Free frame values */
JS_FreeValue(ctx, frame->cur_func); JS_FreeValue(ctx, frame->cur_func);
JS_FreeValue(ctx, frame->this_obj); JS_FreeValue(ctx, frame->this_obj);
JS_FreeValue(ctx, frame->new_target);
/* Pop frame and value stack */ /* Pop frame and value stack */
ctx->value_stack_top -= frame->stack_size_allocated; 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 */ /* Trampoline VM dispatcher - runs frames without C recursion */
static JSValue JS_CallTrampoline(JSContext *caller_ctx, JSValueConst func_obj, 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) int argc, JSValue *argv, int flags)
{ {
JSRuntime *rt = caller_ctx->rt; 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) */ /* 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, argc, argv, flags,
NULL, 0, 0, 0); NULL, 0, 0, 0);
if (!frame) if (!frame)
@@ -11896,7 +11863,7 @@ static VMExecState vm_execute_frame(JSContext *ctx, struct VMFrame *frame,
/* TODO: Replace with proper bytecode loop extraction */ /* TODO: Replace with proper bytecode loop extraction */
/* For now, delegate to the old recursive implementation */ /* For now, delegate to the old recursive implementation */
*ret_val = JS_CallInternal(ctx, frame->cur_func, frame->this_obj, *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); vm_frame_get_arg_buf(ctx, frame), 0);
if (JS_IsException(*ret_val)) if (JS_IsException(*ret_val))
return VM_EXEC_EXCEPTION; 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, 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) int argc, JSValue *argv, int flags)
{ {
JSRuntime *rt = caller_ctx->rt; JSRuntime *rt = caller_ctx->rt;
@@ -12076,13 +12043,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{ {
JSValue val; JSValue val;
/* User-defined functions don't support property access in cell script */ /* Functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-1])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-1]); JS_ThrowTypeError(ctx, "cannot get property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
} }
sf->cur_pc = pc; 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); *sp++ = JS_DupValue(ctx, sf->cur_func);
break; break;
case OP_SPECIAL_OBJECT_NEW_TARGET: case OP_SPECIAL_OBJECT_NEW_TARGET:
*sp++ = JS_DupValue(ctx, new_target); /* new.target is always null (constructors not supported) */
*sp++ = JS_NULL;
break; break;
case OP_SPECIAL_OBJECT_VAR_OBJECT: case OP_SPECIAL_OBJECT_VAR_OBJECT:
*sp++ = JS_NewObjectProto(ctx, JS_NULL); *sp++ = JS_NewObjectProto(ctx, JS_NULL);
@@ -12323,7 +12288,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
#endif #endif
/* TODO: Use trampoline - for now keep recursive */ /* TODO: Use trampoline - for now keep recursive */
ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL, 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))) if (unlikely(JS_IsException(ret_val)))
goto exception; goto exception;
if (opcode == OP_tail_call) if (opcode == OP_tail_call)
@@ -12347,16 +12312,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
/* Record call site */ /* Record call site */
profile_record_call_site(rt, b, (uint32_t)(pc - b->byte_code_buf)); profile_record_call_site(rt, b, (uint32_t)(pc - b->byte_code_buf));
#endif #endif
/* Proxy method-call: detect [bytecode_func, "name", ...args] /* Proxy method-call: detect [func, "name", ...args]
and rewrite as func("name", [args]) */ and rewrite as func("name", [args]) */
if (JS_VALUE_GET_TAG(call_argv[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(call_argv[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(call_argv[-2]); if (!JS_IsFunction(ctx, call_argv[-1])) {
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { int t = JS_VALUE_GET_TAG(call_argv[-1]);
if (!JS_IsFunction(ctx, call_argv[-1])) { if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
int t = JS_VALUE_GET_TAG(call_argv[-1]); is_proxy = TRUE;
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; proxy_argv[1] = args;
ret_val = JS_CallInternal(ctx, call_argv[-2], JS_NULL, ret_val = JS_CallInternal(ctx, call_argv[-2], JS_NULL,
JS_NULL, 2, proxy_argv, 0); 2, proxy_argv, 0);
JS_FreeValue(ctx, args); JS_FreeValue(ctx, args);
} }
} else { } else {
ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2], 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))) if (unlikely(JS_IsException(ret_val)))
goto exception; goto exception;
@@ -12433,16 +12395,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
pc += 2; pc += 2;
sf->cur_pc = pc; 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) */ and rewrite as func("name", args_array) */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]); if (!JS_IsFunction(ctx, sp[-3])) {
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { int t = JS_VALUE_GET_TAG(sp[-3]);
if (!JS_IsFunction(ctx, sp[-3])) { if (t == JS_TAG_STRING || t == JS_TAG_SYMBOL)
int t = JS_VALUE_GET_TAG(sp[-3]); is_proxy = TRUE;
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 */ proxy_argv[1] = sp[-1]; /* args array already built by bytecode */
ret_val = JS_CallInternal(ctx, sp[-2], JS_NULL, ret_val = JS_CallInternal(ctx, sp[-2], JS_NULL,
JS_NULL, 2, proxy_argv, 0); 2, proxy_argv, 0);
} else { } else {
ret_val = js_function_apply(ctx, sp[-3], 2, (JSValueConst *)&sp[-2], magic); 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); JS_EVAL_TYPE_DIRECT, scope_idx);
} else { } else {
ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL, 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))) if (unlikely(JS_IsException(ret_val)))
goto exception; goto exception;
@@ -12568,8 +12527,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_regexp): CASE(OP_regexp):
{ {
sp[-2] = js_regexp_constructor_internal(ctx, JS_NULL, sp[-2] = js_regexp_constructor_internal(ctx, sp[-2], sp[-1]);
sp[-2], sp[-1]);
sp--; sp--;
} }
BREAK; BREAK;
@@ -13147,13 +13105,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
#endif #endif
obj = sp[-1]; obj = sp[-1];
/* User-defined functions don't support property access in cell script */ /* Functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { if (js_is_proxy_callable(obj)) {
JSObject *fp = JS_VALUE_GET_OBJ(obj); JS_ThrowTypeError(ctx, "cannot get property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
} }
/* Monomorphic IC fast path: shape-guarded own-property lookup */ /* 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...]) /* Proxy method-call sugar: func.name(...) -> func("name", [args...])
OP_get_field2 is only emitted when a call immediately follows. */ OP_get_field2 is only emitted when a call immediately follows. */
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { if (js_is_proxy_callable(obj)) {
JSObject *fp = JS_VALUE_GET_OBJ(obj); val = JS_AtomToValue(ctx, atom); /* "name" */
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { if (unlikely(JS_IsException(val)))
val = JS_AtomToValue(ctx, atom); /* "name" */ goto exception;
if (unlikely(JS_IsException(val))) *sp++ = val; /* stack becomes [func, "name"] */
goto exception; goto get_field2_done;
*sp++ = val; /* stack becomes [func, "name"] */
goto get_field2_done;
}
} }
/* Monomorphic IC fast path */ /* Monomorphic IC fast path */
@@ -13315,13 +13267,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
/* Record property access site */ /* Record property access site */
profile_record_prop_site(rt, b, (uint32_t)(pc - b->byte_code_buf), atom); profile_record_prop_site(rt, b, (uint32_t)(pc - b->byte_code_buf), atom);
#endif #endif
/* User-defined functions don't support property assignment in cell script */ /* Functions don't support property assignment in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]); JS_ThrowTypeError(ctx, "cannot set property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
} }
ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], sp[-2], 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; JSValue val;
/* User-defined functions don't support property access in cell script */ /* Functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]); JS_ThrowTypeError(ctx, "cannot get property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
} }
sf->cur_pc = pc; sf->cur_pc = pc;
@@ -13474,34 +13420,31 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JSValue val; JSValue val;
/* Proxy method-call sugar for bracket calls: func[key](...) */ /* Proxy method-call sugar for bracket calls: func[key](...) */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]); /* Keep [func, key] and normalize key to property-key (string/symbol). */
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { switch (JS_VALUE_GET_TAG(sp[-1])) {
/* Keep [func, key] and normalize key to property-key (string/symbol). */ case JS_TAG_INT:
switch (JS_VALUE_GET_TAG(sp[-1])) { /* Convert integer to string */
case JS_TAG_INT: sf->cur_pc = pc;
/* Convert integer to string */ ret_val = JS_ToString(ctx, sp[-1]);
sf->cur_pc = pc; if (JS_IsException(ret_val))
ret_val = JS_ToString(ctx, sp[-1]); goto exception;
if (JS_IsException(ret_val)) JS_FreeValue(ctx, sp[-1]);
goto exception; sp[-1] = ret_val;
JS_FreeValue(ctx, sp[-1]); break;
sp[-1] = ret_val; case JS_TAG_STRING:
break; case JS_TAG_SYMBOL:
case JS_TAG_STRING: break;
case JS_TAG_SYMBOL: default:
break; sf->cur_pc = pc;
default: ret_val = JS_ToPropertyKey(ctx, sp[-1]);
sf->cur_pc = pc; if (JS_IsException(ret_val))
ret_val = JS_ToPropertyKey(ctx, sp[-1]); goto exception;
if (JS_IsException(ret_val)) JS_FreeValue(ctx, sp[-1]);
goto exception; sp[-1] = ret_val;
JS_FreeValue(ctx, sp[-1]); break;
sp[-1] = ret_val;
break;
}
BREAK; /* skip JS_GetPropertyValue, keep [func, key] on stack */
} }
BREAK; /* skip JS_GetPropertyValue, keep [func, key] on stack */
} }
sf->cur_pc = pc; sf->cur_pc = pc;
@@ -13516,13 +13459,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{ {
JSValue val; JSValue val;
/* User-defined functions don't support property access in cell script */ /* Functions don't support property access in cell script */
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-2])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-2]); JS_ThrowTypeError(ctx, "cannot get property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot get property of function");
goto exception;
}
} }
switch (JS_VALUE_GET_TAG(sp[-2])) { switch (JS_VALUE_GET_TAG(sp[-2])) {
@@ -13593,13 +13533,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
{ {
int ret; int ret;
/* User-defined functions don't support property assignment in cell script */ /* Functions don't support property assignment in cell script */
if (JS_VALUE_GET_TAG(sp[-3]) == JS_TAG_OBJECT) { if (js_is_proxy_callable(sp[-3])) {
JSObject *fp = JS_VALUE_GET_OBJ(sp[-3]); JS_ThrowTypeError(ctx, "cannot set property of function");
if (fp->class_id == JS_CLASS_BYTECODE_FUNCTION) { goto exception;
JS_ThrowTypeError(ctx, "cannot set property of function");
goto exception;
}
} }
sf->cur_pc = pc; sf->cur_pc = pc;
@@ -14395,14 +14332,14 @@ CASE(OP_template_concat):
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv) 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); argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV);
} }
static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj, static JSValue JS_CallFree(JSContext *ctx, JSValue func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv) 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); argc, (JSValue *)argv, JS_CALL_FLAG_COPY_ARGV);
JS_FreeValue(ctx, func_obj); JS_FreeValue(ctx, func_obj);
return res; return res;
@@ -26389,50 +26326,6 @@ int JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
return 0; 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 */ /* Object class */
static JSValue JS_ToObject(JSContext *ctx, JSValueConst val) static JSValue JS_ToObject(JSContext *ctx, JSValueConst val)
@@ -26719,35 +26612,20 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
} }
/* Error class */ /* 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) int argc, JSValueConst *argv, int magic)
{ {
JSValue obj, msg, proto; JSValue obj, msg;
JSValueConst message, options; JSValueConst message, options, proto;
int arg_index; int arg_index;
if (JS_IsNull(new_target)) /* Use the appropriate error prototype based on magic */
new_target = JS_GetActiveFunction(ctx); if (magic < 0) {
proto = JS_GetProperty(ctx, new_target, JS_ATOM_prototype); proto = ctx->class_proto[JS_CLASS_ERROR];
if (JS_IsException(proto)) } else {
return proto; proto = ctx->native_error_proto[magic];
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);
} }
obj = JS_NewObjectProtoClass(ctx, proto, JS_CLASS_ERROR); obj = JS_NewObjectProtoClass(ctx, proto, JS_CLASS_ERROR);
JS_FreeValue(ctx, proto);
if (JS_IsException(obj)) if (JS_IsException(obj))
return obj; return obj;
arg_index = (magic == JS_AGGREGATE_ERROR); arg_index = (magic == JS_AGGREGATE_ERROR);
@@ -26916,13 +26794,13 @@ static int JS_CopySubArray(JSContext *ctx,
return -1; 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) int argc, JSValueConst *argv)
{ {
JSValue obj; JSValue obj;
int i; int i;
obj = js_create_from_ctor(ctx, new_target, JS_CLASS_ARRAY); obj = JS_NewArray(ctx);
if (JS_IsException(obj)) if (JS_IsException(obj))
return obj; return obj;
if (argc == 1 && JS_IsNumber(argv[0])) { 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 /* create a RegExp object from a string containing the RegExp bytecode
and the source pattern */ 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 pattern, JSValue bc)
{ {
JSValue obj; JSValue obj;
@@ -27394,7 +27272,7 @@ static JSValue js_regexp_constructor_internal(JSContext *ctx, JSValueConst ctor,
return JS_EXCEPTION; 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)) if (JS_IsException(obj))
goto fail; goto fail;
p = JS_VALUE_GET_OBJ(obj); 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; 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) int argc, JSValueConst *argv)
{ {
JSValue pattern, flags, bc, val; 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); pat_is_regexp = js_is_regexp(ctx, pat);
if (pat_is_regexp < 0) if (pat_is_regexp < 0)
return JS_EXCEPTION; return JS_EXCEPTION;
if (JS_IsNull(new_target)) { /* If called with a regexp and no flags, just return a copy */
/* called as a function */ if (pat_is_regexp && JS_IsNull(flags1)) {
new_target = JS_GetActiveFunction(ctx); re = js_get_regexp(ctx, pat, FALSE);
if (pat_is_regexp && JS_IsNull(flags1)) { if (re)
JSValue ctor; return JS_DupValue(ctx, pat);
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);
}
} }
re = js_get_regexp(ctx, pat, FALSE); re = js_get_regexp(ctx, pat, FALSE);
if (re) { if (re) {
@@ -27505,7 +27374,7 @@ static JSValue js_regexp_constructor(JSContext *ctx, JSValueConst new_target,
goto fail; goto fail;
JS_FreeValue(ctx, flags); JS_FreeValue(ctx, flags);
no_compilation: no_compilation:
return js_regexp_constructor_internal(ctx, new_target, pattern, bc); return js_regexp_constructor_internal(ctx, pattern, bc);
fail: fail:
JS_FreeValue(ctx, pattern); JS_FreeValue(ctx, pattern);
JS_FreeValue(ctx, flags); JS_FreeValue(ctx, flags);
@@ -28099,9 +27968,12 @@ void JS_AddIntrinsicRegExp(JSContext *ctx)
ctx->class_proto[JS_CLASS_REGEXP] = JS_NewObject(ctx); ctx->class_proto[JS_CLASS_REGEXP] = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_REGEXP], js_regexp_proto_funcs, JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_REGEXP], js_regexp_proto_funcs,
countof(js_regexp_proto_funcs)); countof(js_regexp_proto_funcs));
obj = JS_NewGlobalCConstructor(ctx, "RegExp", js_regexp_constructor, 2, obj = JS_NewCFunction2(ctx, js_regexp_constructor, "RegExp", 2,
ctx->class_proto[JS_CLASS_REGEXP]); JS_CFUNC_generic, 0);
ctx->regexp_ctor = JS_DupValue(ctx, obj); JS_DefinePropertyValueStr(ctx, ctx->global_obj, "RegExp",
JS_DupValue(ctx, obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
ctx->regexp_ctor = obj;
} }
/* JSON */ /* JSON */
@@ -31675,7 +31547,7 @@ static void js_blob_finalizer(JSRuntime *rt, JSValue val)
} }
/* blob() constructor */ /* 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) int argc, JSValueConst *argv)
{ {
blob *bd = NULL; blob *bd = NULL;
@@ -32987,32 +32859,34 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
ctx->global_obj = JS_NewObject(ctx); ctx->global_obj = JS_NewObject(ctx);
ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL); ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL);
/* Function - no constructor needed */
ctx->function_ctor = JS_NULL;
/* Error */ /* Error */
obj1 = JS_NewCFunctionMagic(ctx, js_error_constructor, obj1 = JS_NewCFunctionMagic(ctx, js_error_constructor,
"Error", 1, JS_CFUNC_constructor_or_func_magic, -1); "Error", 1, JS_CFUNC_generic_magic, -1);
JS_NewGlobalCConstructor2(ctx, obj1, JS_DefinePropertyValueStr(ctx, ctx->global_obj, "Error",
"Error", ctx->class_proto[JS_CLASS_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++) { for(i = 0; i < JS_NATIVE_ERROR_COUNT; i++) {
JSValue func_obj; JSValue func_obj;
int n_args; int n_args;
n_args = 1 + (i == JS_AGGREGATE_ERROR); n_args = 1 + (i == JS_AGGREGATE_ERROR);
func_obj = JS_NewCFunction3(ctx, ft.generic, func_obj = JS_NewCFunctionMagic(ctx, js_error_constructor,
native_error_name[i], n_args, native_error_name[i], n_args,
JS_CFUNC_constructor_or_func_magic, i, obj1); JS_CFUNC_generic_magic, i);
JS_NewGlobalCConstructor2(ctx, func_obj, native_error_name[i], JS_DefinePropertyValueStr(ctx, ctx->global_obj, native_error_name[i],
ctx->native_error_proto[i]); JS_DupValue(ctx, func_obj),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, func_obj);
} }
/* Array */ /* Array */
obj = JS_NewGlobalCConstructor(ctx, "Array", js_array_constructor, 1, obj = JS_NewCFunction2(ctx, js_array_constructor, "Array", 1,
ctx->class_proto[JS_CLASS_ARRAY]); JS_CFUNC_generic, 0);
ctx->array_ctor = JS_DupValue(ctx, obj); 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 */ /* XXX: create auto_initializer */
{ {

View File

@@ -685,8 +685,6 @@ JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
JSValue JS_NewObject(JSContext *ctx); JSValue JS_NewObject(JSContext *ctx);
JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val); 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); JSValue JS_NewArray(JSContext *ctx);
int JS_IsArray(JSContext *ctx, JSValueConst val); 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); int argc, JSValueConst *argv);
JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom, JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
int argc, JSValueConst *argv); 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'. */ /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len, JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags); 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); JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
/* C function definition */ /* C function definition */
typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */ typedef enum JSCFunctionEnum {
JS_CFUNC_generic, JS_CFUNC_generic,
JS_CFUNC_generic_magic, 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,
JS_CFUNC_f_f_f, JS_CFUNC_f_f_f,
JS_CFUNC_getter, JS_CFUNC_getter,
@@ -841,9 +830,6 @@ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
typedef union JSCFunctionType { typedef union JSCFunctionType {
JSCFunction *generic; JSCFunction *generic;
JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); 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)(double);
double (*f_f_f)(double, double); double (*f_f_f)(double, double);
JSValue (*getter)(JSContext *ctx, JSValueConst this_val); 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); return JS_NewCFunction2(ctx, (JSCFunction *)func, name, length, cproto, magic);
} }
void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
JSValueConst proto);
/* C property definition */ /* C property definition */