all compilation is strict

This commit is contained in:
2025-06-18 16:37:55 -05:00
parent 4689ea1167
commit 3d5f345236
5 changed files with 107 additions and 236 deletions

View File

@@ -770,7 +770,7 @@ void script_startup(cell_rt *prt)
data[stat.filesize] = 0;
prt->state = ACTOR_RUNNING;
JSValue v = JS_Eval(js, data, (size_t)stat.filesize, ENGINE, JS_EVAL_FLAG_STRICT);
JSValue v = JS_Eval(js, data, (size_t)stat.filesize, ENGINE, 0);
uncaught_exception(js, v);
prt->state = ACTOR_IDLE;
set_actor_state(prt);
@@ -923,7 +923,7 @@ int main(int argc, char **argv)
ffi_load(js);
/* Execute the script */
JSValue result = JS_Eval(js, script, size, argv[2], JS_EVAL_FLAG_STRICT);
JSValue result = JS_Eval(js, script, size, argv[2], 0);
free(script);
/* Check for exceptions */

View File

@@ -1646,7 +1646,7 @@ void ffi_load(JSContext *js)
const char actorsym_script[] = "var sym = Symbol(`actordata`); sym;";
JSValue actorsym = JS_Eval(js, actorsym_script, sizeof(actorsym_script)-1, "internal", JS_EVAL_FLAG_STRICT);
JSValue actorsym = JS_Eval(js, actorsym_script, sizeof(actorsym_script)-1, "internal", 0);
JS_SetPropertyStr(js, hidden_fn, "actorsym", actorsym);

View File

