mirror of
https://github.com/bellard/quickjs.git
synced 2024-11-22 05:38:11 +08:00
class static block (initial patch by bnoordhuis)
This commit is contained in:
parent
a8064b74fb
commit
16057644f3
2
TODO
2
TODO
@ -63,5 +63,5 @@ Optimization ideas:
|
||||
Test262o: 0/11262 errors, 463 excluded
|
||||
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
|
||||
|
||||
Result: 16/76783 errors, 1497 excluded, 8199 skipped
|
||||
Result: 16/76909 errors, 1497 excluded, 8136 skipped
|
||||
Test262 commit: 6cbb6da9473c56d95358d8e679c5a6d2b4574efb
|
||||
|
93
quickjs.c
93
quickjs.c
@ -19688,6 +19688,7 @@ typedef enum JSParseFunctionEnum {
|
||||
JS_PARSE_FUNC_GETTER,
|
||||
JS_PARSE_FUNC_SETTER,
|
||||
JS_PARSE_FUNC_METHOD,
|
||||
JS_PARSE_FUNC_CLASS_STATIC_INIT,
|
||||
JS_PARSE_FUNC_CLASS_CONSTRUCTOR,
|
||||
JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR,
|
||||
} JSParseFunctionEnum;
|
||||
@ -20574,17 +20575,19 @@ static __exception int next_token(JSParseState *s)
|
||||
(s->cur_func->parent->func_kind & JS_FUNC_GENERATOR)))) ||
|
||||
(s->token.u.ident.atom == JS_ATOM_await &&
|
||||
(s->is_module ||
|
||||
(((s->cur_func->func_kind & JS_FUNC_ASYNC) ||
|
||||
(s->cur_func->func_type == JS_PARSE_FUNC_ARROW &&
|
||||
!s->cur_func->in_function_body && s->cur_func->parent &&
|
||||
(s->cur_func->parent->func_kind & JS_FUNC_ASYNC))))))) {
|
||||
if (ident_has_escape) {
|
||||
s->token.u.ident.is_reserved = TRUE;
|
||||
s->token.val = TOK_IDENT;
|
||||
} else {
|
||||
/* The keywords atoms are pre allocated */
|
||||
s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD;
|
||||
}
|
||||
(s->cur_func->func_kind & JS_FUNC_ASYNC) ||
|
||||
s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT ||
|
||||
(s->cur_func->func_type == JS_PARSE_FUNC_ARROW &&
|
||||
!s->cur_func->in_function_body && s->cur_func->parent &&
|
||||
((s->cur_func->parent->func_kind & JS_FUNC_ASYNC) ||
|
||||
s->cur_func->parent->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))))) {
|
||||
if (ident_has_escape) {
|
||||
s->token.u.ident.is_reserved = TRUE;
|
||||
s->token.val = TOK_IDENT;
|
||||
} else {
|
||||
/* The keywords atoms are pre allocated */
|
||||
s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD;
|
||||
}
|
||||
} else {
|
||||
s->token.val = TOK_IDENT;
|
||||
}
|
||||
@ -22810,6 +22813,49 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr,
|
||||
if (is_static) {
|
||||
if (next_token(s))
|
||||
goto fail;
|
||||
if (s->token.val == '{') {
|
||||
ClassFieldsDef *cf = &class_fields[is_static];
|
||||
JSFunctionDef *init;
|
||||
if (!cf->fields_init_fd) {
|
||||
if (emit_class_init_start(s, cf))
|
||||
goto fail;
|
||||
}
|
||||
s->cur_func = cf->fields_init_fd;
|
||||
/* XXX: could try to avoid creating a new function and
|
||||
reuse 'fields_init_fd' with a specific 'var'
|
||||
scope */
|
||||
// stack is now: <empty>
|
||||
if (js_parse_function_decl2(s, JS_PARSE_FUNC_CLASS_STATIC_INIT,
|
||||
JS_FUNC_NORMAL, JS_ATOM_NULL,
|
||||
s->token.ptr, s->token.line_num,
|
||||
JS_PARSE_EXPORT_NONE, &init) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
// stack is now: fclosure
|
||||
push_scope(s);
|
||||
emit_op(s, OP_scope_get_var);
|
||||
emit_atom(s, JS_ATOM_this);
|
||||
emit_u16(s, 0);
|
||||
// stack is now: fclosure this
|
||||
/* XXX: should do it only once */
|
||||
if (class_name != JS_ATOM_NULL) {
|
||||
// TODO(bnoordhuis) pass as argument to init method?
|
||||
emit_op(s, OP_dup);
|
||||
emit_op(s, OP_scope_put_var_init);
|
||||
emit_atom(s, class_name);
|
||||
emit_u16(s, s->cur_func->scope_level);
|
||||
}
|
||||
emit_op(s, OP_swap);
|
||||
// stack is now: this fclosure
|
||||
emit_op(s, OP_call_method);
|
||||
emit_u16(s, 0);
|
||||
// stack is now: returnvalue
|
||||
emit_op(s, OP_drop);
|
||||
// stack is now: <empty>
|
||||
pop_scope(s);
|
||||
s->cur_func = s->cur_func->parent;
|
||||
continue;
|
||||
}
|
||||
/* allow "static" field name */
|
||||
if (s->token.val == ';' || s->token.val == '=') {
|
||||
is_static = FALSE;
|
||||
@ -26127,6 +26173,10 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
||||
js_parse_error(s, "return not in a function");
|
||||
goto fail;
|
||||
}
|
||||
if (s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||
js_parse_error(s, "return in a static initializer block");
|
||||
goto fail;
|
||||
}
|
||||
if (next_token(s))
|
||||
goto fail;
|
||||
if (s->token.val != ';' && s->token.val != '}' && !s->got_lf) {
|
||||
@ -33278,8 +33328,9 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
func_type == JS_PARSE_FUNC_EXPR &&
|
||||
(func_kind & JS_FUNC_GENERATOR)) ||
|
||||
(s->token.u.ident.atom == JS_ATOM_await &&
|
||||
func_type == JS_PARSE_FUNC_EXPR &&
|
||||
(func_kind & JS_FUNC_ASYNC))) {
|
||||
((func_type == JS_PARSE_FUNC_EXPR &&
|
||||
(func_kind & JS_FUNC_ASYNC)) ||
|
||||
func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))) {
|
||||
return js_parse_error_reserved_identifier(s);
|
||||
}
|
||||
}
|
||||
@ -33373,7 +33424,8 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
func_type == JS_PARSE_FUNC_SETTER ||
|
||||
func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR ||
|
||||
func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR);
|
||||
fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW);
|
||||
fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW &&
|
||||
func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT);
|
||||
fd->has_this_binding = fd->has_arguments_binding;
|
||||
fd->is_derived_class_constructor = (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR);
|
||||
if (func_type == JS_PARSE_FUNC_ARROW) {
|
||||
@ -33381,6 +33433,11 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
fd->super_call_allowed = fd->parent->super_call_allowed;
|
||||
fd->super_allowed = fd->parent->super_allowed;
|
||||
fd->arguments_allowed = fd->parent->arguments_allowed;
|
||||
} else if (func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||
fd->new_target_allowed = TRUE; // although new.target === undefined
|
||||
fd->super_call_allowed = FALSE;
|
||||
fd->super_allowed = TRUE;
|
||||
fd->arguments_allowed = FALSE;
|
||||
} else {
|
||||
fd->new_target_allowed = TRUE;
|
||||
fd->super_call_allowed = fd->is_derived_class_constructor;
|
||||
@ -33418,7 +33475,7 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
if (add_arg(ctx, fd, name) < 0)
|
||||
goto fail;
|
||||
fd->defined_arg_count = 1;
|
||||
} else {
|
||||
} else if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||
if (s->token.val == '(') {
|
||||
int skip_bits;
|
||||
/* if there is an '=' inside the parameter list, we
|
||||
@ -33639,8 +33696,10 @@ static __exception int js_parse_function_decl2(JSParseState *s,
|
||||
}
|
||||
}
|
||||
|
||||
if (js_parse_expect(s, '{'))
|
||||
goto fail;
|
||||
if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) {
|
||||
if (js_parse_expect(s, '{'))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (js_parse_directives(s))
|
||||
goto fail;
|
||||
|
@ -79,7 +79,7 @@ class-fields-private
|
||||
class-fields-private-in=skip
|
||||
class-fields-public
|
||||
class-methods-private
|
||||
class-static-block=skip
|
||||
class-static-block
|
||||
class-static-fields-private
|
||||
class-static-fields-public
|
||||
class-static-methods-private
|
||||
|
Loading…
Reference in New Issue
Block a user