Skip to content

Commit b94e537

Browse files
committed
Support methods for object initializers.
MethodDefinition in ES-2015 12.2.6. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
1 parent e0e6363 commit b94e537

File tree

3 files changed

+187
-91
lines changed

3 files changed

+187
-91
lines changed

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

Lines changed: 141 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,28 @@ parser_parse_class (parser_context_t *context_p, /**< context */
633633
} /* parser_parse_class */
634634
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
635635

636+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
637+
/**
638+
* Parse object method.
639+
*/
640+
static void
641+
parser_parse_object_method (parser_context_t *context_p) /**< context */
642+
{
643+
parser_flush_cbc (context_p);
644+
645+
context_p->source_p--;
646+
context_p->column--;
647+
uint16_t function_literal_index = lexer_construct_function_object (context_p,
648+
PARSER_IS_FUNCTION | PARSER_IS_CLOSURE);
649+
650+
parser_emit_cbc_literal (context_p,
651+
CBC_PUSH_LITERAL,
652+
function_literal_index);
653+
654+
lexer_next_token (context_p);
655+
} /* parser_parse_object_method */
656+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
657+
636658
/**
637659
* Parse object literal.
638660
*/
@@ -651,122 +673,159 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
651673
{
652674
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
653675

654-
if (context_p->token.type == LEXER_RIGHT_BRACE)
676+
switch (context_p->token.type)
655677
{
656-
break;
657-
}
678+
case LEXER_RIGHT_BRACE:
679+
{
680+
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
681+
while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START)
682+
{
683+
parser_stack_pop (context_p, NULL, 3);
684+
}
658685

659-
if (context_p->token.type == LEXER_PROPERTY_GETTER
660-
|| context_p->token.type == LEXER_PROPERTY_SETTER)
661-
{
662-
uint32_t status_flags;
663-
cbc_ext_opcode_t opcode;
664-
uint16_t literal_index, function_literal_index;
686+
parser_stack_pop_uint8 (context_p);
687+
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
688+
return;
689+
}
690+
case LEXER_PROPERTY_GETTER:
691+
case LEXER_PROPERTY_SETTER:
692+
{
693+
uint32_t status_flags;
694+
cbc_ext_opcode_t opcode;
695+
uint16_t literal_index, function_literal_index;
665696
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
666-
parser_object_literal_item_types_t item_type;
697+
parser_object_literal_item_types_t item_type;
667698
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
668699

669-
if (context_p->token.type == LEXER_PROPERTY_GETTER)
670-
{
671-
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
672-
opcode = CBC_EXT_SET_GETTER;
700+
if (context_p->token.type == LEXER_PROPERTY_GETTER)
701+
{
702+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
703+
opcode = CBC_EXT_SET_GETTER;
673704
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
674-
item_type = PARSER_OBJECT_PROPERTY_GETTER;
705+
item_type = PARSER_OBJECT_PROPERTY_GETTER;
675706
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
676-
}
677-
else
678-
{
679-
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
680-
opcode = CBC_EXT_SET_SETTER;
707+
}
708+
else
709+
{
710+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
711+
opcode = CBC_EXT_SET_SETTER;
681712
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
682-
item_type = PARSER_OBJECT_PROPERTY_SETTER;
713+
item_type = PARSER_OBJECT_PROPERTY_SETTER;
683714
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
684-
}
715+
}
685716

686-
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
717+
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
687718

688-
/* This assignment is a nop for computed getters/setters. */
689-
literal_index = context_p->lit_object.index;
719+
/* This assignment is a nop for computed getters/setters. */
720+
literal_index = context_p->lit_object.index;
690721

691722
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
692-
if (context_p->token.type == LEXER_RIGHT_SQUARE)
693-
{
694-
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
695-
: CBC_EXT_SET_COMPUTED_SETTER);
696-
}
723+
if (context_p->token.type == LEXER_RIGHT_SQUARE)
724+
{
725+
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
726+
: CBC_EXT_SET_COMPUTED_SETTER);
727+
}
697728
#else /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
698-
parser_append_object_literal_item (context_p, literal_index, item_type);
729+
parser_append_object_literal_item (context_p, literal_index, item_type);
699730
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
700731

701-
parser_flush_cbc (context_p);
702-
function_literal_index = lexer_construct_function_object (context_p, status_flags);
732+
parser_flush_cbc (context_p);
733+
function_literal_index = lexer_construct_function_object (context_p, status_flags);
703734

