Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23708,11 +23708,40 @@ static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags)
if (get_lvalue(s, &opcode, &scope, &name, &label, NULL, (op != '='), op) < 0)
return -1;

// comply with rather obtuse evaluation order of computed properties:
// obj[key]=val evaluates val->obj->key when obj is null/undefined
// but key->obj->val when an object
// FIXME(bnoordhuis) less stack shuffling; don't to_propkey twice in
// happy path; replace `dup is_undefined_or_null if_true` with new
// opcode if_undefined_or_null? replace `swap dup` with over?
if (op == '=' && opcode == OP_get_array_el) {
int label_next = -1;
JSFunctionDef *fd = s->cur_func;
assert(OP_to_propkey2 == fd->byte_code.buf[fd->last_opcode_pos]);
fd->byte_code.size = fd->last_opcode_pos;
fd->last_opcode_pos = -1;
emit_op(s, OP_swap); // obj key -> key obj
emit_op(s, OP_dup);
emit_op(s, OP_is_undefined_or_null);
label_next = emit_goto(s, OP_if_true, -1);
emit_op(s, OP_swap);
emit_op(s, OP_to_propkey);
emit_op(s, OP_swap);
emit_label(s, label_next);
emit_op(s, OP_swap);
}

if (js_parse_assign_expr2(s, parse_flags)) {
JS_FreeAtom(s->ctx, name);
return -1;
}

if (op == '=' && opcode == OP_get_array_el) {
emit_op(s, OP_swap); // obj key val -> obj val key
emit_op(s, OP_to_propkey);
emit_op(s, OP_swap);
}

if (op == '=') {
if (opcode == OP_get_ref_value && name == name0) {
set_object_name(s, name);
Expand Down
4 changes: 0 additions & 4 deletions test262_errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: Test262Er
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: strict mode: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/function/static-init-await-binding.js:16: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/function/static-init-await-binding.js:16: strict mode: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/generators/static-init-await-binding.js:16: SyntaxError: 'await' is a reserved identifier
Expand Down