return js_parse_expect(s, ']');
}
-/* XXX: remove */
+/* check if scope chain contains a with statement */
static BOOL has_with_scope(JSFunctionDef *s, int scope_level)
{
- /* check if scope chain contains a with statement */
while (s) {
- int scope_idx = s->scopes[scope_level].first;
- while (scope_idx >= 0) {
- JSVarDef *vd = &s->vars[scope_idx];
-
- if (vd->var_name == JS_ATOM__with_)
- return TRUE;
- scope_idx = vd->scope_next;
+ /* no with in strict mode */
+ if (!(s->js_mode & JS_MODE_STRICT)) {
+ int scope_idx = s->scopes[scope_level].first;
+ while (scope_idx >= 0) {
+ JSVarDef *vd = &s->vars[scope_idx];
+ if (vd->var_name == JS_ATOM__with_)
+ return TRUE;
+ scope_idx = vd->scope_next;
+ }
}
/* check parent scopes */
scope_level = s->parent_scope_level;
}
if (name == JS_ATOM_this || name == JS_ATOM_new_target)
goto invalid_lvalue;
- depth = 2; /* will generate OP_get_ref_value */
+ if (has_with_scope(fd, scope)) {
+ depth = 2; /* will generate OP_get_ref_value */
+ } else {
+ depth = 0;
+ }
break;
case OP_get_field:
name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1);
/* get the value but keep the object/fields on the stack */
switch(opcode) {
case OP_scope_get_var:
- label = new_label(s);
- if (label < 0)
- return -1;
- emit_op(s, OP_scope_make_ref);
- emit_atom(s, name);
- emit_u32(s, label);
- emit_u16(s, scope);
- update_label(fd, label, 1);
- emit_op(s, OP_get_ref_value);
- opcode = OP_get_ref_value;
+ if (depth != 0) {
+ label = new_label(s);
+ if (label < 0)
+ return -1;
+ emit_op(s, OP_scope_make_ref);
+ emit_atom(s, name);
+ emit_u32(s, label);
+ emit_u16(s, scope);
+ update_label(fd, label, 1);
+ emit_op(s, OP_get_ref_value);
+ opcode = OP_get_ref_value;
+ } else {
+ emit_op(s, OP_scope_get_var);
+ emit_atom(s, name);
+ emit_u16(s, scope);
+ }
break;
case OP_get_field:
emit_op(s, OP_get_field2);
} else {
switch(opcode) {
case OP_scope_get_var:
- label = new_label(s);
- if (label < 0)
- return -1;
- emit_op(s, OP_scope_make_ref);
- emit_atom(s, name);
- emit_u32(s, label);
- emit_u16(s, scope);
- update_label(fd, label, 1);
- opcode = OP_get_ref_value;
+ if (depth != 0) {
+ label = new_label(s);
+ if (label < 0)
+ return -1;
+ emit_op(s, OP_scope_make_ref);
+ emit_atom(s, name);
+ emit_u32(s, label);
+ emit_u16(s, scope);
+ update_label(fd, label, 1);
+ opcode = OP_get_ref_value;
+ }
break;
default:
break;
BOOL is_let)
{
switch(opcode) {
+ case OP_scope_get_var:
+ /* depth = 0 */
+ switch(special) {
+ case PUT_LVALUE_NOKEEP:
+ case PUT_LVALUE_NOKEEP_DEPTH:
+ case PUT_LVALUE_KEEP_SECOND:
+ case PUT_LVALUE_NOKEEP_BOTTOM:
+ break;
+ case PUT_LVALUE_KEEP_TOP:
+ emit_op(s, OP_dup);
+ break;
+ default:
+ abort();
+ }
+ break;
case OP_get_field:
case OP_scope_get_private_field:
/* depth = 1 */
switch(opcode) {
case OP_scope_get_var: /* val -- */
- assert(special == PUT_LVALUE_NOKEEP ||
- special == PUT_LVALUE_NOKEEP_DEPTH);
emit_op(s, is_let ? OP_scope_put_var_init : OP_scope_put_var);
emit_u32(s, name); /* has refcount */
emit_u16(s, scope);
/* swap ref and lvalue object if any */
if (prop_name == JS_ATOM_NULL) {
switch(depth_lvalue) {
+ case 0:
+ break;
case 1:
/* source prop x -> x source prop */
emit_op(s, OP_rot3r);
emit_op(s, OP_rot5l);
emit_op(s, OP_rot5l);
break;
+ default:
+ abort();
}
} else {
switch(depth_lvalue) {
+ case 0:
+ break;
case 1:
/* source x -> x source */
emit_op(s, OP_swap);
/* source x y z -> x y z source */
emit_op(s, OP_rot4l);
break;
+ default:
+ abort();
}
}
}
}
if (op == '=') {
- if (opcode == OP_get_ref_value && name == name0) {
+ if ((opcode == OP_get_ref_value || opcode == OP_scope_get_var) && name == name0) {
set_object_name(s, name);
}
} else {
return -1;
}
- if (opcode == OP_get_ref_value && name == name0) {
+ if ((opcode == OP_get_ref_value || opcode == OP_scope_get_var) && name == name0) {
set_object_name(s, name);
}
switch(depth_lvalue) {
+ case 0:
+ emit_op(s, OP_dup);
+ break;
case 1:
emit_op(s, OP_insert2);
break;
}
}
break;
+ case OP_scope_put_var:
+ if (!(var_idx & ARGUMENT_VAR_OFFSET) &&
+ s->vars[var_idx].var_kind == JS_VAR_FUNCTION_NAME) {
+ /* in non strict mode, modifying the function name is ignored */
+ dbuf_putc(bc, OP_drop);
+ goto done;
+ }
+ goto local_scope_var;
case OP_scope_get_ref:
dbuf_putc(bc, OP_undefined);
- /* fall thru */
+ goto local_scope_var;
case OP_scope_get_var_checkthis:
case OP_scope_get_var_undef:
case OP_scope_get_var:
- case OP_scope_put_var:
case OP_scope_put_var_init:
+ local_scope_var:
is_put = (op == OP_scope_put_var || op == OP_scope_put_var_init);
if (var_idx & ARGUMENT_VAR_OFFSET) {
dbuf_putc(bc, OP_get_arg + is_put);
dbuf_put_u16(bc, idx);
}
break;
+ case OP_scope_put_var:
+ if (s->closure_var[idx].var_kind == JS_VAR_FUNCTION_NAME) {
+ /* in non strict mode, modifying the function name is ignored */
+ dbuf_putc(bc, OP_drop);
+ goto done;
+ }
+ goto closure_scope_var;
case OP_scope_get_ref:
/* XXX: should create a dummy object with a named slot that is
a reference to the closure variable */
dbuf_putc(bc, OP_undefined);
- /* fall thru */
+ goto closure_scope_var;
case OP_scope_get_var_undef:
case OP_scope_get_var:
- case OP_scope_put_var:
case OP_scope_put_var_init:
+ closure_scope_var:
is_put = (op == OP_scope_put_var ||
op == OP_scope_put_var_init);
if (is_put) {
test262/test/annexB/language/expressions/assignmenttargettype/callexpression-in-prefix-update.js:27: SyntaxError: invalid increment/decrement operand
test262/test/annexB/language/expressions/assignmenttargettype/callexpression.js:33: SyntaxError: invalid assignment left-hand side
test262/test/annexB/language/expressions/assignmenttargettype/cover-callexpression-and-asyncarrowhead.js:20: SyntaxError: invalid assignment left-hand side
+test262/test/language/expressions/assignment/S11.13.1_A6_T1.js:23: Test262Error: #1: innerX === undefined. Actual: 1
+test262/test/language/expressions/assignment/S11.13.1_A6_T2.js:23: Test262Error: #1: innerX === 2. Actual: 1
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.1_T1.js:24: Test262Error: #1: innerX === 2. Actual: 12
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.2_T1.js:24: Test262Error: #1: innerX === 2. Actual: 5
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.3_T1.js:24: Test262Error: #1: innerX === 2. Actual: 3
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.4_T1.js:24: Test262Error: #1: innerX === 2. Actual: 4
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.5_T1.js:24: Test262Error: #1: innerX === 2. Actual: 4
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.6_T1.js:24: Test262Error: #1: innerX === 2. Actual: 8
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.7_T1.js:24: Test262Error: #1: innerX === 2. Actual: 4
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.8_T1.js:24: Test262Error: #1: innerX === 2. Actual: 4
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.9_T1.js:24: Test262Error: #1: innerX === 2. Actual: 1
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.10_T1.js:24: Test262Error: #1: innerX === 2. Actual: 5
+test262/test/language/expressions/compound-assignment/S11.13.2_A6.11_T1.js:24: Test262Error: #1: innerX === 2. Actual: 5
test262/test/language/identifier-resolution/assign-to-global-undefined.js:20: strict mode: expected error
test262/test/staging/sm/Function/arguments-parameter-shadowing.js:14: Test262Error: Expected SameValue(«true», «false») to be true
test262/test/staging/sm/Function/constructor-binding.js:11: Test262Error: Expected SameValue(«"function"», «"undefined"») to be true
test262/test/staging/sm/class/strictExecution.js:13: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/staging/sm/class/superPropOrdering.js:17: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/staging/sm/class/superPropOrdering.js:17: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
-test262/test/staging/sm/expressions/short-circuit-compound-assignment-const.js:96: TypeError: 'a' is read-only
-test262/test/staging/sm/expressions/short-circuit-compound-assignment-tdz.js:18: Test262Error: Expected a ReferenceError but got a TypeError
-test262/test/staging/sm/expressions/short-circuit-compound-assignment-tdz.js:18: strict mode: Test262Error: Expected a ReferenceError but got a TypeError
test262/test/staging/sm/generators/syntax.js:50: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/staging/sm/lexical-environment/block-scoped-functions-annex-b-arguments.js:13: Test262Error: Expected SameValue(«"object"», «"function"») to be true
test262/test/staging/sm/lexical-environment/block-scoped-functions-annex-b-eval.js:11: Test262Error: Expected SameValue(«"outer-gouter-geval-gtruefalseq"», «"outer-geval-gwith-gtruefalseq"») to be true