Merge remote-tracking branch 'origin/js-rm-with' into js-rm-modules
This commit is contained in:
245
source/quickjs.c
245
source/quickjs.c
@@ -14215,24 +14215,6 @@ static __exception int js_operator_in(JSContext *ctx, JSValue *sp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __exception int js_has_unscopable(JSContext *ctx, JSValueConst obj,
|
||||
JSAtom atom)
|
||||
{
|
||||
JSValue arr, val;
|
||||
int ret;
|
||||
|
||||
arr = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_unscopables);
|
||||
if (JS_IsException(arr))
|
||||
return -1;
|
||||
ret = 0;
|
||||
if (JS_IsObject(arr)) {
|
||||
val = JS_GetProperty(ctx, arr, atom);
|
||||
ret = JS_ToBoolFree(ctx, val);
|
||||
}
|
||||
JS_FreeValue(ctx, arr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __exception int js_operator_instanceof(JSContext *ctx, JSValue *sp)
|
||||
{
|
||||
JSValue op1, op2;
|
||||
@@ -17872,108 +17854,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
||||
}
|
||||
BREAK;
|
||||
#endif
|
||||
CASE(OP_with_get_var):
|
||||
CASE(OP_with_put_var):
|
||||
CASE(OP_with_delete_var):
|
||||
CASE(OP_with_make_ref):
|
||||
CASE(OP_with_get_ref):
|
||||
{
|
||||
JSAtom atom;
|
||||
int32_t diff;
|
||||
JSValue obj, val;
|
||||
int ret, is_with;
|
||||
atom = get_u32(pc);
|
||||
diff = get_u32(pc + 4);
|
||||
is_with = pc[8];
|
||||
pc += 9;
|
||||
sf->cur_pc = pc;
|
||||
|
||||
obj = sp[-1];
|
||||
ret = JS_HasProperty(ctx, obj, atom);
|
||||
if (unlikely(ret < 0))
|
||||
goto exception;
|
||||
if (ret) {
|
||||
if (is_with) {
|
||||
ret = js_has_unscopable(ctx, obj, atom);
|
||||
if (unlikely(ret < 0))
|
||||
goto exception;
|
||||
if (ret)
|
||||
goto no_with;
|
||||
}
|
||||
switch (opcode) {
|
||||
case OP_with_get_var:
|
||||
/* in Object Environment Records, GetBindingValue() calls HasProperty() */
|
||||
ret = JS_HasProperty(ctx, obj, atom);
|
||||
if (unlikely(ret <= 0)) {
|
||||
if (ret < 0)
|
||||
goto exception;
|
||||
if (is_strict_mode(ctx)) {
|
||||
JS_ThrowReferenceErrorNotDefined(ctx, atom);
|
||||
goto exception;
|
||||
}
|
||||
val = JS_UNDEFINED;
|
||||
} else {
|
||||
val = JS_GetProperty(ctx, obj, atom);
|
||||
if (unlikely(JS_IsException(val)))
|
||||
goto exception;
|
||||
}
|
||||
set_value(ctx, &sp[-1], val);
|
||||
break;
|
||||
case OP_with_put_var: /* used e.g. in for in/of */
|
||||
/* in Object Environment Records, SetMutableBinding() calls HasProperty() */
|
||||
ret = JS_HasProperty(ctx, obj, atom);
|
||||
if (unlikely(ret <= 0)) {
|
||||
if (ret < 0)
|
||||
goto exception;
|
||||
if (is_strict_mode(ctx)) {
|
||||
JS_ThrowReferenceErrorNotDefined(ctx, atom);
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], obj,
|
||||
JS_PROP_THROW_STRICT);
|
||||
JS_FreeValue(ctx, sp[-1]);
|
||||
sp -= 2;
|
||||
if (unlikely(ret < 0))
|
||||
goto exception;
|
||||
break;
|
||||
case OP_with_delete_var:
|
||||
ret = JS_DeleteProperty(ctx, obj, atom, 0);
|
||||
if (unlikely(ret < 0))
|
||||
goto exception;
|
||||
JS_FreeValue(ctx, sp[-1]);
|
||||
sp[-1] = JS_NewBool(ctx, ret);
|
||||
break;
|
||||
case OP_with_make_ref:
|
||||
/* produce a pair object/propname on the stack */
|
||||
*sp++ = JS_AtomToValue(ctx, atom);
|
||||
break;
|
||||
case OP_with_get_ref:
|
||||
/* produce a pair object/method on the stack */
|
||||
/* in Object Environment Records, GetBindingValue() calls HasProperty() */
|
||||
ret = JS_HasProperty(ctx, obj, atom);
|
||||
if (unlikely(ret < 0))
|
||||
goto exception;
|
||||
if (!ret) {
|
||||
val = JS_UNDEFINED;
|
||||
} else {
|
||||
val = JS_GetProperty(ctx, obj, atom);
|
||||
if (unlikely(JS_IsException(val)))
|
||||
goto exception;
|
||||
}
|
||||
*sp++ = val;
|
||||
break;
|
||||
}
|
||||
pc += diff - 5;
|
||||
} else {
|
||||
no_with:
|
||||
/* if not jumping, drop the object argument */
|
||||
JS_FreeValue(ctx, sp[-1]);
|
||||
sp--;
|
||||
}
|
||||
}
|
||||
BREAK;
|
||||
|
||||
CASE(OP_nop):
|
||||
BREAK;
|
||||
CASE(OP_is_undefined_or_null):
|
||||
@@ -24581,36 +24461,6 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
||||
if (next_token(s))
|
||||
goto fail;
|
||||
break;
|
||||
case TOK_WITH:
|
||||
if (s->cur_func->js_mode & JS_MODE_STRICT) {
|
||||
js_parse_error(s, "invalid keyword: with");
|
||||
goto fail;
|
||||
} else {
|
||||
int with_idx;
|
||||
|
||||
if (next_token(s))
|
||||
goto fail;
|
||||
|
||||
if (js_parse_expr_paren(s))
|
||||
goto fail;
|
||||
|
||||
push_scope(s);
|
||||
with_idx = define_var(s, s->cur_func, JS_ATOM__with_,
|
||||
JS_VAR_DEF_WITH);
|
||||
if (with_idx < 0)
|
||||
goto fail;
|
||||
emit_op(s, OP_to_object);
|
||||
emit_op(s, OP_put_loc);
|
||||
emit_u16(s, with_idx);
|
||||
|
||||
set_eval_ret_undefined(s);
|
||||
if (js_parse_statement(s))
|
||||
goto fail;
|
||||
|
||||
/* Popping scope drops lexical context for the with object variable */
|
||||
pop_scope(s);
|
||||
}
|
||||
break;
|
||||
case TOK_FUNCTION:
|
||||
/* ES6 Annex B.3.2 and B.3.3 semantics */
|
||||
if (!(decl_mask & DECL_MASK_FUNC))
|
||||
@@ -25389,14 +25239,6 @@ static int get_closure_var(JSContext *ctx, JSFunctionDef *s,
|
||||
var_kind);
|
||||
}
|
||||
|
||||
static int get_with_scope_opcode(int op)
|
||||
{
|
||||
if (op == OP_scope_get_var_undef)
|
||||
return OP_with_get_var;
|
||||
else
|
||||
return OP_with_get_var + (op - OP_scope_get_var);
|
||||
}
|
||||
|
||||
static BOOL can_opt_put_ref_value(const uint8_t *bc_buf, int pos)
|
||||
{
|
||||
int opcode = bc_buf[pos];
|
||||
@@ -25582,19 +25424,8 @@ static void var_object_test(JSContext *ctx, JSFunctionDef *s,
|
||||
JSAtom var_name, int op, DynBuf *bc,
|
||||
int *plabel_done, BOOL is_with)
|
||||
{
|
||||
dbuf_putc(bc, get_with_scope_opcode(op));
|
||||
dbuf_putc(bc, op);
|
||||
dbuf_put_u32(bc, JS_DupAtom(ctx, var_name));
|
||||
if (*plabel_done < 0) {
|
||||
*plabel_done = new_label_fd(s);
|
||||
if (*plabel_done < 0) {
|
||||
dbuf_set_error(bc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dbuf_put_u32(bc, *plabel_done);
|
||||
dbuf_putc(bc, is_with);
|
||||
update_label(s, *plabel_done, 1);
|
||||
s->jump_size++;
|
||||
}
|
||||
|
||||
/* return the position of the next opcode */
|
||||
@@ -25633,11 +25464,6 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
|
||||
}
|
||||
var_idx = idx;
|
||||
break;
|
||||
} else
|
||||
if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) {
|
||||
dbuf_putc(bc, OP_get_loc);
|
||||
dbuf_put_u16(bc, idx);
|
||||
var_object_test(ctx, s, var_name, op, bc, &label_done, 1);
|
||||
}
|
||||
idx = vd->scope_next;
|
||||
}
|
||||
@@ -25794,14 +25620,6 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
|
||||
}
|
||||
var_idx = idx;
|
||||
break;
|
||||
} else if (vd->var_name == JS_ATOM__with_ && !is_pseudo_var) {
|
||||
vd->is_captured = 1;
|
||||
idx = get_closure_var(ctx, s, fd, FALSE, idx, vd->var_name, FALSE, FALSE, JS_VAR_NORMAL);
|
||||
if (idx >= 0) {
|
||||
dbuf_putc(bc, OP_get_var_ref);
|
||||
dbuf_put_u16(bc, idx);
|
||||
var_object_test(ctx, s, var_name, op, bc, &label_done, 1);
|
||||
}
|
||||
}
|
||||
idx = vd->scope_next;
|
||||
}
|
||||
@@ -25877,9 +25695,7 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
|
||||
}
|
||||
goto has_idx;
|
||||
} else if ((cv->var_name == JS_ATOM__var_ ||
|
||||
cv->var_name == JS_ATOM__arg_var_ ||
|
||||
cv->var_name == JS_ATOM__with_) && !is_pseudo_var) {
|
||||
int is_with = (cv->var_name == JS_ATOM__with_);
|
||||
cv->var_name == JS_ATOM__arg_var_) && !is_pseudo_var) {
|
||||
if (fd != s) {
|
||||
idx = get_closure_var2(ctx, s, fd,
|
||||
FALSE,
|
||||
@@ -25891,7 +25707,7 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s,
|
||||
}
|
||||
dbuf_putc(bc, OP_get_var_ref);
|
||||
dbuf_put_u16(bc, idx);
|
||||
var_object_test(ctx, s, var_name, op, bc, &label_done, is_with);
|
||||
var_object_test(ctx, s, var_name, op, bc, &label_done, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27517,43 +27333,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case OP_with_get_var:
|
||||
case OP_with_put_var:
|
||||
case OP_with_delete_var:
|
||||
case OP_with_make_ref:
|
||||
case OP_with_get_ref:
|
||||
{
|
||||
JSAtom atom;
|
||||
int is_with;
|
||||
|
||||
atom = get_u32(bc_buf + pos + 1);
|
||||
label = get_u32(bc_buf + pos + 5);
|
||||
is_with = bc_buf[pos + 9];
|
||||
if (OPTIMIZE) {
|
||||
label = find_jump_target(s, label, &op1, NULL);
|
||||
}
|
||||
assert(label >= 0 && label < s->label_count);
|
||||
ls = &label_slots[label];
|
||||
add_pc2line_info(s, bc_out.size, line_num);
|
||||
#if SHORT_OPCODES
|
||||
jp = &s->jump_slots[s->jump_count++];
|
||||
jp->op = op;
|
||||
jp->size = 4;
|
||||
jp->pos = bc_out.size + 5;
|
||||
jp->label = label;
|
||||
#endif
|
||||
dbuf_putc(&bc_out, op);
|
||||
dbuf_put_u32(&bc_out, atom);
|
||||
dbuf_put_u32(&bc_out, ls->addr - bc_out.size);
|
||||
if (ls->addr == -1) {
|
||||
/* unresolved yet: create a new relocation entry */
|
||||
if (!add_reloc(ctx, ls, bc_out.size - 4, 4))
|
||||
goto fail;
|
||||
}
|
||||
dbuf_putc(&bc_out, is_with);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_drop:
|
||||
if (OPTIMIZE) {
|
||||
/* remove useless drops before return */
|
||||
@@ -28286,23 +28065,6 @@ static __exception int compute_stack_size(JSContext *ctx,
|
||||
if (ss_check(ctx, s, pos + 1 + diff, op, stack_len + 1, catch_pos))
|
||||
goto fail;
|
||||
break;
|
||||
case OP_with_get_var:
|
||||
case OP_with_delete_var:
|
||||
diff = get_u32(bc_buf + pos + 5);
|
||||
if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 1, catch_pos))
|
||||
goto fail;
|
||||
break;
|
||||
case OP_with_make_ref:
|
||||
case OP_with_get_ref:
|
||||
diff = get_u32(bc_buf + pos + 5);
|
||||
if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 2, catch_pos))
|
||||
goto fail;
|
||||
break;
|
||||
case OP_with_put_var:
|
||||
diff = get_u32(bc_buf + pos + 5);
|
||||
if (ss_check(ctx, s, pos + 5 + diff, op, stack_len - 1, catch_pos))
|
||||
goto fail;
|
||||
break;
|
||||
case OP_catch:
|
||||
diff = get_u32(bc_buf + pos + 1);
|
||||
if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos))
|
||||
@@ -28686,7 +28448,6 @@ static __exception int js_parse_directives(JSParseState *s)
|
||||
case TOK_TRY:
|
||||
case TOK_FUNCTION:
|
||||
case TOK_DEBUGGER:
|
||||
case TOK_WITH:
|
||||
case TOK_CONST:
|
||||
case TOK_ENUM:
|
||||
case TOK_EXPORT:
|
||||
|
||||
Reference in New Issue
Block a user