Skip to content

Commit f05a39a

Browse files
authored
Fix exporting destructured variables
Fixes: bellard/quickjs#382
1 parent f106b7c commit f05a39a

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

quickjs.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23009,7 +23009,7 @@ static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg)
2300923009
present at the top level. */
2301023010
static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
2301123011
int hasval, int has_ellipsis,
23012-
bool allow_initializer)
23012+
bool allow_initializer, bool export_flag)
2301323013
{
2301423014
int label_parse, label_assign, label_done, label_lvalue, depth_lvalue;
2301523015
int start_addr, assign_addr;
@@ -23128,7 +23128,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
2312823128
emit_u32(s, prop_name);
2312923129
emit_ic(s, prop_name);
2313023130
}
23131-
if (js_parse_destructuring_element(s, tok, is_arg, true, -1, true) < 0)
23131+
if (js_parse_destructuring_element(s, tok, is_arg, true, -1, true, export_flag) < 0)
2313223132
return -1;
2313323133
if (s->token.val == '}')
2313423134
break;
@@ -23254,6 +23254,11 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
2325423254
if (tok) {
2325523255
if (js_define_var(s, var_name, tok))
2325623256
goto var_error;
23257+
if (export_flag) {
23258+
if (!add_export_entry(s, s->cur_func->module, var_name, var_name,
23259+
JS_EXPORT_TYPE_LOCAL))
23260+
goto var_error;
23261+
}
2325723262
scope = s->cur_func->scope_level;
2325823263
}
2325923264
if (s->token.val == '=') { /* handle optional default value */
@@ -23329,7 +23334,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
2332923334
emit_u8(s, 0);
2333023335
emit_op(s, OP_drop);
2333123336
}
23332-
if (js_parse_destructuring_element(s, tok, is_arg, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
23337+
if (js_parse_destructuring_element(s, tok, is_arg, true, skip_bits & SKIP_HAS_ELLIPSIS, true, export_flag) < 0)
2333323338
return -1;
2333423339
} else {
2333523340
var_name = JS_ATOM_NULL;
@@ -23620,7 +23625,7 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2362023625
{
2362123626
int skip_bits;
2362223627
if (js_parse_skip_parens_token(s, &skip_bits, false) == '=') {
23623-
if (js_parse_destructuring_element(s, 0, 0, false, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
23628+
if (js_parse_destructuring_element(s, 0, 0, false, skip_bits & SKIP_HAS_ELLIPSIS, true, false) < 0)
2362423629
return -1;
2362523630
} else {
2362623631
if (s->token.val == '{') {
@@ -25179,7 +25184,7 @@ static __exception int js_parse_var(JSParseState *s, int parse_flags, int tok,
2517925184
if ((s->token.val == '[' || s->token.val == '{')
2518025185
&& js_parse_skip_parens_token(s, &skip_bits, false) == '=') {
2518125186
emit_op(s, OP_undefined);
25182-
if (js_parse_destructuring_element(s, tok, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
25187+
if (js_parse_destructuring_element(s, tok, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true, export_flag) < 0)
2518325188
return -1;
2518425189
} else {
2518525190
return js_parse_error(s, "variable name expected");
@@ -25301,7 +25306,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
2530125306

2530225307
if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) {
2530325308
if (s->token.val == '[' || s->token.val == '{') {
25304-
if (js_parse_destructuring_element(s, tok, 0, true, -1, false) < 0)
25309+
if (js_parse_destructuring_element(s, tok, 0, true, -1, false, false) < 0)
2530525310
return -1;
2530625311
has_destructuring = true;
2530725312
} else {
@@ -25329,7 +25334,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
2532925334
int skip_bits;
2533025335
if ((s->token.val == '[' || s->token.val == '{')
2533125336
&& ((tok1 = js_parse_skip_parens_token(s, &skip_bits, false)) == TOK_IN || tok1 == TOK_OF)) {
25332-
if (js_parse_destructuring_element(s, 0, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
25337+
if (js_parse_destructuring_element(s, 0, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true, false) < 0)
2533325338
return -1;
2533425339
} else {
2533525340
int lvalue_label;
@@ -26007,7 +26012,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
2600726012
if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) {
2600826013
if (s->token.val == '[' || s->token.val == '{') {
2600926014
/* XXX: TOK_LET is not completely correct */
26010-
if (js_parse_destructuring_element(s, TOK_LET, 0, true, -1, true) < 0)
26015+
if (js_parse_destructuring_element(s, TOK_LET, 0, true, -1, true, false) < 0)
2601126016
goto fail;
2601226017
} else {
2601326018
js_parse_error(s, "identifier expected");
@@ -32955,7 +32960,7 @@ static __exception int js_parse_function_decl2(JSParseState *s,
3295532960
emit_op(s, OP_get_arg);
3295632961
emit_u16(s, idx);
3295732962
}
32958-
has_initializer = js_parse_destructuring_element(s, fd->has_parameter_expressions ? TOK_LET : TOK_VAR, 1, true, -1, true);
32963+
has_initializer = js_parse_destructuring_element(s, fd->has_parameter_expressions ? TOK_LET : TOK_VAR, 1, true, -1, true, false);
3295932964
if (has_initializer < 0)
3296032965
goto fail;
3296132966
if (has_initializer)

test262_errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ test262/test/language/expressions/in/private-field-invalid-assignment-target.js:
7070
test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: strict mode: unexpected error type: Test262: This statement should not be evaluated.
7171
test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true
7272
test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: strict mode: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true
73-
test262/test/language/module-code/top-level-await/async-module-does-not-block-sibling-modules.js:13: SyntaxError: Could not find export 'check' in module 'test262/test/language/module-code/top-level-await/async-module-sync_FIXTURE.js'
7473
test262/test/language/module-code/top-level-await/module-graphs-does-not-hang.js:10: TypeError: $DONE() not called
7574
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: SyntaxError: invalid property name
7675
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: strict mode: SyntaxError: invalid property name

tests/destructured-export.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { assert, assertArrayEquals } from "./assert.js";
2+
import * as mod from "./destructured-export.js";
3+
4+
export const { a, b, c } = { a: 1, b: 2, c: 3 };
5+
export const d = 4;
6+
7+
assert(typeof mod === 'object');
8+
assertArrayEquals(Object.keys(mod), ["a", "b", "c", "d"]);

0 commit comments

Comments
 (0)