Skip to content

Commit 1e36e4f

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 1e36e4f

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
@@ -633,6 +633,30 @@ 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 initializer method definition.
639+
*
640+
* See also: ES2015 14.3
641+
*/
642+
static void
643+
parser_parse_object_method (parser_context_t *context_p) /**< context */
644+
{
645+
parser_flush_cbc (context_p);
646+
647+
context_p->source_p--;
648+
context_p->column--;
649+
uint16_t function_literal_index = lexer_construct_function_object (context_p,
650+
PARSER_IS_FUNCTION | PARSER_IS_CLOSURE);
651+
652+
parser_emit_cbc_literal (context_p,
653+
CBC_PUSH_LITERAL,
654+
function_literal_index);
655+
656+
lexer_next_token (context_p);
657+
} /* parser_parse_object_method */
658+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
659+
636660
/**
637661
* Parse object literal.
638662
*/
@@ -651,122 +675,151 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
651675
{
652676
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
653677

654-
if (context_p->token.type == LEXER_RIGHT_BRACE)
655-
{
656-
break;
657-
}
658-
659-
if (context_p->token.type == LEXER_PROPERTY_GETTER
660-
|| context_p->token.type == LEXER_PROPERTY_SETTER)
678+
switch (context_p->token.type)
661679
{
662-
uint32_t status_flags;
663-
cbc_ext_opcode_t opcode;
664-
uint16_t literal_index, function_literal_index;
680+
case LEXER_RIGHT_BRACE:
681+
{
682+
break;
683+
}
684+
case LEXER_PROPERTY_GETTER:
685+
case LEXER_PROPERTY_SETTER:
686+
{
687+
uint32_t status_flags;
688+
cbc_ext_opcode_t opcode;
689+
uint16_t literal_index, function_literal_index;
665690
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
666-
parser_object_literal_item_types_t item_type;
691+
parser_object_literal_item_types_t item_type;
667692
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
668693

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;
694+
if (context_p->token.type == LEXER_PROPERTY_GETTER)
695+
{
696+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
697+
opcode = CBC_EXT_SET_GETTER;
673698
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
674-
item_type = PARSER_OBJECT_PROPERTY_GETTER;
699+
item_type = PARSER_OBJECT_PROPERTY_GETTER;
675700
#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;
701+
}
702+
else
703+
{
704+
status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
705+
opcode = CBC_EXT_SET_SETTER;
681706
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
682-
item_type = PARSER_OBJECT_PROPERTY_SETTER;
707+
item_type = PARSER_OBJECT_PROPERTY_SETTER;
683708
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
684-
}
709+
}
685710

686-
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
711+
lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
687712

688-
/* This assignment is a nop for computed getters/setters. */
689-
literal_index = context_p->lit_object.index;
713+
/* This assignment is a nop for computed getters/setters. */
714+
literal_index = context_p->lit_object.index;
690715

691716
#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-
}
717+
if (context_p->token.type == LEXER_RIGHT_SQUARE)
718+
{
719+
opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
720+
: CBC_EXT_SET_COMPUTED_SETTER);
721+
}
697722
#else /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
698-
parser_append_object_literal_item (context_p, literal_index, item_type);
723+
parser_append_object_literal_item (context_p, literal_index, item_type);
699724
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
700725

701-
parser_flush_cbc (context_p);
702-
function_literal_index = lexer_construct_function_object (context_p, status_flags);
726+
parser_flush_cbc (context_p);
727+
function_literal_index = lexer_construct_function_object (context_p, status_flags);
703728

704729
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
705-
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
706-
{
707-
literal_index = function_literal_index;
708-
}
730+
if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
731+
{
732+
literal_index = function_literal_index;
733+
}
709734
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
710735

711-
parser_emit_cbc_literal (context_p,
712-
CBC_PUSH_LITERAL,
713-
literal_index);
736+
parser_emit_cbc_literal (context_p,
737+
CBC_PUSH_LITERAL,
738+
literal_index);
714739

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;
740+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
741+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
742+
context_p->last_cbc.value = function_literal_index;
718743

719-
lexer_next_token (context_p);
720-
}
744+
lexer_next_token (context_p);
745+
break;
746+
}
721747
#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)
748+
case LEXER_RIGHT_SQUARE:
726749
{
727-
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
728-
}
750+
lexer_next_token (context_p);
729751

730-
lexer_next_token (context_p);
731-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
752+
if (context_p->token.type == LEXER_LEFT_PAREN)
753+
{
754+
parser_parse_object_method (context_p);
732755

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);
756+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
757+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
758+
break;
759+
}
760+
761+
if (context_p->token.type != LEXER_COLON)
762+
{
763+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
764+
}
765+
766+
lexer_next_token (context_p);
767+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
768+
769+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
770+
{
771+
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
772+
}
773+
else
774+
{
775+
parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
776+
}
777+
break;
740778
}
741-
}
742779
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
743-
else
744-
{
745-
uint16_t literal_index = context_p->lit_object.index;
780+
default:
781+
{
782+
uint16_t literal_index = context_p->lit_object.index;
746783

747784
#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
748-
parser_append_object_literal_item (context_p,
749-
literal_index,
750-
PARSER_OBJECT_PROPERTY_VALUE);
785+
parser_append_object_literal_item (context_p,
786+
literal_index,
787+
PARSER_OBJECT_PROPERTY_VALUE);
751788
#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
752789

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-
}
790+
lexer_next_token (context_p);
758791

759-
lexer_next_token (context_p);
760-
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
792+
#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
793+
if (context_p->token.type == LEXER_LEFT_PAREN)
794+
{
795+
parser_parse_object_method (context_p);
761796

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);
797+
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
798+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
799+
context_p->last_cbc.value = literal_index;
800+
break;
801+
}
802+
#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
803+
804+
if (context_p->token.type != LEXER_COLON)
805+
{
806+
parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
807+
}
808+
809+
lexer_next_token (context_p);
810+
parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
811+
812+
if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
813+
{
814+
context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
815+
context_p->last_cbc.value = literal_index;
816+
}
817+
else
818+
{
819+
parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
820+
}
821+
822+
break;
770823
}
771824
}
772825

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)