@@ -39,11 +39,11 @@ JSC_CCALL(os_calc_mem,
)
JSC_SSCALL(os_eval,
ret = JS_Eval(js,str2,strlen(str2),str, JS_EVAL_FLAG_STRICT);
ret = JS_Eval(js,str2,strlen(str2),str, 0);
)
JSC_SSCALL(js_compile,
ret = JS_Eval(js, str2, strlen(str2), str, JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_COMPILE_ONLY);
ret = JS_Eval(js, str2, strlen(str2), str, JS_EVAL_FLAG_COMPILE_ONLY);
)
JSC_CCALL(js_eval_compile,

View File

@@ -253,7 +253,6 @@ struct JSClass {
const JSClassExoticMethods *exotic;
};
#define JS_MODE_STRICT (1 << 0)
#define JS_MODE_BACKTRACE_BARRIER (1 << 3) /* stop backtrace before this frame */
typedef struct JSStackFrame {
@@ -1795,12 +1794,6 @@ void JS_UpdateStackTop(JSRuntime *rt)
update_stack_limit(rt);
}
static inline BOOL is_strict_mode(JSContext *ctx)
{
JSStackFrame *sf = ctx->rt->current_stack_frame;
return (sf && (sf->js_mode & JS_MODE_STRICT));
}
/* JSAtom support */
#define JS_ATOM_TAG_INT (1U << 31)
@@ -6205,8 +6198,8 @@ static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSCont
{
va_list ap;
if ((flags & JS_PROP_THROW) ||
((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) {
if (flags & JS_PROP_THROW ||
flags & JS_PROP_THROW_STRICT) {
va_start(ap, fmt);
JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap);
va_end(ap);
@@ -6239,8 +6232,8 @@ static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowSyntaxErrorAtom(J
static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom)
{
if ((flags & JS_PROP_THROW) ||
((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) {
if (flags & JS_PROP_THROW ||
flags & JS_PROP_THROW_STRICT) {
JS_ThrowTypeErrorAtom(ctx, "'%s' is read-only", atom);
return -1;
} else {
@@ -6302,11 +6295,6 @@ static JSValue JS_ThrowTypeErrorNotAnObject(JSContext *ctx)
return JS_ThrowTypeError(ctx, "not an object");
}
static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx)
{
return JS_ThrowTypeError(ctx, "not a symbol");
}
static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name)
{
char buf[ATOM_GET_STR_BUF_SIZE];
@@ -7559,8 +7547,8 @@ static int call_setter(JSContext *ctx, JSObject *setter,
return TRUE;
} else {
JS_FreeValue(ctx, val);
if ((flags & JS_PROP_THROW) ||
((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) {
if (flags & JS_PROP_THROW ||
flags & JS_PROP_THROW_STRICT) {
JS_ThrowTypeError(ctx, "no setter for property");
return -1;
}
@@ -8874,9 +8862,7 @@ static int JS_SetGlobalVar(JSContext *ctx, JSAtom prop, JSValue val,
/* XXX: add a fast path where the property exists and the object
is not exotic. Otherwise do as in OP_put_ref_value and remove
JS_PROP_NO_ADD which is no longer necessary */
flags = JS_PROP_THROW_STRICT;
if (is_strict_mode(ctx))
flags |= JS_PROP_NO_ADD;
flags = JS_PROP_THROW_STRICT | JS_PROP_NO_ADD;
return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, ctx->global_obj, flags);
}
@@ -8920,8 +8906,8 @@ int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags)
JS_FreeValue(ctx, obj1);
if (res != FALSE)
return res;
if ((flags & JS_PROP_THROW) ||
((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) {
if (flags & JS_PROP_THROW ||
flags & JS_PROP_THROW_STRICT) {
JS_ThrowTypeError(ctx, "could not delete property");
return -1;
}
@@ -11402,12 +11388,8 @@ static __exception int js_operator_delete(JSContext *ctx, JSValue *sp)
static JSValue js_throw_type_error(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSFunctionBytecode *b = JS_GetFunctionBytecode(this_val);
if (!b || (b->js_mode & JS_MODE_STRICT) || !b->has_prototype || argc >= 1) {
return JS_ThrowTypeError(ctx, "invalid property access");
}
return JS_NULL;
}
static JSValue js_function_proto_fileName(JSContext *ctx,
JSValueConst this_val)
@@ -12763,22 +12745,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_push_this):
/* OP_push_this is only called at the start of a function */
{
JSValue val;
if (!(b->js_mode & JS_MODE_STRICT)) {
uint32_t tag = JS_VALUE_GET_TAG(this_obj);
if (likely(tag == JS_TAG_OBJECT))
goto normal_this;
if (tag == JS_TAG_NULL) {
val = JS_DupValue(ctx, ctx->global_obj);
} else {
val = JS_ToObject(ctx, this_obj);
if (JS_IsException(val))
goto exception;
}
} else {
normal_this:
val = JS_DupValue(ctx, this_obj);
}
JSValue val = JS_DupValue(ctx, this_obj);
*sp++ = val;
}
BREAK;
@@ -14097,11 +14064,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JS_FreeAtom(ctx, atom);
goto exception;
}
if (is_strict_mode(ctx)) {
JS_ThrowReferenceErrorNotDefined(ctx, atom);
JS_FreeAtom(ctx, atom);
goto exception;
}
val = JS_NULL;
} else {
val = JS_GetProperty(ctx, sp[-2], atom);
@@ -14136,13 +14101,9 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
if (unlikely(atom == JS_ATOM_NULL))
goto exception;
if (unlikely(JS_IsNull(sp[-3]))) {
if (is_strict_mode(ctx)) {
JS_ThrowReferenceErrorNotDefined(ctx, atom);
JS_FreeAtom(ctx, atom);
goto exception;
} else {
sp[-3] = JS_DupValue(ctx, ctx->global_obj);
}
}
ret = JS_HasProperty(ctx, sp[-3], atom);
if (unlikely(ret <= 0)) {
@@ -14150,12 +14111,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JS_FreeAtom(ctx, atom);
goto exception;
}
if (is_strict_mode(ctx)) {
JS_ThrowReferenceErrorNotDefined(ctx, atom);
JS_FreeAtom(ctx, atom);
goto exception;
}
}
ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-3], JS_PROP_THROW_STRICT);
JS_FreeAtom(ctx, atom);
JS_FreeValue(ctx, sp[-2]);
@@ -15716,8 +15675,6 @@ static __exception int js_parse_string(JSParseState *s, int sep,
continue;
default:
if (c >= '0' && c <= '9') {
if (!(s->cur_func->js_mode & JS_MODE_STRICT) && sep != '`')
goto parse_escape;
if (c == '0' && !(p[1] >= '0' && p[1] <= '9')) {
p++;
c = '\0';
@@ -15935,9 +15892,7 @@ static void update_token_ident(JSParseState *s)
{
JSAtom atom = s->token.u.ident.atom;
/* if its a (strict-mode) keyword, convert it */
if(atom <= JS_ATOM_LAST_KEYWORD ||
(atom <= JS_ATOM_LAST_STRICT_KEYWORD &&
(s->cur_func->js_mode & JS_MODE_STRICT))) {
if(atom <= JS_ATOM_LAST_STRICT_KEYWORD) {
if(s->token.u.ident.has_escape) {
/* identifiers with escape sequences stay identifiers */
s->token.u.ident.is_reserved = TRUE;
@@ -16177,8 +16132,8 @@ static __exception int next_token(JSParseState *s)
break;
case '0':
/* in strict mode, octal literals are not accepted */
if (is_digit(p[1]) && (s->cur_func->js_mode & JS_MODE_STRICT)) {
js_parse_error(s, "octal literals are deprecated in strict mode");
if (is_digit(p[1])) {
js_parse_error(s, "octal literals are not allowed");
goto fail;
}
goto parse_number;
@@ -17105,21 +17060,6 @@ static int find_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name)
return find_arg(ctx, fd, name);
}
/* find a variable declaration in a given scope */
static int find_var_in_scope(JSContext *ctx, JSFunctionDef *fd,
JSAtom name, int scope_level)
{
int scope_idx;
for(scope_idx = fd->scopes[scope_level].first; scope_idx >= 0;
scope_idx = fd->vars[scope_idx].scope_next) {
if (fd->vars[scope_idx].scope_level != scope_level)
break;
if (fd->vars[scope_idx].var_name == name)
return scope_idx;
}
return -1;
}
/* return true if scope == parent_scope or if scope is a child of
parent_scope */
static BOOL is_child_scope(JSContext *ctx, JSFunctionDef *fd,
@@ -17298,13 +17238,11 @@ static int add_func_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name)
if (idx < 0 && (idx = add_var(ctx, fd, name)) >= 0) {
fd->func_var_idx = idx;
fd->vars[idx].var_kind = JS_VAR_FUNCTION_NAME;
if (fd->js_mode & JS_MODE_STRICT)
fd->vars[idx].is_const = TRUE;
}
return idx;
}
static int add_arg(JSContext *ctx, JSFunctionDef *fd, JSAtom name)
{
JSVarDef *vd;
@@ -17374,20 +17312,14 @@ static int define_var(JSParseState *s, JSFunctionDef *fd, JSAtom name,
if (idx >= 0) {
if (idx < GLOBAL_VAR_OFFSET) {
if (fd->vars[idx].scope_level == fd->scope_level) {
/* same scope: in non strict mode, functions
can be redefined (annex B.3.3.4). */
if (!(!(fd->js_mode & JS_MODE_STRICT) &&
var_def_type == JS_VAR_DEF_FUNCTION_DECL &&
fd->vars[idx].var_kind == JS_VAR_FUNCTION_DECL)) {
goto redef_lex_error;
}
} else if (fd->vars[idx].var_kind == JS_VAR_CATCH && (fd->vars[idx].scope_level + 2) == fd->scope_level) {
} else if (fd->vars[idx].var_kind == JS_VAR_CATCH &&
(fd->vars[idx].scope_level + 2) == fd->scope_level) {
goto redef_lex_error;
}
} else {
if (fd->scope_level == fd->body_scope) {
redef_lex_error:
/* redefining a scoped var in the same scope: error */
return js_parse_error(s, "invalid redefinition of lexical identifier");
}
}
@@ -18249,7 +18181,7 @@ static __exception int get_lvalue(JSParseState *s, int *popcode, int *pscope,
case OP_scope_get_var:
name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1);
scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5);
if (name == JS_ATOM_eval && (fd->js_mode & JS_MODE_STRICT)) {
if (name == JS_ATOM_eval) {
return js_parse_error(s, "invalid lvalue in strict mode");
}
if (name == JS_ATOM_this || name == JS_ATOM_new_target)
@@ -18444,7 +18376,7 @@ static __exception int js_define_var(JSParseState *s, JSAtom name, int tok)
JSFunctionDef *fd = s->cur_func;
JSVarDefEnum var_def_type;
if (name == JS_ATOM_eval && (fd->js_mode & JS_MODE_STRICT)) {
if (name == JS_ATOM_eval) {
return js_parse_error(s, "invalid variable name in strict mode");
}
if (name == JS_ATOM_let
@@ -18527,10 +18459,9 @@ static BOOL need_var_reference(JSParseState *s, int tok)
JSFunctionDef *fd = s->cur_func;
if (tok != TOK_VAR)
return FALSE; /* no reference for let/const */
if (fd->js_mode & JS_MODE_STRICT) {
if (!fd->is_global_var)
return FALSE; /* local definitions in strict mode in function or direct eval */
}
return TRUE;
}
@@ -18539,8 +18470,7 @@ static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg)
JSAtom name;
if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)
|| ((s->cur_func->js_mode & JS_MODE_STRICT) &&
(s->token.u.ident.atom == JS_ATOM_eval))) {
|| s->token.u.ident.atom == JS_ATOM_eval) {
js_parse_error(s, "invalid destructuring target");
return JS_ATOM_NULL;
}
@@ -18788,8 +18718,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
/* prop_type = PROP_TYPE_VAR, cannot be a computed property */
if (is_arg && js_parse_check_duplicate_parameter(s, prop_name))
goto prop_error;
if ((s->cur_func->js_mode & JS_MODE_STRICT) &&
(prop_name == JS_ATOM_eval)) {
if (prop_name == JS_ATOM_eval) {
js_parse_error(s, "invalid destructuring target");
goto prop_error;
}
@@ -19602,11 +19531,8 @@ static __exception int js_parse_delete(JSParseState *s)
name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1);
if (name == JS_ATOM_this || name == JS_ATOM_new_target)
goto ret_true;
if (fd->js_mode & JS_MODE_STRICT) {
return js_parse_error(s, "cannot delete a direct reference in strict mode");
} else {
fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_delete_var;
}
break;
default:
ret_true:
@@ -20540,8 +20466,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name)
goto initializer_error;
} else if (s->token.val == TOK_IN) {
if (has_initializer &&
(tok != TOK_VAR || (fd->js_mode & JS_MODE_STRICT) ||
has_destructuring)) {
(tok != TOK_VAR || has_destructuring)) {
initializer_error:
return js_parse_error(s, "a declaration in the head of a for-%s loop can't have an initializer",
is_for_of ? "of" : "in");
@@ -20668,12 +20593,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
push_break_entry(s->cur_func, &break_entry,
label_name, label_break, -1, 0);
break_entry.is_regular_stmt = TRUE;
if (!(s->cur_func->js_mode & JS_MODE_STRICT) &&
(decl_mask & DECL_MASK_FUNC_WITH_LABEL)) {
mask = DECL_MASK_FUNC | DECL_MASK_FUNC_WITH_LABEL;
} else {
mask = 0;
}
if (js_parse_statement_or_decl(s, mask))
goto fail;
emit_label(s, label_break);
@@ -20755,10 +20675,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
if (js_parse_expr_paren(s))
goto fail;
label1 = emit_goto(s, OP_if_false, -1);
if (s->cur_func->js_mode & JS_MODE_STRICT)
mask = 0;
else
mask = DECL_MASK_FUNC; /* Annex B.3.4 */
if (js_parse_statement_or_decl(s, mask))
goto fail;
@@ -21896,7 +21813,6 @@ static __maybe_unused void js_dump_function_bytecode(JSContext *ctx, JSFunctionB
printf("function: %s%s\n", "", str);
if (b->js_mode) {
printf(" mode:");
if (b->js_mode & JS_MODE_STRICT)
printf(" strict");
printf("\n");
}
@@ -22092,20 +22008,15 @@ static int optimize_scope_make_global_ref(JSContext *ctx, JSFunctionDef *s,
JSAtom var_name)
{
int label_pos, end_pos, pos, op;
BOOL is_strict;
is_strict = ((s->js_mode & JS_MODE_STRICT) != 0);
/* replace the reference get/put with normal variable
accesses */
if (is_strict) {
/* need to check if the variable exists before evaluating the right
expression */
/* XXX: need an extra OP_true if destructuring an array */
dbuf_putc(bc, OP_check_var);
dbuf_put_u32(bc, JS_DupAtom(ctx, var_name));
} else {
/* XXX: need 2 extra OP_true if destructuring an array */
}
if (bc_buf[pos_next] == OP_get_ref_value) {
dbuf_putc(bc, OP_get_var);
dbuf_put_u32(bc, JS_DupAtom(ctx, var_name));
@@ -22119,7 +22030,6 @@ static int optimize_scope_make_global_ref(JSContext *ctx, JSFunctionDef *s,
assert(bc_buf[pos] == OP_label);
end_pos = label_pos + 2;
op = bc_buf[label_pos];
if (is_strict) {
if (op != OP_nop) {
switch(op) {
case OP_insert3:
@@ -22136,17 +22046,10 @@ static int optimize_scope_make_global_ref(JSContext *ctx, JSFunctionDef *s,
}
bc_buf[pos++] = op;
}
} else {
if (op == OP_insert3)
bc_buf[pos++] = OP_dup;
}
if (is_strict) {
bc_buf[pos] = OP_put_var_strict;
/* XXX: need 1 extra OP_drop if destructuring an array */
} else {
bc_buf[pos] = OP_put_var;
/* XXX: need 2 extra OP_drop if destructuring an array */
}
put_u32(bc_buf + pos + 1, JS_DupAtom(ctx, var_name));
pos += 5;
/* pad with OP_nop */
@@ -22657,18 +22560,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s)
int i, scope_level, scope_idx;
BOOL has_this_binding, is_arg_scope;
/* in non strict mode, variables are created in the caller's
environment object */
if (!s->is_eval && !(s->js_mode & JS_MODE_STRICT)) {
s->var_object_idx = add_var(ctx, s, JS_ATOM__var_);
if (s->has_parameter_expressions) {
/* an additional variable object is needed for the
argument scope */
s->arg_var_object_idx = add_var(ctx, s, JS_ATOM__arg_var_);
}
}
/* eval can potentially use 'arguments' so we must define it */
has_this_binding = s->has_this_binding;
if (has_this_binding) {
if (s->this_var_idx < 0)
@@ -25136,10 +25027,6 @@ static __exception int js_parse_directives(JSParseState *s)
}
if (!has_semi)
break;
if (!strcmp(str, "use strict")) {
s->cur_func->has_use_strict = TRUE;
s->cur_func->js_mode |= JS_MODE_STRICT;
}
}
return js_parse_seek_token(s, &pos);
}
@@ -25156,7 +25043,6 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd,
JSAtom name;
int i, idx;
if (fd->js_mode & JS_MODE_STRICT) {
if (!fd->has_simple_parameter_list && fd->has_use_strict) {
return js_parse_error(s, "\"use strict\" not allowed in function with default or destructuring parameter");
}
@@ -25170,12 +25056,7 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd,
return js_parse_error(s, "invalid argument name in strict code");
}
}
}
/* check async_generator case */
if ((fd->js_mode & JS_MODE_STRICT)
|| !fd->has_simple_parameter_list
|| fd->func_type == JS_PARSE_FUNC_ARROW
|| fd->func_type == JS_PARSE_FUNC_METHOD) {
for (idx = 0; idx < fd->arg_count; idx++) {
name = fd->args[idx].var_name;
if (name != JS_ATOM_NULL) {
@@ -25192,7 +25073,6 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd,
}
}
}
}
return 0;
duplicate:
@@ -25241,11 +25121,6 @@ static __exception int js_parse_function_decl2(JSParseState *s,
}
if (func_type == JS_PARSE_FUNC_VAR) {
if (!(fd->js_mode & JS_MODE_STRICT)
&& find_lexical_decl(ctx, fd, func_name, fd->scope_first, FALSE) < 0
&& !((func_idx = find_var(ctx, fd, func_name)) >= 0 && (func_idx & ARGUMENT_VAR_OFFSET))) {
create_func_var = TRUE;
}
/* Create the lexical name here so that the function closure
contains it */
if (fd->is_eval &&
@@ -25606,7 +25481,7 @@ static __exception int js_parse_function_decl2(JSParseState *s,
(needed for annex B.3.3.4 and B.3.3.5
checks) */
hf->scope_level = 0;
hf->force_init = ((s->cur_func->js_mode & JS_MODE_STRICT) != 0);
hf->force_init = 1;
/* store directly into global var, bypass lexical scope */
emit_op(s, OP_dup);
emit_op(s, OP_scope_put_var);
@@ -25693,8 +25568,7 @@ static __exception int js_parse_program(JSParseState *s)
if (js_parse_directives(s))
return -1;
fd->is_global_var = (fd->eval_type == JS_EVAL_TYPE_GLOBAL) ||
!(fd->js_mode & JS_MODE_STRICT);
fd->is_global_var = fd->eval_type == JS_EVAL_TYPE_GLOBAL;
/* hidden variable for the return value */
fd->eval_ret_idx = idx = add_var(s->ctx, fd, JS_ATOM__ret_);
@@ -25786,8 +25660,6 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj,
b = NULL;
var_refs = NULL;
js_mode = 0;
if (flags & JS_EVAL_FLAG_STRICT)
js_mode |= JS_MODE_STRICT;
}
fd = js_new_function_def(ctx, NULL, TRUE, FALSE, filename,
s->buf_start, &s->get_line_col_cache);
@@ -36384,8 +36256,8 @@ static int js_proxy_set(JSContext *ctx, JSValueConst obj, JSAtom atom,
js_free_desc(ctx, &desc);
}
} else {
if ((flags & JS_PROP_THROW) ||
((flags & JS_PROP_THROW_STRICT) && is_strict_mode(ctx))) {
if (flags & JS_PROP_THROW ||
flags & JS_PROP_THROW_STRICT) {
JS_ThrowTypeError(ctx, "proxy: cannot set property");
return -1;
}

View File

@@ -313,7 +313,6 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_EVAL_TYPE_INDIRECT (3 << 0) /* indirect call (internal use) */
#define JS_EVAL_TYPE_MASK (3 << 0)
#define JS_EVAL_FLAG_STRICT (1 << 3) /* force 'strict' mode */
/* compile but do not run. The result is an object with a
JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed
with JS_EvalFunction(). */