Skip to content

Commit 4fb2e38

Browse files
authored
Simplify arrow function parsing (bellard#360)
- parse arrow functions only in `js_parse_cond_expr` - remove `PF_ARROW_FUNC` flag and simplify parsing functions with flags
1 parent 16e7661 commit 4fb2e38

File tree

1 file changed

+63
-53
lines changed

1 file changed

+63
-53
lines changed

Diff for: quickjs.c

+63-53
Original file line numberDiff line numberDiff line change
@@ -21260,12 +21260,10 @@ static __exception int js_parse_object_literal(JSParseState *s)
2126021260
#define PF_IN_ACCEPTED (1 << 0)
2126121261
/* allow function calls parsing in js_parse_postfix_expr() */
2126221262
#define PF_POSTFIX_CALL (1 << 1)
21263-
/* allow arrow functions parsing in js_parse_postfix_expr() */
21264-
#define PF_ARROW_FUNC (1 << 2)
2126521263
/* allow the exponentiation operator in js_parse_unary() */
21266-
#define PF_POW_ALLOWED (1 << 3)
21264+
#define PF_POW_ALLOWED (1 << 2)
2126721265
/* forbid the exponentiation operator in js_parse_unary() */
21268-
#define PF_POW_FORBIDDEN (1 << 4)
21266+
#define PF_POW_FORBIDDEN (1 << 3)
2126921267

2127021268
static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags);
2127121269

@@ -22925,7 +22923,7 @@ static void optional_chain_test(JSParseState *s, int *poptional_chaining_label,
2292522923
emit_label(s, label_next);
2292622924
}
2292722925

22928-
/* allowed parse_flags: PF_POSTFIX_CALL, PF_ARROW_FUNC */
22926+
/* allowed parse_flags: PF_POSTFIX_CALL */
2292922927
static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2293022928
{
2293122929
FuncCallType call_type;
@@ -23003,18 +23001,8 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2300323001
}
2300423002
break;
2300523003
case '(':
23006-
if ((parse_flags & PF_ARROW_FUNC) &&
23007-
js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) {
23008-
if (js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
23009-
JS_FUNC_NORMAL, JS_ATOM_NULL,
23010-
s->token.ptr,
23011-
s->token.line_num,
23012-
s->token.col_num))
23013-
return -1;
23014-
} else {
23015-
if (js_parse_expr_paren(s))
23016-
return -1;
23017-
}
23004+
if (js_parse_expr_paren(s))
23005+
return -1;
2301823006
break;
2301923007
case TOK_FUNCTION:
2302023008
if (js_parse_function_decl(s, JS_PARSE_FUNC_EXPR,
@@ -23056,16 +23044,8 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2305623044
if (s->token.u.ident.is_reserved) {
2305723045
return js_parse_error_reserved_identifier(s);
2305823046
}
23059-
if ((parse_flags & PF_ARROW_FUNC) &&
23060-
peek_token(s, TRUE) == TOK_ARROW) {
23061-
if (js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
23062-
JS_FUNC_NORMAL, JS_ATOM_NULL,
23063-
s->token.ptr,
23064-
s->token.line_num,
23065-
s->token.col_num))
23066-
return -1;
23067-
} else if (token_is_pseudo_keyword(s, JS_ATOM_async) &&
23068-
peek_token(s, TRUE) != '\n') {
23047+
if (token_is_pseudo_keyword(s, JS_ATOM_async) &&
23048+
peek_token(s, TRUE) != '\n') {
2306923049
const uint8_t *source_ptr;
2307023050
int source_line_num;
2307123051
int source_col_num;
@@ -23082,17 +23062,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2308223062
source_line_num,
2308323063
source_col_num))
2308423064
return -1;
23085-
} else if ((parse_flags & PF_ARROW_FUNC) &&
23086-
((s->token.val == '(' &&
23087-
js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) ||
23088-
(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved &&
23089-
peek_token(s, TRUE) == TOK_ARROW))) {
23090-
if (js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
23091-
JS_FUNC_ASYNC, JS_ATOM_NULL,
23092-
source_ptr,
23093-
source_line_num,
23094-
source_col_num))
23095-
return -1;
2309623065
} else {
2309723066
name = JS_DupAtom(s->ctx, JS_ATOM_async);
2309823067
goto do_get_var;
@@ -23104,8 +23073,10 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags)
2310423073
return -1;
2310523074
}
2310623075
name = JS_DupAtom(s->ctx, s->token.u.ident.atom);
23107-
if (next_token(s)) /* update line number before emitting code */
23076+
if (next_token(s)) { /* update line number before emitting code */
23077+
JS_FreeAtom(s->ctx, name);
2310823078
return -1;
23079+
}
2310923080
do_get_var:
2311023081
emit_op(s, OP_scope_get_var);
2311123082
emit_u32(s, name);
@@ -23587,7 +23558,7 @@ static __exception int js_parse_delete(JSParseState *s)
2358723558
return 0;
2358823559
}
2358923560

