Skip to content

Commit 93567fb

Browse files
zherczegakosthekiss
authored andcommitted
Support methods for object initializers. (#2567)
MethodDefinition in ES-2015 12.2.6. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent ffbd6e6 commit 93567fb

File tree

3 files changed

+182
-83
lines changed

3 files changed

+182
-83
lines changed

jerry-core/parser/js/js-parser-expr.c

Lines changed: 136 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,30 @@ parser_parse_class (parser_context_t *context_p, /**< context */
636636
} /* parser_parse_class */
637637
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
638638

639+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
640+
/**
641+
* Parse object initializer method definition.
642+
*
643+
* See also: ES2015 14.3
644+
*/
645+
static void
646+
parser_parse_object_method (parser_context_t *context_p) /**< context */
647+
{
648+
parser_flush_cbc (context_p);
649+
650+
context_p->source_p--;
651+
context_p->column--;
652+
uint16_t function_literal_index = lexer_construct_function_object (context_p,
653+
PARSER_IS_FUNCTION | PARSER_IS_CLOSURE);
654+
655+
parser_emit_cbc_literal (context_p,
656+
CBC_PUSH_LITERAL,
657+
function_literal_index);
658+
659+
lexer_next_token (context_p);
660+
} /* parser_parse_object_method */
661+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
662+
639663
/**
640664
* Parse object literal.
641665
*/
@@ -654,122 +678,151 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
654678
{
655679
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
656680

657-
if (context_p->token.type == LEXER_RIGHT_BRACE)
658-
{
659-
break;
660-
}
661-
662-
if (context_p->token.type == LEXER_PROPERTY_GETTER
663-
|| context_p->token.type == LEXER_PROPERTY_SETTER)
681+
switch (context_p->token.type)
664682
{
665-
uint32_t status_flags;
666-
cbc_ext_opcode_t opcode;
667-
uint16_t literal_index, function_literal_index;
683+
case LEXER_RIGHT_BRACE:
684+
{
685+
break;
686+
}
687+
case LEXER_PROPERTY_GETTER:
688+
case LEXER_PROPERTY_SETTER:
689+
{
690+
uint32_t status_flags;
691+
cbc_ext_opcode_t opcode;
692+
uint16_t literal_index, function_literal_index;
668693
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
669-
parser_object_literal_item_types_t item_type;
694+
parser_object_literal_item_types_t item_type;
670695
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
671696

672-
if (context_p->token.type == LEXER_PROPERTY_GETTER)
673-
{
674-
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
675-
opcode = CBC_EXT_SET_GETTER;
697+
if (context_p->token.type == LEXER_PROPERTY_GETTER)
698+
{
699+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
700+
opcode = CBC_EXT_SET_GETTER;
676701
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
677-
item_type = PARSER_OBJECT_PROPERTY_GETTER;
702+
item_type = PARSER_OBJECT_PROPERTY_GETTER;
678703
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
679-
}
680-
else
681-
{
682-
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
683-
opcode = CBC_EXT_SET_SETTER;
704+
}
705+
else
706+
{
707+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
708+
opcode = CBC_EXT_SET_SETTER;
684709
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
685-
item_type = PARSER_OBJECT_PROPERTY_SETTER;
710+
item_type = PARSER_OBJECT_PROPERTY_SETTER;
686711
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
687-
}
712+
}
688713

689-
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
714+
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
690715

691-
/* This assignment is a nop for computed getters/setters. */
692-
literal_index = context_p->lit_object.index;
716+
/* This assignment is a nop for computed getters/setters. */
717+
literal_index = context_p->lit_object.index;
693718

694719
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
695-
if (context_p->token.type == LEXER_RIGHT_SQUARE)
696-
{
697-
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
698-
: CBC_EXT_SET_COMPUTED_SETTER);
699-
}
720+
if (context_p->token.type == LEXER_RIGHT_SQUARE)
721+
{
722+
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
723+
: CBC_EXT_SET_COMPUTED_SETTER);
724+
}
700725
#else /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
701-
parser_append_object_literal_item (context_p, literal_index, item_type);
726+
parser_append_object_literal_item (context_p, literal_index, item_type);
702727
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
703728

704-
parser_flush_cbc (context_p);
705-
function_literal_index = lexer_construct_function_object (context_p, status_flags);
729+
parser_flush_cbc (context_p);
730+
function_literal_index = lexer_construct_function_object (context_p, status_flags);
706731

707732
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
708-
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
709-
{
710-
literal_index = function_literal_index;
711-
}
733+
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
734+
{
735+
literal_index = function_literal_index;
736+
}
712737
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
713738

714-
parser_emit_cbc_literal (context_p,
715-
CBC_PUSH_LITERAL,
716-
literal_index);
739+
parser_emit_cbc_literal (context_p,
740+
CBC_PUSH_LITERAL,
741+
literal_index);
717742

718-
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
719-
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
720-
context_p->last_cbc.value = function_literal_index;
743+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
744+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
745+
context_p->last_cbc.value = function_literal_index;
721746

722-
lexer_next_token (context_p);
723-
}
747+
lexer_next_token (context_p);
748+
break;
749+
}
724750
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
725-
else if (context_p->token.type == LEXER_RIGHT_SQUARE)
726-
{
727-
lexer_next_token (context_p);
728-
if (context_p->token.type != LEXER_COLON)
751+
case LEXER_RIGHT_SQUARE:
729752
{
730-
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
731-
}
753+
lexer_next_token (context_p);
732754

733-
lexer_next_token (context_p);
734-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
755+
if (context_p->token.type == LEXER_LEFT_PAREN)
756+
{
757+
parser_parse_object_method (context_p);
735758

736-
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
737-
{
738-
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
739-
}
740-
else
741-
{
742-
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
759+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
760+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
761+
break;
762+
}
763+
764+
if (context_p->token.type != LEXER_COLON)
765+
{
766+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
767+
}
768+
769+
lexer_next_token (context_p);
770+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
771+
772+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
773+
{
774+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
775+
}
776+
else
777+
{
778+
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
779+
}
780+
break;
743781
}
744-
}
745782
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
746-
else
747-
{
748-
uint16_t literal_index = context_p->lit_object.index;
783+
default:
784+
{
785+
uint16_t literal_index = context_p->lit_object.index;
749786

750787
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
751-
parser_append_object_literal_item (context_p,
752-
literal_index,
753-
PARSER_OBJECT_PROPERTY_VALUE);
788+
parser_append_object_literal_item (context_p,
789+
literal_index,
790+
PARSER_OBJECT_PROPERTY_VALUE);
754791
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
755792

756-
lexer_next_token (context_p);
757-
if (context_p->token.type != LEXER_COLON)
758-
{
759-
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
760-
}
793+
lexer_next_token (context_p);
761794

762-
lexer_next_token (context_p);
763-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
795+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
796+
if (context_p->token.type == LEXER_LEFT_PAREN)
797+
{
798+
parser_parse_object_method (context_p);
764799

765-
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
766-
{
767-
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
768-
context_p->last_cbc.value = literal_index;
769-
}
770-
else
771-
{
772-
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
800+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
801+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
802+
context_p->last_cbc.value = literal_index;
803+
break;
804+
}
805+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
806+
807+
if (context_p->token.type != LEXER_COLON)
808+
{
809+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
810+
}
811+
812+
lexer_next_token (context_p);
813+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
814+
815+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
816+
{
817+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
818+
context_p->last_cbc.value = literal_index;
819+
}
820+
else
821+
{
822+
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
823+
}
824+
825+
break;
773826
}
774827
}
775828

jerry-core/parser/js/js-parser-scanner.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,13 @@ parser_scan_primary_expression_end (parser_context_t *context_p, /**< context */
403403

404404
JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
405405

406+
if (context_p->token.type == LEXER_LEFT_PAREN)
407+
{
408+
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
409+
*mode = SCAN_MODE_FUNCTION_ARGUMENTS;
410+
return true;
411+
}
412+
406413
if (context_p->token.type != LEXER_COLON)
407414
{
408415
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
@@ -916,6 +923,16 @@ parser_scan_until (parser_context_t *context_p, /**< context */
916923
}
917924

918925
lexer_next_token (context_p);
926+
927+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
928+
if (context_p->token.type == LEXER_LEFT_PAREN)
929+
{
930+
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
931+
mode = SCAN_MODE_FUNCTION_ARGUMENTS;
932+
continue;
933+
}
934+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
935+
919936
if (context_p->token.type != LEXER_COLON)
920937
{
921938
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
switch (1) {
16+
default:
17+
var o = {
18+
value: 10,
19+
func() {
20+
return 234 + this.value;
21+
},
22+
["a" + "b"]() {
23+
return 456 - this.value;
24+
}
25+
}
26+
}
27+
28+
assert(o.func() === 244);
29+
assert(o.ab() === 446);

0 commit comments

Comments
 (0)