Skip to content

Commit

Permalink
Fix exporting destructured variables
Browse files Browse the repository at this point in the history
  • Loading branch information
saghul committed Jan 24, 2025
1 parent f106b7c commit c8ab5ed
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
23 changes: 14 additions & 9 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23009,7 +23009,7 @@ static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg)
present at the top level. */
static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
int hasval, int has_ellipsis,
bool allow_initializer)
bool allow_initializer, bool export_flag)
{
int label_parse, label_assign, label_done, label_lvalue, depth_lvalue;
int start_addr, assign_addr;
Expand Down Expand Up @@ -23128,7 +23128,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
emit_u32(s, prop_name);
emit_ic(s, prop_name);
}
if (js_parse_destructuring_element(s, tok, is_arg, true, -1, true) < 0)
if (js_parse_destructuring_element(s, tok, is_arg, true, -1, true, export_flag) < 0)
return -1;
if (s->token.val == '}')
break;
Expand Down Expand Up @@ -23254,6 +23254,11 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
if (tok) {
if (js_define_var(s, var_name, tok))
goto var_error;
if (export_flag) {
if (!add_export_entry(s, s->cur_func->module, var_name, var_name,
JS_EXPORT_TYPE_LOCAL))
goto var_error;
}
scope = s->cur_func->scope_level;
}
if (s->token.val == '=') { /* handle optional default value */
Expand Down Expand Up @@ -23329,7 +23334,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
emit_u8(s, 0);
emit_op(s, OP_drop);
}
if (js_parse_destructuring_element(s, tok, is_arg, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
if (js_parse_destructuring_element(s, tok, is_arg, true, skip_bits & SKIP_HAS_ELLIPSIS, true, export_flag) < 0)
return -1;
} else {
var_name = JS_ATOM_NULL;
Expand Down Expand Up @@ -23620,7 +23625,7 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
{
int skip_bits;
if (js_parse_skip_parens_token(s, &skip_bits, false) == '=') {
if (js_parse_destructuring_element(s, 0, 0, false, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
if (js_parse_destructuring_element(s, 0, 0, false, skip_bits & SKIP_HAS_ELLIPSIS, true, false) < 0)
return -1;
} else {
if (s->token.val == '{') {
Expand Down Expand Up @@ -25179,7 +25184,7 @@ static __exception int js_parse_var(JSParseState *s, int parse_flags, int tok,
if ((s->token.val == '[' || s->token.val == '{')
&& js_parse_skip_parens_token(s, &skip_bits, false) == '=') {
emit_op(s, OP_undefined);
if (js_parse_destructuring_element(s, tok, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
if (js_parse_destructuring_element(s, tok, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true, export_flag) < 0)
return -1;
} else {
return js_parse_error(s, "variable name expected");
Expand Down Expand Up @@ -25301,7 +25306,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,

if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) {
if (s->token.val == '[' || s->token.val == '{') {
if (js_parse_destructuring_element(s, tok, 0, true, -1, false) < 0)
if (js_parse_destructuring_element(s, tok, 0, true, -1, false, false) < 0)
return -1;
has_destructuring = true;
} else {
Expand Down Expand Up @@ -25329,7 +25334,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
int skip_bits;
if ((s->token.val == '[' || s->token.val == '{')
&& ((tok1 = js_parse_skip_parens_token(s, &skip_bits, false)) == TOK_IN || tok1 == TOK_OF)) {
if (js_parse_destructuring_element(s, 0, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true) < 0)
if (js_parse_destructuring_element(s, 0, 0, true, skip_bits & SKIP_HAS_ELLIPSIS, true, false) < 0)
return -1;
} else {
int lvalue_label;
Expand Down Expand Up @@ -26007,7 +26012,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved)) {
if (s->token.val == '[' || s->token.val == '{') {
/* XXX: TOK_LET is not completely correct */
if (js_parse_destructuring_element(s, TOK_LET, 0, true, -1, true) < 0)
if (js_parse_destructuring_element(s, TOK_LET, 0, true, -1, true, false) < 0)
goto fail;
} else {
js_parse_error(s, "identifier expected");
Expand Down Expand Up @@ -32955,7 +32960,7 @@ static __exception int js_parse_function_decl2(JSParseState *s,
emit_op(s, OP_get_arg);
emit_u16(s, idx);
}
has_initializer = js_parse_destructuring_element(s, fd->has_parameter_expressions ? TOK_LET : TOK_VAR, 1, true, -1, true);
has_initializer = js_parse_destructuring_element(s, fd->has_parameter_expressions ? TOK_LET : TOK_VAR, 1, true, -1, true, false);
if (has_initializer < 0)
goto fail;
if (has_initializer)
Expand Down
8 changes: 8 additions & 0 deletions tests/destructured-export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { assert, assertArrayEquals } from "./assert.js";
import * as mod from "./destructured-export.js";

export const { a, b, c } = { a: 1, b: 2, c: 3 };
export const d = 4;

assert(typeof mod === 'object');
assertArrayEquals(Object.keys(mod), ["a", "b", "c", "d"]);

0 comments on commit c8ab5ed

Please sign in to comment.