23590-
/* allowed parse_flags: PF_ARROW_FUNC, PF_POW_ALLOWED, PF_POW_FORBIDDEN */
23561+
/* allowed parse_flags: PF_POW_ALLOWED, PF_POW_FORBIDDEN */
2359123562
static __exception int js_parse_unary(JSParseState *s, int parse_flags)
2359223563
{
2359323564
int op;
@@ -23677,8 +23648,7 @@ static __exception int js_parse_unary(JSParseState *s, int parse_flags)
2367723648
parse_flags = 0;
2367823649
break;
2367923650
default:
23680-
if (js_parse_postfix_expr(s, (parse_flags & PF_ARROW_FUNC) |
23681-
PF_POSTFIX_CALL))
23651+
if (js_parse_postfix_expr(s, PF_POSTFIX_CALL))
2368223652
return -1;
2368323653
if (!s->got_lf &&
2368423654
(s->token.val == TOK_DEC || s->token.val == TOK_INC)) {
@@ -23714,15 +23684,14 @@ static __exception int js_parse_unary(JSParseState *s, int parse_flags)
2371423684
return 0;
2371523685
}
2371623686

23717-
/* allowed parse_flags: PF_ARROW_FUNC, PF_IN_ACCEPTED */
23687+
/* allowed parse_flags: PF_IN_ACCEPTED */
2371823688
static __exception int js_parse_expr_binary(JSParseState *s, int level,
2371923689
int parse_flags)
2372023690
{
2372123691
int op, opcode;
2372223692

2372323693
if (level == 0) {
23724-
return js_parse_unary(s, (parse_flags & PF_ARROW_FUNC) |
23725-
PF_POW_ALLOWED);
23694+
return js_parse_unary(s, PF_POW_ALLOWED);
2372623695
}
2372723696
if (js_parse_expr_binary(s, level - 1, parse_flags))
2372823697
return -1;
@@ -23849,14 +23818,14 @@ static __exception int js_parse_expr_binary(JSParseState *s, int level,
2384923818
}
2385023819
if (next_token(s))
2385123820
return -1;
23852-
if (js_parse_expr_binary(s, level - 1, parse_flags & ~PF_ARROW_FUNC))
23821+
if (js_parse_expr_binary(s, level - 1, parse_flags))
2385323822
return -1;
2385423823
emit_op(s, opcode);
2385523824
}
2385623825
return 0;
2385723826
}
2385823827

