diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 12129ed8e..b5f1009bd 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -82,6 +82,7 @@ typedef enum ECMA_SIMPLE_VALUE_ARRAY_REDIRECT, /**< implementation defined value for an array's elements that exist, but are stored directly in the array's property list (used for array elements with non-default attribute values) */ + ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */ ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma-values */ } ecma_simple_value_t; diff --git a/jerry-core/ecma/base/ecma-helpers-value.cpp b/jerry-core/ecma/base/ecma-helpers-value.cpp index 9c9bc5afc..271380bad 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.cpp +++ b/jerry-core/ecma/base/ecma-helpers-value.cpp @@ -155,6 +155,19 @@ ecma_is_value_true (ecma_value_t value) /**< ecma-value */ && ecma_get_value_value_field (value) == ECMA_SIMPLE_VALUE_TRUE); } /* ecma_is_value_true */ +/** + * Check if the value is array hole. + * + * @return true - if the value contains ecma-array-hole simple value, + * false - otherwise. + */ +bool __attr_pure___ __attr_always_inline___ +ecma_is_value_array_hole (ecma_value_t value) /**< ecma-value */ +{ + return (ecma_get_value_type_field (value) == ECMA_TYPE_SIMPLE + && ecma_get_value_value_field (value) == ECMA_SIMPLE_VALUE_ARRAY_HOLE); +} /* ecma_is_value_array_hole */ + /** * Check if the value is ecma-number. * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index eed78de66..d53441080 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -58,6 +58,7 @@ extern bool ecma_is_value_undefined (ecma_value_t value); extern bool ecma_is_value_null (ecma_value_t value); extern bool ecma_is_value_boolean (ecma_value_t value); extern bool ecma_is_value_true (ecma_value_t value); +extern bool ecma_is_value_array_hole (ecma_value_t value); extern bool ecma_is_value_number (ecma_value_t value); extern bool ecma_is_value_string (ecma_value_t value); diff --git a/jerry-core/ecma/operations/ecma-array-object.cpp b/jerry-core/ecma/operations/ecma-array-object.cpp index 49a074f68..69c8f283d 100644 --- a/jerry-core/ecma/operations/ecma-array-object.cpp +++ b/jerry-core/ecma/operations/ecma-array-object.cpp @@ -131,6 +131,11 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of index < array_items_count; index++) { + if (ecma_is_value_array_hole (array_items_p[index])) + { + continue; + } + ecma_string_t* item_name_string_p = ecma_new_ecma_string_from_uint32 (index); ecma_property_descriptor_t item_prop_desc = ecma_make_empty_property_descriptor (); diff --git a/jerry-core/parser/js/opcodes-dumper.cpp b/jerry-core/parser/js/opcodes-dumper.cpp index c30bc8811..68b5531fc 100644 --- a/jerry-core/parser/js/opcodes-dumper.cpp +++ b/jerry-core/parser/js/opcodes-dumper.cpp @@ -747,6 +747,25 @@ dumper_is_eval_literal (operand obj) /**< byte-code operand */ return is_eval_lit; } /* dumper_is_eval_literal */ +/** + * Dump assignment of an array-hole simple value to a register + * + * @return register number, to which the value vas assigned + */ +operand +dump_array_hole_assignment_res (void) +{ + operand op = tmp_operand (); + + const vm_instr_t instr = getop_assignment (op.data.uid, + OPCODE_ARG_TYPE_SIMPLE, + ECMA_SIMPLE_VALUE_ARRAY_HOLE); + const op_meta om = create_op_meta_000 (instr); + serializer_dump_op_meta (om); + + return op; +} /* dump_array_hole_assignment_res */ + void dump_boolean_assignment (operand op, bool is_true) { diff --git a/jerry-core/parser/js/opcodes-dumper.h b/jerry-core/parser/js/opcodes-dumper.h index 3bb4391e9..111fd18b5 100644 --- a/jerry-core/parser/js/opcodes-dumper.h +++ b/jerry-core/parser/js/opcodes-dumper.h @@ -63,6 +63,7 @@ void dumper_finish_varg_code_sequence (void); extern bool dumper_is_eval_literal (operand); +operand dump_array_hole_assignment_res (void); void dump_boolean_assignment (operand, bool); operand dump_boolean_assignment_res (bool); void dump_string_assignment (operand, lit_cpointer_t); diff --git a/jerry-core/parser/js/parser.cpp b/jerry-core/parser/js/parser.cpp index 428463aa7..611e27f80 100644 --- a/jerry-core/parser/js/parser.cpp +++ b/jerry-core/parser/js/parser.cpp @@ -581,7 +581,7 @@ parse_argument_list (varg_list_type vlt, operand obj, operand *this_arg_p) { if (token_is (TOK_COMMA)) { - op = dump_undefined_assignment_res (); + op = dump_array_hole_assignment_res (); dump_varg (op); } else diff --git a/jerry-core/vm/pretty-printer.cpp b/jerry-core/vm/pretty-printer.cpp index 585d08192..9ab95269b 100644 --- a/jerry-core/vm/pretty-printer.cpp +++ b/jerry-core/vm/pretty-printer.cpp @@ -263,6 +263,7 @@ pp_op_meta (const vm_instr_t *instrs_p, case ECMA_SIMPLE_VALUE_FALSE: printf ("false"); break; case ECMA_SIMPLE_VALUE_TRUE: printf ("true"); break; case ECMA_SIMPLE_VALUE_UNDEFINED: printf ("undefined"); break; + case ECMA_SIMPLE_VALUE_ARRAY_HOLE: printf ("hole"); break; default: JERRY_UNREACHABLE (); } printf (": SIMPLE;"); diff --git a/tests/jerry/array.js b/tests/jerry/array.js index f31af08ff..f167fbf26 100644 --- a/tests/jerry/array.js +++ b/tests/jerry/array.js @@ -152,3 +152,6 @@ for (i = 0; i < 1024; i++) { assert (arr[i] === i + 1); } + +var elision = [0,,2 ,3]; +assert (elision.hasOwnProperty(1) == false);