fixed function arity
This commit is contained in:
49
build.cm
49
build.cm
@@ -121,11 +121,11 @@ Build.compile_file = function(pkg, file, target, buildtype = 'release') {
|
|||||||
|
|
||||||
// Add buildtype-specific flags
|
// Add buildtype-specific flags
|
||||||
if (buildtype == 'release') {
|
if (buildtype == 'release') {
|
||||||
push(cmd_parts, '-O3', '-DNDEBUG')
|
cmd_parts = array(cmd_parts, ['-O3', '-DNDEBUG'])
|
||||||
} else if (buildtype == 'debug') {
|
} else if (buildtype == 'debug') {
|
||||||
push(cmd_parts, '-O2', '-g')
|
cmd_parts = array(cmd_parts, ['-O2', '-g'])
|
||||||
} else if (buildtype == 'minsize') {
|
} else if (buildtype == 'minsize') {
|
||||||
push(cmd_parts, '-Os', '-DNDEBUG')
|
cmd_parts = array(cmd_parts, ['-Os', '-DNDEBUG'])
|
||||||
}
|
}
|
||||||
|
|
||||||
push(cmd_parts, '-DCELL_USE_NAME=' + sym_name)
|
push(cmd_parts, '-DCELL_USE_NAME=' + sym_name)
|
||||||
@@ -278,23 +278,20 @@ 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
|
cmd_parts = array(cmd_parts, [
|
||||||
push(cmd_parts, '-undefined', 'dynamic_lookup')
|
'-undefined', 'dynamic_lookup',
|
||||||
// Dead-strip unused code
|
'-Wl,-dead_strip',
|
||||||
push(cmd_parts, '-Wl,-dead_strip')
|
'-Wl,-install_name,' + stable_path,
|
||||||
// Set install_name to stable path so runtime finds it correctly
|
'-Wl,-rpath,@loader_path/../local',
|
||||||
push(cmd_parts, '-Wl,-install_name,' + stable_path)
|
'-Wl,-rpath,' + local_dir
|
||||||
// rpath for .cell/local libraries
|
])
|
||||||
push(cmd_parts, '-Wl,-rpath,@loader_path/../local')
|
|
||||||
push(cmd_parts, '-Wl,-rpath,' + local_dir)
|
|
||||||
} else if (tc.system == 'linux') {
|
} else if (tc.system == 'linux') {
|
||||||
// Allow undefined symbols at link time
|
cmd_parts = array(cmd_parts, [
|
||||||
push(cmd_parts, '-Wl,--allow-shlib-undefined')
|
'-Wl,--allow-shlib-undefined',
|
||||||
// Garbage collect unused sections
|
'-Wl,--gc-sections',
|
||||||
push(cmd_parts, '-Wl,--gc-sections')
|
'-Wl,-rpath,$ORIGIN/../local',
|
||||||
// rpath for .cell/local libraries
|
'-Wl,-rpath,' + local_dir
|
||||||
push(cmd_parts, '-Wl,-rpath,$ORIGIN/../local')
|
])
|
||||||
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
|
||||||
push(cmd_parts, '-Wl,--allow-shlib-undefined')
|
push(cmd_parts, '-Wl,--allow-shlib-undefined')
|
||||||
@@ -308,17 +305,11 @@ Build.build_dynamic = function(pkg, target = Build.detect_host_target(), buildty
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Do NOT link against core library - symbols resolved at dlopen time
|
// Do NOT link against core library - symbols resolved at dlopen time
|
||||||
|
cmd_parts = array(cmd_parts, resolved_ldflags)
|
||||||
|
cmd_parts = array(cmd_parts, target_ldflags)
|
||||||
|
|
||||||
// Add LDFLAGS
|
push(cmd_parts, '-o')
|
||||||
arrfor(resolved_ldflags, function(flag) {
|
push(cmd_parts, '"' + store_path + '"')
|
||||||
push(cmd_parts, flag)
|
|
||||||
})
|
|
||||||
|
|
||||||
arrfor(target_ldflags, function(flag) {
|
|
||||||
push(cmd_parts, flag)
|
|
||||||
})
|
|
||||||
|
|
||||||
push(cmd_parts, '-o', '"' + store_path + '"')
|
|
||||||
|
|
||||||
var cmd_str = text(cmd_parts, ' ')
|
var cmd_str = text(cmd_parts, ' ')
|
||||||
|
|
||||||
|
|||||||
2
crypto.c
2
crypto.c
@@ -231,7 +231,7 @@ JSValue js_crypto_unlock(JSContext *js, JSValue self, int argc, JSValue *argv) {
|
|||||||
|
|
||||||
static const JSCFunctionListEntry js_crypto_funcs[] = {
|
static const JSCFunctionListEntry js_crypto_funcs[] = {
|
||||||
JS_CFUNC_DEF("shared", 2, js_crypto_shared),
|
JS_CFUNC_DEF("shared", 2, js_crypto_shared),
|
||||||
JS_CFUNC_DEF("blake2", 1, js_crypto_blake2),
|
JS_CFUNC_DEF("blake2", 2, js_crypto_blake2),
|
||||||
JS_CFUNC_DEF("sign", 2, js_crypto_sign),
|
JS_CFUNC_DEF("sign", 2, js_crypto_sign),
|
||||||
JS_CFUNC_DEF("verify", 3, js_crypto_verify),
|
JS_CFUNC_DEF("verify", 3, js_crypto_verify),
|
||||||
JS_CFUNC_DEF("lock", 3, js_crypto_lock),
|
JS_CFUNC_DEF("lock", 3, js_crypto_lock),
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ function use_core(path) {
|
|||||||
var script = text(script_blob)
|
var script = text(script_blob)
|
||||||
var mod = `(function setup_module(use){${script}})`
|
var mod = `(function setup_module(use){${script}})`
|
||||||
var fn = js.eval('core:' + path, mod)
|
var fn = js.eval('core:' + path, mod)
|
||||||
var result = call(fn,sym, use_core)
|
var result = call(fn,sym, [use_core])
|
||||||
use_cache[cache_key] = result;
|
use_cache[cache_key] = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ function disrupt(err)
|
|||||||
|
|
||||||
if (underlings) {
|
if (underlings) {
|
||||||
var unders = array(underlings)
|
var unders = array(underlings)
|
||||||
arrfor(unders, function(id) {
|
arrfor(unders, function(id, index) {
|
||||||
log.console(`calling on ${id} to disrupt too`)
|
log.console(`calling on ${id} to disrupt too`)
|
||||||
$_.stop(create_actor({id}))
|
$_.stop(create_actor({id}))
|
||||||
})
|
})
|
||||||
@@ -416,14 +416,14 @@ function handle_host(e) {
|
|||||||
peers[`${e.peer.address}:${e.peer.port}`] = e.peer
|
peers[`${e.peer.address}:${e.peer.port}`] = e.peer
|
||||||
var queue = peer_queue.get(e.peer)
|
var queue = peer_queue.get(e.peer)
|
||||||
if (queue) {
|
if (queue) {
|
||||||
arrfor(queue, msg => e.peer.send(nota.encode(msg)))
|
arrfor(queue, (msg, index) => e.peer.send(nota.encode(msg)))
|
||||||
log.system(`sent ${msg} out of queue`)
|
log.system(`sent ${msg} out of queue`)
|
||||||
peer_queue.delete(e.peer)
|
peer_queue.delete(e.peer)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "disconnect":
|
case "disconnect":
|
||||||
peer_queue.delete(e.peer)
|
peer_queue.delete(e.peer)
|
||||||
arrfor(array(peers), function(id) {
|
arrfor(array(peers), function(id, index) {
|
||||||
if (peers[id] == e.peer) delete peers[id]
|
if (peers[id] == e.peer) delete peers[id]
|
||||||
})
|
})
|
||||||
log.system('portal got disconnect from ' + e.peer.address + ":" + e.peer.port)
|
log.system('portal got disconnect from ' + e.peer.address + ":" + e.peer.port)
|
||||||
@@ -440,7 +440,7 @@ function handle_host(e) {
|
|||||||
obj[ACTORDATA].address = e.peer.address
|
obj[ACTORDATA].address = e.peer.address
|
||||||
obj[ACTORDATA].port = e.peer.port
|
obj[ACTORDATA].port = e.peer.port
|
||||||
}
|
}
|
||||||
arrfor(array(obj), function(key) {
|
arrfor(array(obj), function(key, index) {
|
||||||
if (key in obj)
|
if (key in obj)
|
||||||
populate_actor_addresses(obj[key])
|
populate_actor_addresses(obj[key])
|
||||||
})
|
})
|
||||||
@@ -496,11 +496,6 @@ $_.unneeded = function unneeded(fn, seconds) {
|
|||||||
|
|
||||||
// schedules the invocation of a function after a specified amount of time.
|
// schedules the invocation of a function after a specified amount of time.
|
||||||
$_.delay = function delay(fn, seconds = 0) {
|
$_.delay = function delay(fn, seconds = 0) {
|
||||||
if (seconds <= 0) {
|
|
||||||
$_.clock(fn)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
function delay_turn() {
|
function delay_turn() {
|
||||||
fn()
|
fn()
|
||||||
send_messages()
|
send_messages()
|
||||||
@@ -592,7 +587,7 @@ var need_stop = false
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfor(message_queue, function(msg) {
|
arrfor(message_queue, function(msg, index) {
|
||||||
if (msg.startup) {
|
if (msg.startup) {
|
||||||
// now is the time to actually spin up the actor
|
// now is the time to actually spin up the actor
|
||||||
actor_mod.createactor(msg.startup)
|
actor_mod.createactor(msg.startup)
|
||||||
@@ -817,7 +812,7 @@ $_.clock(_ => {
|
|||||||
|
|
||||||
// Call with signature: setup_module(args, use, env)
|
// Call with signature: setup_module(args, use, env)
|
||||||
// The script wrapper binds $delay, $start, etc. from env
|
// The script wrapper binds $delay, $start, etc. from env
|
||||||
var val = call(locator.symbol, null, _cell.args.arg, use_fn, env)
|
var val = call(locator.symbol, null, [_cell.args.arg, use_fn, env])
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
throw Error('Program must not return anything');
|
throw Error('Program must not return anything');
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ Shop.open_package_dylib = function(pkg) {
|
|||||||
var content = text(fd.slurp(toml_path))
|
var content = text(fd.slurp(toml_path))
|
||||||
var cfg = toml.decode(content)
|
var cfg = toml.decode(content)
|
||||||
if (cfg.dependencies) {
|
if (cfg.dependencies) {
|
||||||
arrfor(array(cfg.dependencies), function(alias) {
|
arrfor(array(cfg.dependencies), function(alias, i) {
|
||||||
var dep_pkg = cfg.dependencies[alias]
|
var dep_pkg = cfg.dependencies[alias]
|
||||||
try {
|
try {
|
||||||
Shop.open_package_dylib(dep_pkg)
|
Shop.open_package_dylib(dep_pkg)
|
||||||
@@ -812,7 +812,7 @@ function execute_module(info)
|
|||||||
|
|
||||||
// Call with signature: setup_module(args, use, env)
|
// Call with signature: setup_module(args, use, env)
|
||||||
// args is null for module loading
|
// args is null for module loading
|
||||||
used = call(mod_resolve.symbol, context, null, use_fn, env)
|
used = call(mod_resolve.symbol, context, [null, use_fn, env])
|
||||||
} else if (c_resolve.scope < 900) {
|
} else if (c_resolve.scope < 900) {
|
||||||
// C only
|
// C only
|
||||||
used = call_c_module(c_resolve)
|
used = call_c_module(c_resolve)
|
||||||
@@ -1195,11 +1195,11 @@ Shop.module_reload = function(path, package) {
|
|||||||
var old = use_cache[cache_key]
|
var old = use_cache[cache_key]
|
||||||
var newmod = get_module(path, package)
|
var newmod = get_module(path, package)
|
||||||
|
|
||||||
arrfor(array(newmod), function(i) {
|
arrfor(array(newmod), function(i, idx) {
|
||||||
old[i] = newmod[i]
|
old[i] = newmod[i]
|
||||||
})
|
})
|
||||||
|
|
||||||
arrfor(array(old), function(i) {
|
arrfor(array(old), function(i, idx) {
|
||||||
if (!(i in newmod))
|
if (!(i in newmod))
|
||||||
old[i] = null
|
old[i] = null
|
||||||
})
|
})
|
||||||
@@ -1226,7 +1226,7 @@ Shop.build_package_scripts = function(package)
|
|||||||
var scripts = get_package_scripts(package)
|
var scripts = get_package_scripts(package)
|
||||||
var pkg_dir = get_package_abs_dir(package)
|
var pkg_dir = get_package_abs_dir(package)
|
||||||
|
|
||||||
arrfor(scripts, function(script) {
|
arrfor(scripts, function(script, i) {
|
||||||
resolve_mod_fn(pkg_dir + '/' + script, package)
|
resolve_mod_fn(pkg_dir + '/' + script, package)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1284,7 +1284,7 @@ Shop.audit_packages = function() {
|
|||||||
|
|
||||||
var bad = []
|
var bad = []
|
||||||
|
|
||||||
arrfor(packages, function(package) {
|
arrfor(packages, function(package, i) {
|
||||||
if (package == 'core') return
|
if (package == 'core') return
|
||||||
if (fd.is_dir(package)) return
|
if (fd.is_dir(package)) return
|
||||||
if (fetch_remote_hash(package)) return
|
if (fetch_remote_hash(package)) return
|
||||||
|
|||||||
207
source/quickjs.c
207
source/quickjs.c
@@ -686,7 +686,7 @@ typedef enum {
|
|||||||
typedef struct JSFunction {
|
typedef struct JSFunction {
|
||||||
JSGCObjectHeader header; /* must come first */
|
JSGCObjectHeader header; /* must come first */
|
||||||
JSAtom name;
|
JSAtom name;
|
||||||
uint8_t length;
|
uint16_t length; /* arity: max allowed arguments */
|
||||||
uint8_t kind;
|
uint8_t kind;
|
||||||
uint8_t free_mark : 1;
|
uint8_t free_mark : 1;
|
||||||
union {
|
union {
|
||||||
@@ -4986,7 +4986,7 @@ JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
|
|||||||
|
|
||||||
typedef struct JSCFunctionDataRecord {
|
typedef struct JSCFunctionDataRecord {
|
||||||
JSCFunctionData *func;
|
JSCFunctionData *func;
|
||||||
uint8_t length;
|
uint16_t length; /* arity: max allowed arguments */
|
||||||
uint8_t data_len;
|
uint8_t data_len;
|
||||||
uint16_t magic;
|
uint16_t magic;
|
||||||
JSValue data[0];
|
JSValue data[0];
|
||||||
@@ -10133,7 +10133,7 @@ static JSValue js_closure(JSContext *ctx, JSValue bfunc,
|
|||||||
if (name_atom == JS_ATOM_NULL)
|
if (name_atom == JS_ATOM_NULL)
|
||||||
name_atom = JS_ATOM_empty_string;
|
name_atom = JS_ATOM_empty_string;
|
||||||
f->name = JS_DupAtom(ctx, name_atom);
|
f->name = JS_DupAtom(ctx, name_atom);
|
||||||
f->length = b->defined_arg_count;
|
f->length = b->arg_count; /* arity = total parameter count */
|
||||||
return func_obj;
|
return func_obj;
|
||||||
fail:
|
fail:
|
||||||
/* bfunc is freed when func_obj is freed */
|
/* bfunc is freed when func_obj is freed */
|
||||||
@@ -10263,6 +10263,19 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj,
|
|||||||
ret_val = JS_NewFloat64(ctx, func.f_f_f(d1, d2));
|
ret_val = JS_NewFloat64(ctx, func.f_f_f(d1, d2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
/* Fixed-arity fast paths - direct call without argc/argv marshaling */
|
||||||
|
case JS_CFUNC_0:
|
||||||
|
ret_val = func.f0(ctx, this_obj);
|
||||||
|
break;
|
||||||
|
case JS_CFUNC_1:
|
||||||
|
ret_val = func.f1(ctx, this_obj, arg_buf[0]);
|
||||||
|
break;
|
||||||
|
case JS_CFUNC_2:
|
||||||
|
ret_val = func.f2(ctx, this_obj, arg_buf[0], arg_buf[1]);
|
||||||
|
break;
|
||||||
|
case JS_CFUNC_3:
|
||||||
|
ret_val = func.f3(ctx, this_obj, arg_buf[0], arg_buf[1], arg_buf[2]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@@ -10436,10 +10449,15 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
return JS_ThrowTypeError(caller_ctx, "not a function");
|
return JS_ThrowTypeError(caller_ctx, "not a function");
|
||||||
}
|
}
|
||||||
f = JS_VALUE_GET_FUNCTION(func_obj);
|
f = JS_VALUE_GET_FUNCTION(func_obj);
|
||||||
|
/* Strict arity enforcement: too many arguments throws */
|
||||||
|
if (unlikely(argc > f->length)) {
|
||||||
|
char buf[ATOM_GET_STR_BUF_SIZE];
|
||||||
|
return JS_ThrowTypeError(caller_ctx, "too many arguments for %s: expected %d, got %d", JS_AtomGetStr(caller_ctx,buf, ATOM_GET_STR_BUF_SIZE, f->name), f->length, argc);
|
||||||
|
}
|
||||||
switch (f->kind) {
|
switch (f->kind) {
|
||||||
case JS_FUNC_KIND_C:
|
case JS_FUNC_KIND_C:
|
||||||
return js_call_c_function(caller_ctx, func_obj, this_obj, argc,
|
return js_call_c_function(caller_ctx, func_obj, this_obj, argc,
|
||||||
(JSValueConst *)argv);
|
(JSValueConst *)argv);
|
||||||
case JS_FUNC_KIND_BOUND:
|
case JS_FUNC_KIND_BOUND:
|
||||||
return js_call_bound_function(caller_ctx, func_obj, this_obj, argc,
|
return js_call_bound_function(caller_ctx, func_obj, this_obj, argc,
|
||||||
(JSValueConst *)argv);
|
(JSValueConst *)argv);
|
||||||
@@ -10985,6 +11003,16 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
scope_idx = get_u16(pc) + ARG_SCOPE_END;
|
scope_idx = get_u16(pc) + ARG_SCOPE_END;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
sf->cur_pc = pc;
|
sf->cur_pc = pc;
|
||||||
|
/* Fast path: check arity before building arg list */
|
||||||
|
if (JS_VALUE_GET_TAG(sp[-2]) == JS_TAG_FUNCTION &&
|
||||||
|
JS_VALUE_GET_TAG(sp[-1]) == JS_TAG_ARRAY) {
|
||||||
|
JSFunction *callee = JS_VALUE_GET_FUNCTION(sp[-2]);
|
||||||
|
JSArray *arr = JS_VALUE_GET_ARRAY(sp[-1]);
|
||||||
|
if (unlikely(arr->len > callee->length)) {
|
||||||
|
JS_ThrowTypeError(ctx, "too many arguments");
|
||||||
|
goto exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
tab = build_arg_list(ctx, &len, sp[-1]);
|
tab = build_arg_list(ctx, &len, sp[-1]);
|
||||||
if (!tab)
|
if (!tab)
|
||||||
goto exception;
|
goto exception;
|
||||||
@@ -22070,7 +22098,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
JSFunctionDef *fd = s->cur_func;
|
JSFunctionDef *fd = s->cur_func;
|
||||||
BOOL is_expr;
|
BOOL is_expr;
|
||||||
int func_idx, lexical_func_idx = -1;
|
int func_idx, lexical_func_idx = -1;
|
||||||
BOOL has_opt_arg;
|
|
||||||
BOOL create_func_var = FALSE;
|
BOOL create_func_var = FALSE;
|
||||||
|
|
||||||
is_expr = (func_type != JS_PARSE_FUNC_STATEMENT &&
|
is_expr = (func_type != JS_PARSE_FUNC_STATEMENT &&
|
||||||
@@ -22154,7 +22181,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
/* parse arguments */
|
/* parse arguments */
|
||||||
fd->has_simple_parameter_list = TRUE;
|
fd->has_simple_parameter_list = TRUE;
|
||||||
fd->has_parameter_expressions = FALSE;
|
fd->has_parameter_expressions = FALSE;
|
||||||
has_opt_arg = FALSE;
|
|
||||||
if (func_type == JS_PARSE_FUNC_ARROW && s->token.val == TOK_IDENT) {
|
if (func_type == JS_PARSE_FUNC_ARROW && s->token.val == TOK_IDENT) {
|
||||||
JSAtom name;
|
JSAtom name;
|
||||||
if (s->token.u.ident.is_reserved) {
|
if (s->token.u.ident.is_reserved) {
|
||||||
@@ -22164,7 +22190,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
name = s->token.u.ident.atom;
|
name = s->token.u.ident.atom;
|
||||||
if (add_arg(ctx, fd, name) < 0)
|
if (add_arg(ctx, fd, name) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
fd->defined_arg_count = 1;
|
|
||||||
} else if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
} else if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||||
if (s->token.val == '(') {
|
if (s->token.val == '(') {
|
||||||
int skip_bits;
|
int skip_bits;
|
||||||
@@ -22199,10 +22224,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
has_initializer = js_parse_destructuring_element(s, TOK_VAR, 1, TRUE, TRUE, FALSE);
|
has_initializer = js_parse_destructuring_element(s, TOK_VAR, 1, TRUE, TRUE, FALSE);
|
||||||
if (has_initializer < 0)
|
if (has_initializer < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (has_initializer)
|
|
||||||
has_opt_arg = TRUE;
|
|
||||||
if (!has_opt_arg)
|
|
||||||
fd->defined_arg_count++;
|
|
||||||
} else if (s->token.val == TOK_IDENT) {
|
} else if (s->token.val == TOK_IDENT) {
|
||||||
if (s->token.u.ident.is_reserved) {
|
if (s->token.u.ident.is_reserved) {
|
||||||
js_parse_error_reserved_identifier(s);
|
js_parse_error_reserved_identifier(s);
|
||||||
@@ -22224,7 +22245,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
int label;
|
int label;
|
||||||
|
|
||||||
fd->has_simple_parameter_list = FALSE;
|
fd->has_simple_parameter_list = FALSE;
|
||||||
has_opt_arg = TRUE;
|
|
||||||
|
|
||||||
if (next_token(s))
|
if (next_token(s))
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -22248,9 +22268,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
emit_atom(s, name);
|
emit_atom(s, name);
|
||||||
emit_u16(s, fd->scope_level);
|
emit_u16(s, fd->scope_level);
|
||||||
} else {
|
} else {
|
||||||
if (!has_opt_arg) {
|
|
||||||
fd->defined_arg_count++;
|
|
||||||
}
|
|
||||||
if (fd->has_parameter_expressions) {
|
if (fd->has_parameter_expressions) {
|
||||||
/* copy the argument to the argument scope */
|
/* copy the argument to the argument scope */
|
||||||
emit_op(s, OP_get_arg);
|
emit_op(s, OP_get_arg);
|
||||||
@@ -22276,6 +22293,8 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Explicit arity: defined_arg_count == arg_count always */
|
||||||
|
fd->defined_arg_count = fd->arg_count;
|
||||||
|
|
||||||
if (fd->has_parameter_expressions) {
|
if (fd->has_parameter_expressions) {
|
||||||
int idx;
|
int idx;
|
||||||
@@ -24518,14 +24537,22 @@ static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
|
|||||||
JSValueConst this_arg, array_arg;
|
JSValueConst this_arg, array_arg;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
JSValue *tab, ret;
|
JSValue *tab, ret;
|
||||||
|
JSFunction *f;
|
||||||
|
|
||||||
if (check_function(ctx, this_val))
|
if (check_function(ctx, this_val))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
f = JS_VALUE_GET_FUNCTION(this_val);
|
||||||
this_arg = argv[0];
|
this_arg = argv[0];
|
||||||
array_arg = argv[1];
|
array_arg = argv[1];
|
||||||
if (JS_VALUE_GET_TAG(array_arg) == JS_TAG_NULL && magic != 2) {
|
if (JS_VALUE_GET_TAG(array_arg) == JS_TAG_NULL && magic != 2) {
|
||||||
return JS_Call(ctx, this_val, this_arg, 0, NULL);
|
return JS_Call(ctx, this_val, this_arg, 0, NULL);
|
||||||
}
|
}
|
||||||
|
/* Fast path: check arity before building arg list */
|
||||||
|
if (JS_VALUE_GET_TAG(array_arg) == JS_TAG_ARRAY) {
|
||||||
|
JSArray *arr = JS_VALUE_GET_ARRAY(array_arg);
|
||||||
|
if (unlikely(arr->len > f->length))
|
||||||
|
return JS_ThrowTypeError(ctx, "too many arguments");
|
||||||
|
}
|
||||||
tab = build_arg_list(ctx, &len, array_arg);
|
tab = build_arg_list(ctx, &len, array_arg);
|
||||||
if (!tab)
|
if (!tab)
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
@@ -27872,6 +27899,8 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (JS_IsFunction(ctx, argv[1])) {
|
if (JS_IsFunction(ctx, argv[1])) {
|
||||||
/* Map */
|
/* Map */
|
||||||
JSValueConst func = argv[1];
|
JSValueConst func = argv[1];
|
||||||
|
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
|
||||||
|
|
||||||
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
|
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
|
||||||
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
|
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
|
||||||
|
|
||||||
@@ -27886,10 +27915,15 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
|
|||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue val;
|
||||||
JSValue val = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity >= 2) {
|
||||||
JS_FreeValue(ctx, args[0]);
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
JS_FreeValue(ctx, args[1]);
|
val = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
} else {
|
||||||
|
val = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
}
|
||||||
|
JS_FreeValue(ctx, item);
|
||||||
if (JS_IsException(val)) {
|
if (JS_IsException(val)) {
|
||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
@@ -27908,10 +27942,15 @@ static JSValue js_cell_array(JSContext *ctx, JSValueConst this_val,
|
|||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue val;
|
||||||
JSValue val = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity >= 2) {
|
||||||
JS_FreeValue(ctx, args[0]);
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
JS_FreeValue(ctx, args[1]);
|
val = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
} else {
|
||||||
|
val = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
}
|
||||||
|
JS_FreeValue(ctx, item);
|
||||||
if (JS_IsException(val)) {
|
if (JS_IsException(val)) {
|
||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
@@ -28360,14 +28399,22 @@ static JSValue js_cell_array_for(JSContext *ctx, JSValueConst this_val,
|
|||||||
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
|
int reverse = argc > 2 && JS_ToBool(ctx, argv[2]);
|
||||||
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
|
JSValue exit_val = argc > 3 ? argv[3] : JS_NULL;
|
||||||
|
|
||||||
|
/* Determine function arity */
|
||||||
|
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
|
||||||
|
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
for (int64_t i = len - 1; i >= 0; i--) {
|
for (int64_t i = len - 1; i >= 0; i--) {
|
||||||
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
||||||
if (JS_IsException(item)) return JS_EXCEPTION;
|
if (JS_IsException(item)) return JS_EXCEPTION;
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue result;
|
||||||
JSValue result = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity == 1) {
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
} else {
|
||||||
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
}
|
||||||
JS_FreeValue(ctx, item);
|
JS_FreeValue(ctx, item);
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
if (JS_IsException(result)) return JS_EXCEPTION;
|
if (JS_IsException(result)) return JS_EXCEPTION;
|
||||||
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, result, exit_val)) {
|
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, result, exit_val)) {
|
||||||
return result;
|
return result;
|
||||||
@@ -28378,10 +28425,15 @@ static JSValue js_cell_array_for(JSContext *ctx, JSValueConst this_val,
|
|||||||
for (int64_t i = 0; i < len; i++) {
|
for (int64_t i = 0; i < len; i++) {
|
||||||
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
||||||
if (JS_IsException(item)) return JS_EXCEPTION;
|
if (JS_IsException(item)) return JS_EXCEPTION;
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue result;
|
||||||
JSValue result = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity == 1) {
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
} else {
|
||||||
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
}
|
||||||
JS_FreeValue(ctx, item);
|
JS_FreeValue(ctx, item);
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
if (JS_IsException(result)) return JS_EXCEPTION;
|
if (JS_IsException(result)) return JS_EXCEPTION;
|
||||||
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, result, exit_val)) {
|
if (!JS_IsNull(exit_val) && js_strict_eq(ctx, result, exit_val)) {
|
||||||
return result;
|
return result;
|
||||||
@@ -28443,14 +28495,21 @@ static JSValue js_cell_array_find(JSContext *ctx, JSValueConst this_val,
|
|||||||
|
|
||||||
/* Use function predicate */
|
/* Use function predicate */
|
||||||
JSValueConst func = argv[1];
|
JSValueConst func = argv[1];
|
||||||
|
int arity = (JSFunction*)JS_VALUE_GET_FUNCTION(argv[1])->length;
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
for (int64_t i = from; i >= 0; i--) {
|
for (int64_t i = from; i >= 0; i--) {
|
||||||
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
||||||
if (JS_IsException(item)) return JS_EXCEPTION;
|
if (JS_IsException(item)) return JS_EXCEPTION;
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue result;
|
||||||
JSValue result = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity == 2) {
|
||||||
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
} else {
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
}
|
||||||
JS_FreeValue(ctx, item);
|
JS_FreeValue(ctx, item);
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
if (JS_IsException(result)) return JS_EXCEPTION;
|
if (JS_IsException(result)) return JS_EXCEPTION;
|
||||||
if (JS_ToBool(ctx, result)) {
|
if (JS_ToBool(ctx, result)) {
|
||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
@@ -28462,10 +28521,16 @@ static JSValue js_cell_array_find(JSContext *ctx, JSValueConst this_val,
|
|||||||
for (int64_t i = from; i < len; i++) {
|
for (int64_t i = from; i < len; i++) {
|
||||||
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
||||||
if (JS_IsException(item)) return JS_EXCEPTION;
|
if (JS_IsException(item)) return JS_EXCEPTION;
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue result;
|
||||||
JSValue result = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity == 2) {
|
||||||
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
} else {
|
||||||
|
result = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
}
|
||||||
JS_FreeValue(ctx, item);
|
JS_FreeValue(ctx, item);
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
if (JS_IsException(result)) return JS_EXCEPTION;
|
if (JS_IsException(result)) return JS_EXCEPTION;
|
||||||
if (JS_ToBool(ctx, result)) {
|
if (JS_ToBool(ctx, result)) {
|
||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
@@ -28495,6 +28560,8 @@ static JSValue js_cell_array_filter(JSContext *ctx, JSValueConst this_val,
|
|||||||
JSValue result = JS_NewArray(ctx);
|
JSValue result = JS_NewArray(ctx);
|
||||||
if (JS_IsException(result)) return result;
|
if (JS_IsException(result)) return result;
|
||||||
|
|
||||||
|
int arity = ((JSFunction*)JS_VALUE_GET_FUNCTION(func))->length;
|
||||||
|
|
||||||
int64_t out_idx = 0;
|
int64_t out_idx = 0;
|
||||||
for (int64_t i = 0; i < len; i++) {
|
for (int64_t i = 0; i < len; i++) {
|
||||||
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
JSValue item = JS_GetPropertyInt64(ctx, arr, i);
|
||||||
@@ -28502,9 +28569,16 @@ static JSValue js_cell_array_filter(JSContext *ctx, JSValueConst this_val,
|
|||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
JSValue val;
|
||||||
JSValue val = JS_Call(ctx, func, JS_NULL, 2, args);
|
if (arity == 0) {
|
||||||
JS_FreeValue(ctx, args[1]);
|
val = JS_Call(ctx, func, JS_NULL, 0, NULL);
|
||||||
|
} else if (arity == 1) {
|
||||||
|
val = JS_Call(ctx, func, JS_NULL, 1, &item);
|
||||||
|
} else {
|
||||||
|
JSValue args[2] = { item, JS_NewInt64(ctx, i) };
|
||||||
|
val = JS_Call(ctx, func, JS_NULL, 2, args);
|
||||||
|
JS_FreeValue(ctx, args[1]);
|
||||||
|
}
|
||||||
if (JS_IsException(val)) {
|
if (JS_IsException(val)) {
|
||||||
JS_FreeValue(ctx, item);
|
JS_FreeValue(ctx, item);
|
||||||
JS_FreeValue(ctx, result);
|
JS_FreeValue(ctx, result);
|
||||||
@@ -28848,7 +28922,7 @@ static JSValue js_cell_object(JSContext *ctx, JSValueConst this_val,
|
|||||||
* fn function and sub-functions
|
* fn function and sub-functions
|
||||||
* ---------------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* fn.apply(func, args) */
|
/* fn.apply(func, args) - arity is enforced in JS_CallInternal */
|
||||||
static JSValue js_cell_fn_apply(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_cell_fn_apply(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
@@ -28871,19 +28945,6 @@ static JSValue js_cell_fn_apply(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (js_get_length64(ctx, &len, args_val))
|
if (js_get_length64(ctx, &len, args_val))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
/* Check arity */
|
|
||||||
JSValue func_len = JS_GetPropertyStr(ctx, func, "length");
|
|
||||||
if (!JS_IsException(func_len)) {
|
|
||||||
int arity;
|
|
||||||
if (!JS_ToInt32(ctx, &arity, func_len)) {
|
|
||||||
if (len > arity) {
|
|
||||||
JS_FreeValue(ctx, func_len);
|
|
||||||
return JS_ThrowTypeError(ctx, "fn.apply: too many arguments");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JS_FreeValue(ctx, func_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue *args = js_malloc(ctx, sizeof(JSValue) * (len > 0 ? len : 1));
|
JSValue *args = js_malloc(ctx, sizeof(JSValue) * (len > 0 ? len : 1));
|
||||||
if (!args) return JS_EXCEPTION;
|
if (!args) return JS_EXCEPTION;
|
||||||
|
|
||||||
@@ -29221,22 +29282,22 @@ static JSValue js_blob_w32(JSContext *ctx, JSValueConst this_val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* blob.wf(value) - write float */
|
/* blob.wf(value) - write float */
|
||||||
static JSValue js_blob_wf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
|
static JSValue js_blob_wf(JSContext *ctx, JSValueConst this_val, JSValueConst arg0)
|
||||||
{
|
{
|
||||||
if (argc < 1) return JS_ThrowTypeError(ctx, "wf(value) requires 1 argument");
|
if (JS_IsNull(arg0)) return JS_ThrowTypeError(ctx, "wf(value) requires 1 argument");
|
||||||
|
|
||||||
blob *bd = js_get_blob(ctx, this_val);
|
blob *bd = js_get_blob(ctx, this_val);
|
||||||
if (!bd) return JS_ThrowTypeError(ctx, "wf: not called on a blob");
|
if (!bd) return JS_ThrowTypeError(ctx, "wf: not called on a blob");
|
||||||
|
|
||||||
float f;
|
float f;
|
||||||
int tag = JS_VALUE_GET_TAG(argv[0]);
|
int tag = JS_VALUE_GET_TAG(arg0);
|
||||||
if (tag == JS_TAG_INT) {
|
if (tag == JS_TAG_INT) {
|
||||||
f = (float)JS_VALUE_GET_INT(argv[0]);
|
f = (float)JS_VALUE_GET_INT(arg0);
|
||||||
} else if (tag == JS_TAG_FLOAT64) {
|
} else if (tag == JS_TAG_FLOAT64) {
|
||||||
f = (float)JS_VALUE_GET_FLOAT64(argv[0]);
|
f = (float)JS_VALUE_GET_FLOAT64(arg0);
|
||||||
} else {
|
} else {
|
||||||
double d;
|
double d;
|
||||||
if (JS_ToFloat64(ctx, &d, argv[0]) < 0) return JS_EXCEPTION;
|
if (JS_ToFloat64(ctx, &d, arg0) < 0) return JS_EXCEPTION;
|
||||||
f = (float)d;
|
f = (float)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29409,7 +29470,7 @@ static const JSCFunctionListEntry js_blob_proto_funcs[] = {
|
|||||||
JS_CFUNC_DEF("write_fit", 2, js_blob_write_fit),
|
JS_CFUNC_DEF("write_fit", 2, js_blob_write_fit),
|
||||||
JS_CFUNC_DEF("write_text", 1, js_blob_write_text),
|
JS_CFUNC_DEF("write_text", 1, js_blob_write_text),
|
||||||
JS_CFUNC_DEF("write_pad", 1, js_blob_write_pad),
|
JS_CFUNC_DEF("write_pad", 1, js_blob_write_pad),
|
||||||
JS_CFUNC_DEF("wf", 1, js_blob_wf),
|
JS_CFUNC1_DEF("wf", js_blob_wf),
|
||||||
JS_CFUNC_DEF("w16", 1, js_blob_w16),
|
JS_CFUNC_DEF("w16", 1, js_blob_w16),
|
||||||
JS_CFUNC_DEF("w32", 1, js_blob_w32),
|
JS_CFUNC_DEF("w32", 1, js_blob_w32),
|
||||||
|
|
||||||
@@ -29922,7 +29983,7 @@ static JSValue js_cell_length(JSContext *ctx, JSValueConst this_val,
|
|||||||
* call() function - call a function with explicit this and arguments
|
* call() function - call a function with explicit this and arguments
|
||||||
* ============================================================================ */
|
* ============================================================================ */
|
||||||
|
|
||||||
/* call(func, this_val, ...args) */
|
/* call(func, this_val, args_array) */
|
||||||
static JSValue js_cell_call(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_cell_call(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
@@ -29937,10 +29998,20 @@ static JSValue js_cell_call(JSContext *ctx, JSValueConst this_val,
|
|||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
this_arg = argv[1];
|
this_arg = argv[1];
|
||||||
|
|
||||||
int call_argc = argc > 2 ? argc - 2 : 0;
|
if (argc < 3 || JS_IsNull(argv[2]))
|
||||||
JSValueConst *call_argv = call_argc > 0 ? &argv[2] : NULL;
|
return JS_Call(ctx, func, this_arg, 0, NULL);
|
||||||
|
|
||||||
return JS_Call(ctx, func, this_arg, call_argc, call_argv);
|
if (!JS_IsArray(ctx, argv[2]))
|
||||||
|
return JS_ThrowTypeError(ctx, "third argument must be an array");
|
||||||
|
|
||||||
|
uint32_t len;
|
||||||
|
JSValue *tab = build_arg_list(ctx, &len, argv[2]);
|
||||||
|
if (!tab)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
|
JSValue ret = JS_Call(ctx, func, this_arg, len, (JSValueConst *)tab);
|
||||||
|
free_arg_list(ctx, tab, len);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
@@ -30199,7 +30270,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
|
|||||||
|
|
||||||
/* Cell Script global functions: text, number, array, object, fn */
|
/* Cell Script global functions: text, number, array, object, fn */
|
||||||
{
|
{
|
||||||
JSValue text_func = JS_NewCFunction(ctx, js_cell_text, "text", 2);
|
JSValue text_func = JS_NewCFunction(ctx, js_cell_text, "text", 3);
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "text", text_func);
|
JS_SetPropertyStr(ctx, ctx->global_obj, "text", text_func);
|
||||||
|
|
||||||
JSValue number_func = JS_NewCFunction(ctx, js_cell_number, "number", 2);
|
JSValue number_func = JS_NewCFunction(ctx, js_cell_number, "number", 2);
|
||||||
@@ -30267,7 +30338,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
|
|||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "apply",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "apply",
|
||||||
JS_NewCFunction(ctx, js_cell_fn_apply, "apply", 2));
|
JS_NewCFunction(ctx, js_cell_fn_apply, "apply", 2));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "replace",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "replace",
|
||||||
JS_NewCFunction(ctx, js_cell_text_replace, "replace", 2));
|
JS_NewCFunction(ctx, js_cell_text_replace, "replace", 4));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "lower",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "lower",
|
||||||
JS_NewCFunction(ctx, js_cell_text_lower, "lower", 1));
|
JS_NewCFunction(ctx, js_cell_text_lower, "lower", 1));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "upper",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "upper",
|
||||||
@@ -30279,7 +30350,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
|
|||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "search",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "search",
|
||||||
JS_NewCFunction(ctx, js_cell_text_search, "search", 3));
|
JS_NewCFunction(ctx, js_cell_text_search, "search", 3));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "extract",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "extract",
|
||||||
JS_NewCFunction(ctx, js_cell_text_extract, "extract", 3));
|
JS_NewCFunction(ctx, js_cell_text_extract, "extract", 4));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "reduce",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "reduce",
|
||||||
JS_NewCFunction(ctx, js_cell_array_reduce, "reduce", 4));
|
JS_NewCFunction(ctx, js_cell_array_reduce, "reduce", 4));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "arrfor",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "arrfor",
|
||||||
@@ -30309,9 +30380,9 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
|
|||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "trunc",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "trunc",
|
||||||
JS_NewCFunction(ctx, js_cell_number_trunc, "trunc", 2));
|
JS_NewCFunction(ctx, js_cell_number_trunc, "trunc", 2));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "min",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "min",
|
||||||
JS_NewCFunction(ctx, js_cell_number_min, "min", 0));
|
JS_NewCFunction(ctx, js_cell_number_min, "min", 2));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "max",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "max",
|
||||||
JS_NewCFunction(ctx, js_cell_number_max, "max", 0));
|
JS_NewCFunction(ctx, js_cell_number_max, "max", 2));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "remainder",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "remainder",
|
||||||
JS_NewCFunction(ctx, js_cell_number_remainder, "remainder", 2));
|
JS_NewCFunction(ctx, js_cell_number_remainder, "remainder", 2));
|
||||||
JS_SetPropertyStr(ctx, ctx->global_obj, "character",
|
JS_SetPropertyStr(ctx, ctx->global_obj, "character",
|
||||||
|
|||||||
@@ -746,13 +746,32 @@ typedef enum JSCFunctionEnum {
|
|||||||
JS_CFUNC_generic_magic,
|
JS_CFUNC_generic_magic,
|
||||||
JS_CFUNC_f_f,
|
JS_CFUNC_f_f,
|
||||||
JS_CFUNC_f_f_f,
|
JS_CFUNC_f_f_f,
|
||||||
|
/* Fixed-arity fast paths - no argc/argv overhead */
|
||||||
|
JS_CFUNC_0, /* JSValue f(ctx, this_val) */
|
||||||
|
JS_CFUNC_1, /* JSValue f(ctx, this_val, arg0) */
|
||||||
|
JS_CFUNC_2, /* JSValue f(ctx, this_val, arg0, arg1) */
|
||||||
|
JS_CFUNC_3, /* JSValue f(ctx, this_val, arg0, arg1, arg2) */
|
||||||
|
JS_CFUNC_4
|
||||||
} JSCFunctionEnum;
|
} JSCFunctionEnum;
|
||||||
|
|
||||||
|
/* Fixed-arity C function types for fast paths */
|
||||||
|
typedef JSValue JSCFunction0(JSContext *ctx, JSValueConst this_val);
|
||||||
|
typedef JSValue JSCFunction1(JSContext *ctx, JSValueConst this_val, JSValueConst arg0);
|
||||||
|
typedef JSValue JSCFunction2(JSContext *ctx, JSValueConst this_val, JSValueConst arg0, JSValueConst arg1);
|
||||||
|
typedef JSValue JSCFunction3(JSContext *ctx, JSValueConst this_val, JSValueConst arg0, JSValueConst arg1, JSValueConst arg2);
|
||||||
|
typedef JSValue JSCFunction4(JSContext *ctx, JSValueConst this_val, JSValueConst arg0, JSValueConst arg1, JSValueConst arg2, JSValueConst arg3);
|
||||||
|
|
||||||
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);
|
||||||
double (*f_f)(double);
|
double (*f_f)(double);
|
||||||
double (*f_f_f)(double, double);
|
double (*f_f_f)(double, double);
|
||||||
|
/* Fixed-arity fast paths */
|
||||||
|
JSCFunction0 *f0;
|
||||||
|
JSCFunction1 *f1;
|
||||||
|
JSCFunction2 *f2;
|
||||||
|
JSCFunction3 *f3;
|
||||||
|
JSCFunction4 *f4;
|
||||||
} JSCFunctionType;
|
} JSCFunctionType;
|
||||||
|
|
||||||
JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
|
JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
|
||||||
@@ -775,6 +794,32 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fixed-arity fast path constructors */
|
||||||
|
static inline JSValue JS_NewCFuncFixed0(JSContext *ctx, JSCFunction0 *func, const char *name)
|
||||||
|
{
|
||||||
|
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, 0, JS_CFUNC_0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline JSValue JS_NewCFuncFixed1(JSContext *ctx, JSCFunction1 *func, const char *name)
|
||||||
|
{
|
||||||
|
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, 1, JS_CFUNC_1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline JSValue JS_NewCFuncFixed2(JSContext *ctx, JSCFunction2 *func, const char *name)
|
||||||
|
{
|
||||||
|
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, 2, JS_CFUNC_2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline JSValue JS_NewCFuncFixed3(JSContext *ctx, JSCFunction3 *func, const char *name)
|
||||||
|
{
|
||||||
|
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, 3, JS_CFUNC_3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline JSValue JS_NewCFuncFixed4(JSContext *ctx, JSCFunction4 *func, const char *name)
|
||||||
|
{
|
||||||
|
return JS_NewCFunction2(ctx, (JSCFunction *)func, name, 4, JS_CFUNC_4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* C property definition */
|
/* C property definition */
|
||||||
|
|
||||||
typedef struct JSCFunctionListEntry {
|
typedef struct JSCFunctionListEntry {
|
||||||
@@ -816,6 +861,11 @@ typedef struct JSCFunctionListEntry {
|
|||||||
#define JS_CFUNC_DEF(name, length, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
|
#define JS_CFUNC_DEF(name, length, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
|
||||||
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, 0, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
|
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, 0, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
|
||||||
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
|
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
|
||||||
|
/* Fixed-arity fast path macros */
|
||||||
|
#define JS_CFUNC0_DEF(name, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { 0, JS_CFUNC_0, { .f0 = func1 } } } }
|
||||||
|
#define JS_CFUNC1_DEF(name, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { 1, JS_CFUNC_1, { .f1 = func1 } } } }
|
||||||
|
#define JS_CFUNC2_DEF(name, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { 2, JS_CFUNC_2, { .f2 = func1 } } } }
|
||||||
|
#define JS_CFUNC3_DEF(name, func1) { name, 0, JS_DEF_CFUNC, 0, .u = { .func = { 3, JS_CFUNC_3, { .f3 = func1 } } } }
|
||||||
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, 0, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
|
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, 0, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
|
||||||
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
|
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
|
||||||
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
|
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
|
||||||
|
|||||||
Reference in New Issue
Block a user