From ec4f18c3ce46863014d28e127a06fb3bf4f54355 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Mon, 27 Aug 2018 00:09:35 -0700 Subject: [PATCH] Implement computed properties for object literals. Also disable ES5.1 property name dumplication checks when ES2015 object literals are enabled. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/api/jerry-snapshot.h | 2 +- jerry-core/config.h | 3 +- jerry-core/include/jerryscript-port.h | 1 + jerry-core/jrt/jrt-fatals.c | 5 + jerry-core/parser/js/byte-code.h | 30 ++- jerry-core/parser/js/js-lexer.c | 32 +++- jerry-core/parser/js/js-parser-expr.c | 180 +++++++++++++----- jerry-core/parser/js/js-parser-statm.c | 9 +- jerry-core/profiles/README.md | 2 + jerry-core/vm/opcodes.c | 6 +- jerry-core/vm/opcodes.h | 2 +- jerry-core/vm/vm.c | 106 ++++++++--- jerry-core/vm/vm.h | 41 +++- tests/jerry/es2015/object-computed.js | 139 ++++++++++++++ .../object-literal-fails.js} | 35 +++- tests/jerry/fail/object-get-data.js | 15 -- tests/jerry/fail/object-get-get.js | 15 -- .../fail/object-several-prop-names-strict.js | 17 -- tests/unit-core/test-snapshot.c | 2 +- 19 files changed, 486 insertions(+), 156 deletions(-) create mode 100644 tests/jerry/es2015/object-computed.js rename tests/jerry/{object-literal-3.js => es5.1/object-literal-fails.js} (53%) delete mode 100644 tests/jerry/fail/object-get-data.js delete mode 100644 tests/jerry/fail/object-get-get.js delete mode 100644 tests/jerry/fail/object-several-prop-names-strict.js diff --git a/jerry-core/api/jerry-snapshot.h b/jerry-core/api/jerry-snapshot.h index f8a4140cf7..ce7a088a76 100644 --- a/jerry-core/api/jerry-snapshot.h +++ b/jerry-core/api/jerry-snapshot.h @@ -41,7 +41,7 @@ typedef struct /** * Jerry snapshot format version. */ -#define JERRY_SNAPSHOT_VERSION (16u) +#define JERRY_SNAPSHOT_VERSION (17u) /** * Snapshot configuration flags. diff --git a/jerry-core/config.h b/jerry-core/config.h index 51d2c77016..53249bbf63 100644 --- a/jerry-core/config.h +++ b/jerry-core/config.h @@ -37,8 +37,9 @@ */ #ifdef CONFIG_DISABLE_ES2015 # define CONFIG_DISABLE_ES2015_ARROW_FUNCTION -# define CONFIG_DISABLE_ES2015_CLASS # define CONFIG_DISABLE_ES2015_BUILTIN +# define CONFIG_DISABLE_ES2015_CLASS +# define CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER # define CONFIG_DISABLE_ES2015_PROMISE_BUILTIN # define CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS # define CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN diff --git a/jerry-core/include/jerryscript-port.h b/jerry-core/include/jerryscript-port.h index 777b5e747d..4aae586bcb 100644 --- a/jerry-core/include/jerryscript-port.h +++ b/jerry-core/include/jerryscript-port.h @@ -50,6 +50,7 @@ typedef enum ERR_OUT_OF_MEMORY = 10, ERR_SYSCALL = 11, ERR_REF_COUNT_LIMIT = 12, + ERR_DISABLED_BYTE_CODE = 13, ERR_FAILED_INTERNAL_ASSERTION = 120 } jerry_fatal_code_t; diff --git a/jerry-core/jrt/jrt-fatals.c b/jerry-core/jrt/jrt-fatals.c index 5535a687c5..838cbc9254 100644 --- a/jerry-core/jrt/jrt-fatals.c +++ b/jerry-core/jrt/jrt-fatals.c @@ -47,6 +47,11 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */ JERRY_ERROR_MSG ("Error: ERR_REF_COUNT_LIMIT\n"); break; } + case ERR_DISABLED_BYTE_CODE: + { + JERRY_ERROR_MSG ("Error: ERR_DISABLED_BYTE_CODE\n"); + break; + } case ERR_FAILED_INTERNAL_ASSERTION: { JERRY_ERROR_MSG ("Error: ERR_FAILED_INTERNAL_ASSERTION\n"); diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index 8be5015a52..2d745f0758 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -236,7 +236,7 @@ CBC_BACKWARD_BRANCH (CBC_BRANCH_IF_FALSE_BACKWARD, -1, \ VM_OC_BRANCH_IF_FALSE) \ CBC_OPCODE (CBC_SET_PROPERTY, CBC_HAS_LITERAL_ARG, -1, \ - VM_OC_SET_PROPERTY | VM_OC_GET_STACK_LITERAL) \ + VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \ CBC_FORWARD_BRANCH (CBC_JUMP_FORWARD_EXIT_CONTEXT, 0, \ VM_OC_JUMP_AND_EXIT_CONTEXT) \ CBC_OPCODE (CBC_CREATE_ARRAY, CBC_NO_FLAG, 1, \ @@ -318,7 +318,7 @@ CBC_OPCODE (CBC_RETURN_WITH_LITERAL, CBC_HAS_LITERAL_ARG, 0, \ VM_OC_RET | VM_OC_GET_LITERAL) \ CBC_OPCODE (CBC_SET_LITERAL_PROPERTY, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ - VM_OC_SET_PROPERTY | VM_OC_GET_LITERAL_LITERAL) \ + VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \ CBC_OPCODE (CBC_BREAKPOINT_ENABLED, CBC_NO_FLAG, 0, \ VM_OC_BREAKPOINT_ENABLED) \ CBC_OPCODE (CBC_BREAKPOINT_DISABLED, CBC_NO_FLAG, 0, \ @@ -522,11 +522,11 @@ CBC_FORWARD_BRANCH (CBC_EXT_FOR_IN_CREATE_CONTEXT, \ -1 + PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION, VM_OC_FOR_IN_CREATE_CONTEXT) \ CBC_OPCODE (CBC_EXT_SET_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ - VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \ + VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \ CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT, 0, \ VM_OC_FOR_IN_HAS_NEXT) \ CBC_OPCODE (CBC_EXT_SET_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ - VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \ + VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \ CBC_FORWARD_BRANCH (CBC_EXT_TRY_CREATE_CONTEXT, PARSER_TRY_CONTEXT_STACK_ALLOCATION, \ VM_OC_TRY) \ CBC_OPCODE (CBC_EXT_THROW_REFERENCE_ERROR, CBC_NO_FLAG, 1, \ @@ -539,8 +539,6 @@ VM_OC_FINALLY) \ \ /* Basic opcodes. */ \ - CBC_OPCODE (CBC_EXT_DEBUGGER, CBC_NO_FLAG, 0, \ - VM_OC_NONE) \ CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \ VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \ CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \ @@ -551,12 +549,26 @@ VM_OC_RESOURCE_NAME) \ CBC_OPCODE (CBC_EXT_LINE, CBC_NO_FLAG, 0, \ VM_OC_LINE) \ - CBC_OPCODE (CBC_EXT_SET_STATIC_PROPERTY, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ + CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY, CBC_NO_FLAG, -2, \ + VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \ + CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_STATIC_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ VM_OC_SET_PROPERTY | VM_OC_GET_LITERAL_LITERAL) \ - CBC_OPCODE (CBC_EXT_SET_STATIC_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ - VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_COMPUTED_PROPERTY | VM_OC_GET_STACK_LITERAL) \ CBC_OPCODE (CBC_EXT_SET_STATIC_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_STATIC_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \ + VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \ + CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \ \ /* Binary compound assignment opcodes with pushing the result. */ \ CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_ADD, \ diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index 9a717c4d24..9745ee7f48 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -2323,6 +2323,22 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ lexer_parse_string (context_p); create_literal_object = true; } +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + else if (context_p->source_p[0] == LIT_CHAR_LEFT_SQUARE) + { + context_p->source_p += 1; + context_p->column++; + + lexer_next_token (context_p); + parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); + + if (context_p->token.type != LEXER_RIGHT_SQUARE) + { + parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED); + } + return; + } +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ else if (!(ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS) && context_p->source_p[0] == LIT_CHAR_RIGHT_BRACE) { context_p->token.type = LEXER_RIGHT_BRACE; @@ -2349,17 +2365,17 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ } } -#ifndef CONFIG_DISABLE_ES2015_CLASS - if (is_class_method - && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11)) + if (create_literal_object) { - context_p->token.type = LEXER_CLASS_CONSTRUCTOR; - return; - } +#ifndef CONFIG_DISABLE_ES2015_CLASS + if (is_class_method + && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11)) + { + context_p->token.type = LEXER_CLASS_CONSTRUCTOR; + return; + } #endif /* !CONFIG_DISABLE_ES2015_CLASS */ - if (create_literal_object) - { lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL); diff --git a/jerry-core/parser/js/js-parser-expr.c b/jerry-core/parser/js/js-parser-expr.c index 26cfd9e35c..ef39413d12 100644 --- a/jerry-core/parser/js/js-parser-expr.c +++ b/jerry-core/parser/js/js-parser-expr.c @@ -260,6 +260,7 @@ parser_parse_array_literal (parser_context_t *context_p) /**< context */ } } /* parser_parse_array_literal */ +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER /** * Object literal item types. */ @@ -356,8 +357,14 @@ parser_append_object_literal_item (parser_context_t *context_p, /**< context */ context_p->stack_top_uint8 = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS; } } /* parser_append_object_literal_item */ +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ #ifndef CONFIG_DISABLE_ES2015_CLASS + +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER +#error "Class support requires ES2015 object literal support" +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ + /** * Parse class as an object literal. */ @@ -388,25 +395,22 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */ if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER) { - uint32_t status_flags; - cbc_ext_opcode_t opcode; uint16_t literal_index, function_literal_index; + bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER); - if (context_p->token.type == LEXER_PROPERTY_GETTER) - { - status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER; - opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER; - } - else - { - status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER; - opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER; - } + uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE; + status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER); lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); literal_index = context_p->lit_object.index; - if (!is_static && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11)) + bool is_computed = false; + + if (context_p->token.type == LEXER_RIGHT_SQUARE) + { + is_computed = true; + } + else if (!is_static && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11)) { parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR); } @@ -419,12 +423,42 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */ literal_index); JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); - context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode); - context_p->last_cbc.value = function_literal_index; + cbc_ext_opcode_t opcode; + + if (is_computed) + { + context_p->last_cbc.literal_index = function_literal_index; + + if (is_getter) + { + opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_GETTER : CBC_EXT_SET_COMPUTED_GETTER; + } + else + { + opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_SETTER : CBC_EXT_SET_COMPUTED_SETTER; + } + } + else + { + context_p->last_cbc.value = function_literal_index; + + if (is_getter) + { + opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER; + } + else + { + opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER; + } + } + + context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode); is_static = false; + continue; } - else if (!is_static && context_p->token.type == LEXER_CLASS_CONSTRUCTOR) + + if (!is_static && context_p->token.type == LEXER_CLASS_CONSTRUCTOR) { if (constructor_literal_p->type == LEXER_FUNCTION_LITERAL) { @@ -436,47 +470,50 @@ parser_parse_class_literal (parser_context_t *context_p, /**< context */ uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_CLASS_CONSTRUCTOR; constructor_literal_p->u.bytecode_p = parser_parse_function (context_p, status_flags); constructor_literal_p->type = LEXER_FUNCTION_LITERAL; + continue; } - else if (!is_static && context_p->token.type == LEXER_KEYW_STATIC) + + if (!is_static && context_p->token.type == LEXER_KEYW_STATIC) { is_static = true; + continue; } - else - { - if (is_static && lexer_compare_raw_identifier_to_current (context_p, "prototype", 9)) - { - parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE); - } - if (!lexer_check_left_paren (context_p)) - { - lexer_next_token (context_p); - parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED); - } + bool is_computed = false; - parser_flush_cbc (context_p); + if (context_p->token.type == LEXER_RIGHT_SQUARE) + { + is_computed = true; + } + else if (is_static && lexer_compare_raw_identifier_to_current (context_p, "prototype", 9)) + { + parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE); + } - uint16_t literal_index = context_p->lit_object.index; - uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_FUNC_EXPRESSION | PARSER_IS_CLOSURE; - uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags); + parser_flush_cbc (context_p); - parser_emit_cbc_literal (context_p, - CBC_PUSH_LITERAL, - function_literal_index); + uint16_t literal_index = context_p->lit_object.index; + uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE; + uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags); - JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); + parser_emit_cbc_literal (context_p, + CBC_PUSH_LITERAL, + function_literal_index); - context_p->last_cbc.value = literal_index; + JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL); - if (is_static) - { - context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_STATIC_PROPERTY); - is_static = false; - } - else - { - context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY; - } + context_p->last_cbc.value = literal_index; + + if (is_static) + { + context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL + : CBC_EXT_SET_STATIC_PROPERTY_LITERAL); + is_static = false; + } + else + { + context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL) + : CBC_SET_LITERAL_PROPERTY); } } @@ -606,7 +643,9 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */ parser_emit_cbc (context_p, CBC_CREATE_OBJECT); +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START); +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ while (true) { @@ -623,29 +662,52 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */ uint32_t status_flags; cbc_ext_opcode_t opcode; uint16_t literal_index, function_literal_index; +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER parser_object_literal_item_types_t item_type; +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ if (context_p->token.type == LEXER_PROPERTY_GETTER) { status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER; opcode = CBC_EXT_SET_GETTER; +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER item_type = PARSER_OBJECT_PROPERTY_GETTER; +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ } else { status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER; opcode = CBC_EXT_SET_SETTER; +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER item_type = PARSER_OBJECT_PROPERTY_SETTER; +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ } lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS); + + /* This assignment is a nop for computed getters/setters. */ literal_index = context_p->lit_object.index; +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + if (context_p->token.type == LEXER_RIGHT_SQUARE) + { + opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER + : CBC_EXT_SET_COMPUTED_SETTER); + } +#else /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ parser_append_object_literal_item (context_p, literal_index, item_type); +#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ parser_flush_cbc (context_p); function_literal_index = lexer_construct_function_object (context_p, status_flags); +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + if (opcode >= CBC_EXT_SET_COMPUTED_GETTER) + { + literal_index = function_literal_index; + } +#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ + parser_emit_cbc_literal (context_p, CBC_PUSH_LITERAL, literal_index); @@ -656,13 +718,37 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */ lexer_next_token (context_p); } +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + else if (context_p->token.type == LEXER_RIGHT_SQUARE) + { + lexer_next_token (context_p); + if (context_p->token.type != LEXER_COLON) + { + parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED); + } + + lexer_next_token (context_p); + parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); + + if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL) + { + context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL); + } + else + { + parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY); + } + } +#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ else { uint16_t literal_index = context_p->lit_object.index; +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER parser_append_object_literal_item (context_p, literal_index, PARSER_OBJECT_PROPERTY_VALUE); +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ lexer_next_token (context_p); if (context_p->token.type != LEXER_COLON) @@ -694,12 +780,14 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */ } } +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START) { parser_stack_pop (context_p, NULL, 3); } parser_stack_pop_uint8 (context_p); +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ } /* parser_parse_object_literal */ /** diff --git a/jerry-core/parser/js/js-parser-statm.c b/jerry-core/parser/js/js-parser-statm.c index 55c83d512b..52feef3467 100644 --- a/jerry-core/parser/js/js-parser-statm.c +++ b/jerry-core/parser/js/js-parser-statm.c @@ -1992,7 +1992,14 @@ parser_parse_statements (parser_context_t *context_p) /**< context */ case LEXER_KEYW_DEBUGGER: { - parser_emit_cbc_ext (context_p, CBC_EXT_DEBUGGER); +#ifdef JERRY_DEBUGGER + /* This breakpoint location is not reported to the + * debugger, so it is impossible to disable it. */ + if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) + { + parser_emit_cbc (context_p, CBC_BREAKPOINT_ENABLED); + } +#endif /* JERRY_DEBUGGER */ lexer_next_token (context_p); break; } diff --git a/jerry-core/profiles/README.md b/jerry-core/profiles/README.md index f855cb4278..ec576048f3 100644 --- a/jerry-core/profiles/README.md +++ b/jerry-core/profiles/README.md @@ -87,6 +87,8 @@ In JerryScript all of the features are enabled by default, so an empty profile f Disable the built-in updates of the 5.1 standard. There are some differences in those built-ins which available in both [5.1](http://www.ecma-international.org/ecma-262/5.1/) and [2015](http://www.ecma-international.org/ecma-262/6.0/) versions of the standard. JerryScript uses the latest definition by default. * `CONFIG_DISABLE_ES2015_CLASS`: Disable the [class](https://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions) language element. +* `CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER`: + Disable the [enhanced object initializer](http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer) language element. * `CONFIG_DISABLE_ES2015_PROMISE_BUILTIN`: Disable the [Promise](http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects) built-in. * `CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS`: diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index b887d99273..a8b39cac29 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -101,12 +101,10 @@ opfunc_typeof (ecma_value_t left_value) /**< left value */ void opfunc_set_accessor (bool is_getter, /**< is getter accessor */ ecma_value_t object, /**< object value */ - ecma_value_t accessor_name, /**< accessor name value */ + ecma_string_t *accessor_name_p, /**< accessor name */ ecma_value_t accessor) /**< accessor value */ { ecma_object_t *object_p = ecma_get_object_from_value (object); - JERRY_ASSERT (ecma_is_value_string (accessor_name) || ecma_is_value_number (accessor_name)); - ecma_string_t *accessor_name_p = ecma_get_string_from_value (ecma_op_to_string (accessor_name)); ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p); if (property_p != NULL @@ -153,8 +151,6 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */ ECMA_PROPERTY_VALUE_PTR (property_p), setter_func_p); } - - ecma_deref_ecma_string (accessor_name_p); } /* opfunc_set_accessor */ /** diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index 5114578fa2..eafd5292bb 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -85,7 +85,7 @@ ecma_value_t opfunc_typeof (ecma_value_t left_value); void -opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_value_t accessor_name, ecma_value_t accessor); +opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_string_t *accessor_name_p, ecma_value_t accessor); ecma_value_t vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict); diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index eeb2ff3a3f..fbdbb46002 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -927,11 +927,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ switch (VM_OC_GROUP_GET_INDEX (opcode_data)) { - case VM_OC_NONE: - { - JERRY_ASSERT (opcode == CBC_EXT_DEBUGGER); - continue; - } case VM_OC_POP: { JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end); @@ -1045,23 +1040,26 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ *stack_top_p++ = ecma_make_object_value (obj_p); continue; } +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + case VM_OC_SET_COMPUTED_PROPERTY: + { + /* Swap values. */ + left_value ^= right_value; + right_value ^= left_value; + left_value ^= right_value; + /* FALLTHRU */ + } +#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ case VM_OC_SET_PROPERTY: { -#ifndef CONFIG_DISABLE_ES2015_CLASS - const int index = (byte_code_start_p[0] == CBC_EXT_OPCODE) ? -2 : -1; -#else - const int index = -1; -#endif /* !CONFIG_DISABLE_ES2015_CLASS */ + JERRY_STATIC_ASSERT (VM_OC_NON_STATIC_FLAG == VM_OC_BACKWARD_BRANCH, + vm_oc_non_static_flag_must_be_equal_to_vm_oc_backward_branch); - ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]); - ecma_string_t *prop_name_p; - ecma_property_t *property_p; + JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1); - if (ecma_is_value_string (right_value)) - { - prop_name_p = ecma_get_string_from_value (right_value); - } - else + result = right_value; + + if (JERRY_UNLIKELY (!ecma_is_value_string (right_value))) { result = ecma_op_to_string (right_value); @@ -1069,11 +1067,30 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { goto error; } + } + + ecma_string_t *prop_name_p = ecma_get_string_from_value (result); + +#ifndef CONFIG_DISABLE_ES2015_CLASS + if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE)) + && !(opcode_data & VM_OC_NON_STATIC_FLAG)) + { + if (!ecma_is_value_string (right_value)) + { + ecma_deref_ecma_string (prop_name_p); + } - prop_name_p = ecma_get_string_from_value (result); + result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable")); + goto error; } - property_p = ecma_find_named_property (object_p, prop_name_p); + const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2; +#else /* CONFIG_DISABLE_ES2015_CLASS */ + const int index = -1; +#endif /* !CONFIG_DISABLE_ES2015_CLASS */ + + ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]); + ecma_property_t *property_p = ecma_find_named_property (object_p, prop_name_p); if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) @@ -1108,18 +1125,50 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ case VM_OC_SET_GETTER: case VM_OC_SET_SETTER: { - JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE); + JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1); + + result = left_value; + + if (JERRY_UNLIKELY (!ecma_is_value_string (left_value))) + { + result = ecma_op_to_string (left_value); + + if (ECMA_IS_VALUE_ERROR (result)) + { + goto error; + } + } + + ecma_string_t *prop_name_p = ecma_get_string_from_value (result); + #ifndef CONFIG_DISABLE_ES2015_CLASS - const int index = (byte_code_start_p[1] > CBC_EXT_SET_SETTER) ? -2 : -1; -#else + if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE)) + && !(opcode_data & VM_OC_NON_STATIC_FLAG)) + { + if (!ecma_is_value_string (left_value)) + { + ecma_deref_ecma_string (prop_name_p); + } + + result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable")); + goto error; + } + + const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2; +#else /* CONFIG_DISABLE_ES2015_CLASS */ const int index = -1; #endif /* !CONFIG_DISABLE_ES2015_CLASS */ opfunc_set_accessor (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_SET_GETTER, stack_top_p[index], - left_value, + prop_name_p, right_value); + if (!ecma_is_value_string (left_value)) + { + ecma_deref_ecma_string (prop_name_p); + } + goto free_both_values; } case VM_OC_PUSH_ARRAY: @@ -2560,9 +2609,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p); continue; } +#ifdef JERRY_DEBUGGER case VM_OC_BREAKPOINT_ENABLED: { -#ifdef JERRY_DEBUGGER if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE) { continue; @@ -2580,12 +2629,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ result = ECMA_VALUE_ERROR; goto error; } -#endif /* JERRY_DEBUGGER */ continue; } case VM_OC_BREAKPOINT_DISABLED: { -#ifdef JERRY_DEBUGGER if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE) { continue; @@ -2634,9 +2681,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ goto error; } } -#endif /* JERRY_DEBUGGER */ continue; } +#endif /* JERRY_DEBUGGER */ #ifdef JERRY_ENABLE_LINE_INFO case VM_OC_RESOURCE_NAME: { @@ -2685,6 +2732,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ #endif /* JERRY_ENABLE_LINE_INFO */ default: { + JERRY_ASSERT (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_NONE); + + jerry_fatal (ERR_DISABLED_BYTE_CODE); JERRY_UNREACHABLE (); } } diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 48e49414a3..f58aa0a3db 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -41,7 +41,8 @@ */ /** - * Branch argument is a backward branch + * If VM_OC_GET_ARGS_INDEX(opcode) == VM_OC_GET_BRANCH, + * this flag signals that the branch is a backward branch. */ #define VM_OC_BACKWARD_BRANCH 0x4000 @@ -102,7 +103,6 @@ typedef enum */ typedef enum { - VM_OC_NONE, /**< do nothing */ VM_OC_POP, /**< pop from stack */ VM_OC_POP_BLOCK, /**< pop block */ VM_OC_PUSH, /**< push one literal */ @@ -121,6 +121,9 @@ typedef enum VM_OC_PUSH_LIT_NEG_BYTE, /**< push literal and number between -1 and -256 */ VM_OC_PUSH_OBJECT, /**< push object */ VM_OC_SET_PROPERTY, /**< set property */ +#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + VM_OC_SET_COMPUTED_PROPERTY, /**< set computed property */ +#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ VM_OC_SET_GETTER, /**< set getter */ VM_OC_SET_SETTER, /**< set setter */ VM_OC_PUSH_UNDEFINED_BASE, /**< push undefined base */ @@ -206,12 +209,36 @@ typedef enum VM_OC_FINALLY, /**< finally */ VM_OC_CONTEXT_END, /**< context end */ VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */ +#ifdef JERRY_DEBUGGER VM_OC_BREAKPOINT_ENABLED, /**< enabled breakpoint for debugger */ VM_OC_BREAKPOINT_DISABLED, /**< disabled breakpoint for debugger */ +#endif /* JERRY_DEBUGGER */ +#ifdef JERRY_ENABLE_LINE_INFO VM_OC_RESOURCE_NAME, /**< resource name of the current function */ VM_OC_LINE, /**< line number of the next statement */ +#endif /* JERRY_ENABLE_LINE_INFO */ + VM_OC_NONE, /**< a special opcode for */ } vm_oc_types; +/** + * Unused opcodes, but required by byte-code types. + */ +typedef enum +{ +#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER + VM_OC_SET_COMPUTED_PROPERTY = VM_OC_NONE, /**< set computed property is unused */ +#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */ +#ifndef JERRY_DEBUGGER + VM_OC_BREAKPOINT_ENABLED = VM_OC_NONE, /**< enabled breakpoint for debugger is unused */ + VM_OC_BREAKPOINT_DISABLED = VM_OC_NONE, /**< disabled breakpoint for debugger is unused */ +#endif /* !JERRY_DEBUGGER */ +#ifndef JERRY_ENABLE_LINE_INFO + VM_OC_RESOURCE_NAME = VM_OC_NONE, /**< resource name of the current function is unused */ + VM_OC_LINE = VM_OC_NONE, /**< line number of the next statement is unused */ +#endif /* !JERRY_ENABLE_LINE_INFO */ + VM_OC_UNUSED = VM_OC_NONE /**< placeholder if the list is empty */ +} vm_oc_unused_types; + /** * Decrement operator. */ @@ -237,6 +264,16 @@ typedef enum */ #define VM_OC_LOGICAL_BRANCH_FLAG 0x2 +/** + * Bit index shift for non-static property initializers. + */ +#define VM_OC_NON_STATIC_SHIFT 14 + +/** + * This flag is set for static property initializers. + */ +#define VM_OC_NON_STATIC_FLAG (0x1 << VM_OC_NON_STATIC_SHIFT) + /** * Position of "put result" opcode. */ diff --git a/tests/jerry/es2015/object-computed.js b/tests/jerry/es2015/object-computed.js new file mode 100644 index 0000000000..1371a9dbb6 --- /dev/null +++ b/tests/jerry/es2015/object-computed.js @@ -0,0 +1,139 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* Test object literals. */ + +var local = 0; + +function f(x) +{ + return x + "et"; +} + +var o = { + a: 5, + [ + "pr" + + "op"] : 6, + + [f + ("g") + ] + : 7, + + [f( + "s" + ) ]: 8, + + get [f + ("res") + ] + () { return 9 }, + + set + [f("res")]( + value) { local = value }, +}; + +assert(o.a === 5); +assert(o.prop === 6); +assert(o.get === 7); +assert(o.set === 8); + +local = 0; +o.reset = 10; +assert(local === 10); +assert(o.reset === 9); + +/* Test classes. */ + +function fxy() { + return "xy"; +} + +class C { + [fxy()] () { + return 6; + } + + static [fxy()]() { + return 7; + } + + get ["a" + 1]() { + return 8; + } + + set ["a" + 1](x) { + local = x; + } + + static get ["a" + 1]() { + return 10; + } + + static set ["a" + 1](x) { + local = x; + } +}; + +var c = new C; +assert(c.xy() === 6); +assert(C.xy() === 7); + +local = 0; +c.a1 = 9; +assert(local === 9); +assert(c.a1 === 8); + +local = 0; +C.a1 = 11; +assert(local === 11); +assert(C.a1 === 10); + +class D { + [(() => "const" + "ructor")()] (arg) { + this.a = arg; + } +} + +var d = new D; +assert(d.a === undefined); +d.constructor(7); +assert(d.a === 7); + +class E { + get ["_constructor_".substring(1,12)]() { + return this.a; + } +} + +var e = new E; +assert(e.constructor === undefined); +e.a = 8; +assert(e.constructor === 8); + +function throw_error(snippet) +{ + try { + eval(snippet); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +} + +throw_error("new class { static ['proto' + 'type'] () {} }"); +throw_error("new class { static get ['proto' + 'type'] () {} }"); +throw_error("new class { static set ['proto' + 'type'] (x) {} }"); diff --git a/tests/jerry/object-literal-3.js b/tests/jerry/es5.1/object-literal-fails.js similarity index 53% rename from tests/jerry/object-literal-3.js rename to tests/jerry/es5.1/object-literal-fails.js index f7a5aa4dc4..e381c16af4 100644 --- a/tests/jerry/object-literal-3.js +++ b/tests/jerry/es5.1/object-literal-fails.js @@ -12,13 +12,36 @@ // See the License for the specific language governing permissions and // limitations under the License. -try +function throw_error(snippet) { - // This should be failed in ECMA-262 v5.1 - eval("({ get 1() {}, 1:1 })"); - assert (false); + try + { + eval(snippet); + assert (false); + } + catch (e) + { + assert (e instanceof SyntaxError); + } } -catch (e) + +function throw_error_strict(snippet) { - assert (e instanceof SyntaxError); + 'use strict' + + try + { + eval(snippet); + assert (false); + } + catch (e) + { + assert (e instanceof SyntaxError); + } } + +// These should be failed in ECMA-262 v5.1 +throw_error_strict("({a:1, a:2})"); +throw_error("({a:1, get a() { return 1 }})"); +throw_error("({get a() {return undefined}, get a() {return undefined}})"); +throw_error("({ get 1() {}, 1:1 })"); diff --git a/tests/jerry/fail/object-get-data.js b/tests/jerry/fail/object-get-data.js deleted file mode 100644 index 459a1574e0..0000000000 --- a/tests/jerry/fail/object-get-data.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright JS Foundation and other contributors, http://js.foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -var a = {a:1, get a() {return 1}} diff --git a/tests/jerry/fail/object-get-get.js b/tests/jerry/fail/object-get-get.js deleted file mode 100644 index 4d987df977..0000000000 --- a/tests/jerry/fail/object-get-get.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright JS Foundation and other contributors, http://js.foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -var a = {get a() {return undefined}, get a() {return undefined}} diff --git a/tests/jerry/fail/object-several-prop-names-strict.js b/tests/jerry/fail/object-several-prop-names-strict.js deleted file mode 100644 index cec4eca312..0000000000 --- a/tests/jerry/fail/object-several-prop-names-strict.js +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright JS Foundation and other contributors, http://js.foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -"use strict" - -var a = {a:1, a:2}; diff --git a/tests/unit-core/test-snapshot.c b/tests/unit-core/test-snapshot.c index e8e2a18e87..cae06d796d 100644 --- a/tests/unit-core/test-snapshot.c +++ b/tests/unit-core/test-snapshot.c @@ -216,7 +216,7 @@ main (void) /* Check the snapshot data. Unused bytes should be filled with zeroes */ const uint8_t expected_data[] = { - 0x4A, 0x52, 0x52, 0x59, 0x10, 0x00, 0x00, 0x00, + 0x4A, 0x52, 0x52, 0x59, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,