23859-
/* allowed parse_flags: PF_ARROW_FUNC, PF_IN_ACCEPTED */
23828+
/* allowed parse_flags: PF_IN_ACCEPTED */
2386023829
static __exception int js_parse_logical_and_or(JSParseState *s, int op,
2386123830
int parse_flags)
2386223831
{
@@ -23880,11 +23849,10 @@ static __exception int js_parse_logical_and_or(JSParseState *s, int op,
2388023849
emit_op(s, OP_drop);
2388123850

2388223851
if (op == TOK_LAND) {
23883-
if (js_parse_expr_binary(s, 8, parse_flags & ~PF_ARROW_FUNC))
23852+
if (js_parse_expr_binary(s, 8, parse_flags))
2388423853
return -1;
2388523854
} else {
23886-
if (js_parse_logical_and_or(s, TOK_LAND,
23887-
parse_flags & ~PF_ARROW_FUNC))
23855+
if (js_parse_logical_and_or(s, TOK_LAND, parse_flags))
2388823856
return -1;
2388923857
}
2389023858
if (s->token.val != op) {
@@ -23916,7 +23884,7 @@ static __exception int js_parse_coalesce_expr(JSParseState *s, int parse_flags)
2391623884
emit_goto(s, OP_if_false, label1);
2391723885
emit_op(s, OP_drop);
2391823886

23919-
if (js_parse_expr_binary(s, 8, parse_flags & ~PF_ARROW_FUNC))
23887+
if (js_parse_expr_binary(s, 8, parse_flags))
2392023888
return -1;
2392123889
if (s->token.val != TOK_DOUBLE_QUESTION_MARK)
2392223890
break;
@@ -23926,7 +23894,7 @@ static __exception int js_parse_coalesce_expr(JSParseState *s, int parse_flags)
2392623894
return 0;
2392723895
}
2392823896

23929-
/* allowed parse_flags: PF_ARROW_FUNC, PF_IN_ACCEPTED */
23897+
/* allowed parse_flags: PF_IN_ACCEPTED */
2393023898
static __exception int js_parse_cond_expr(JSParseState *s, int parse_flags)
2393123899
{
2393223900
int label1, label2;
@@ -24105,12 +24073,54 @@ static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags)
2410524073
emit_label(s, label_next);
2410624074
}
2410724075
return 0;
24076+
} else if (s->token.val == '(' &&
24077+
js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) {
24078+
return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
24079+
JS_FUNC_NORMAL, JS_ATOM_NULL,
24080+
s->token.ptr, s->token.line_num,
24081+
s->token.col_num);
24082+
} else if (token_is_pseudo_keyword(s, JS_ATOM_async)) {
24083+
const uint8_t *source_ptr;
24084+
int tok, source_line_num, source_col_num;
24085+
JSParsePos pos;
24086+
24087+
/* fast test */
24088+
tok = peek_token(s, TRUE);
24089+
if (tok == TOK_FUNCTION || tok == '\n')
24090+
goto next;
24091+
24092+
source_ptr = s->token.ptr;
24093+
source_line_num = s->token.line_num;
24094+
source_col_num = s->token.col_num;
24095+
js_parse_get_pos(s, &pos);
24096+
if (next_token(s))
24097+
return -1;
24098+
if ((s->token.val == '(' &&
24099+
js_parse_skip_parens_token(s, NULL, TRUE) == TOK_ARROW) ||
24100+
(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved &&
24101+
peek_token(s, TRUE) == TOK_ARROW)) {
24102+
return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
24103+
JS_FUNC_ASYNC, JS_ATOM_NULL,
24104+
source_ptr, source_line_num,
24105+
source_col_num);
24106+
} else {
24107+
/* undo the token parsing */
24108+
if (js_parse_seek_token(s, &pos))
24109+
return -1;
24110+
}
24111+
} else if (s->token.val == TOK_IDENT &&
24112+
peek_token(s, TRUE) == TOK_ARROW) {
24113+
return js_parse_function_decl(s, JS_PARSE_FUNC_ARROW,
24114+
JS_FUNC_NORMAL, JS_ATOM_NULL,
24115+
s->token.ptr, s->token.line_num,
24116+
s->token.col_num);
2410824117
}
24118+
next:
2410924119
if (s->token.val == TOK_IDENT) {
2411024120
/* name0 is used to check for OP_set_name pattern, not duplicated */
2411124121
name0 = s->token.u.ident.atom;
2411224122
}
24113-
if (js_parse_cond_expr(s, parse_flags | PF_ARROW_FUNC))
24123+
if (js_parse_cond_expr(s, parse_flags))
2411424124
return -1;
2411524125

2411624126
op = s->token.val;

0 commit comments

Comments
 (0)