704735
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
705-
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
706-
{
707-
literal_index = function_literal_index;
708-
}
736+
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
737+
{
738+
literal_index = function_literal_index;
739+
}
709740
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
710741

711-
parser_emit_cbc_literal (context_p,
712-
CBC_PUSH_LITERAL,
713-
literal_index);
742+
parser_emit_cbc_literal (context_p,
743+
CBC_PUSH_LITERAL,
744+
literal_index);
714745

715-
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
716-
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
717-
context_p->last_cbc.value = function_literal_index;
746+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
747+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
748+
context_p->last_cbc.value = function_literal_index;
718749

719-
lexer_next_token (context_p);
720-
}
750+
lexer_next_token (context_p);
751+
break;
752+
}
721753
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
722-
else if (context_p->token.type == LEXER_RIGHT_SQUARE)
723-
{
724-
lexer_next_token (context_p);
725-
if (context_p->token.type != LEXER_COLON)
754+
case LEXER_RIGHT_SQUARE:
726755
{
727-
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
728-
}
756+
lexer_next_token (context_p);
729757

730-
lexer_next_token (context_p);
731-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
758+
if (context_p->token.type == LEXER_LEFT_PAREN)
759+
{
760+
parser_parse_object_method (context_p);
732761

733-
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
734-
{
735-
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
736-
}
737-
else
738-
{
739-
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
762+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
763+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
764+
break;
765+
}
766+
767+
if (context_p->token.type != LEXER_COLON)
768+
{
769+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
770+
}
771+
772+
lexer_next_token (context_p);
773+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
774+
775+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
776+
{
777+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
778+
}
779+
else
780+
{
781+
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
782+
}
783+
break;
740784
}
741-
}
742785
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
743-
else
744-
{
745-
uint16_t literal_index = context_p->lit_object.index;
786+
default:
787+
{
788+
uint16_t literal_index = context_p->lit_object.index;
746789

747790
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
748-
parser_append_object_literal_item (context_p,
749-
literal_index,
750-
PARSER_OBJECT_PROPERTY_VALUE);
791+
parser_append_object_literal_item (context_p,
792+
literal_index,
793+
PARSER_OBJECT_PROPERTY_VALUE);
751794
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
752795

753-
lexer_next_token (context_p);
754-
if (context_p->token.type != LEXER_COLON)
755-
{
756-
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
757-
}
796+
lexer_next_token (context_p);
758797

759-
lexer_next_token (context_p);
760-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
798+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
799+
if (context_p->token.type == LEXER_LEFT_PAREN)
800+
{
801+
parser_parse_object_method (context_p);
761802

762-
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
763-
{
764-
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
765-
context_p->last_cbc.value = literal_index;
766-
}
767-
else
768-
{
769-
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
803+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
804+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
805+
context_p->last_cbc.value = literal_index;
806+
break;
807+
}
808+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
809+
810+
if (context_p->token.type != LEXER_COLON)
811+
{
812+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
813+
}
814+
815+
lexer_next_token (context_p);
816+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
817+
818+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
819+
{
820+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
821+
context_p->last_cbc.value = literal_index;
822+
}
823+
else
824+
{
825+
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
826+
}
827+
828+
break;
770829
}
771830
}
772831

@@ -779,15 +838,6 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
779838
parser_raise_error (context_p, PARSER_ERR_OBJECT_ITEM_SEPARATOR_EXPECTED);
780839
}
781840
}
782-
783-
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
784-
while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START)
785-
{
786-
parser_stack_pop (context_p, NULL, 3);
787-
}
788-
789-
parser_stack_pop_uint8 (context_p);
790-
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
791841
} /* parser_parse_object_literal */
792842

793843
/**

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

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

397397
JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
398398

399+
if (context_p->token.type == LEXER_LEFT_PAREN)
400+
{
401+
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
402+
*mode = SCAN_MODE_FUNCTION_ARGUMENTS;
403+
return true;
404+
}
405+
399406
if (context_p->token.type != LEXER_COLON)
400407
{
401408
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
@@ -904,6 +911,16 @@ parser_scan_until (parser_context_t *context_p, /**< context */
904911
}
905912

906913
lexer_next_token (context_p);
914+
915+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
916+
if (context_p->token.type == LEXER_LEFT_PAREN)
917+
{
918+
parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
919+
mode = SCAN_MODE_FUNCTION_ARGUMENTS;
920+
continue;
921+
}
922+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
923+
907924
if (context_p->token.type != LEXER_COLON)
908925
{
909926
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)