Skip to content

Empty values in array creation should be not set #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef enum
ECMA_SIMPLE_VALUE_NULL, /**< null value */
ECMA_SIMPLE_VALUE_FALSE, /**< boolean false */
ECMA_SIMPLE_VALUE_TRUE, /**< boolean true */
ECMA_SIMPLE_VALUE_UNUSED, /**< implemenetation defined value to distinguish not initialized values */
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) */
Expand Down
13 changes: 13 additions & 0 deletions jerry-core/ecma/base/ecma-helpers-value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ ecma_is_value_undefined (ecma_value_t value) /**< ecma-value */
&& ecma_get_value_value_field (value) == ECMA_SIMPLE_VALUE_UNDEFINED);
} /* ecma_is_value_undefined */

/**
* Check if the value is unused.
*
* @return true - if the value contains implementation-defined unused simple value,
* false - otherwise.
*/
bool __attr_pure___ __attr_always_inline___
ecma_is_value_unused (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_UNUSED);
} /* ecma_is_value_unused */

/**
* Check if the value is null.
*
Expand Down
1 change: 1 addition & 0 deletions jerry-core/ecma/base/ecma-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
/* ecma-helpers-value.cpp */
extern bool ecma_is_value_empty (ecma_value_t value);
extern bool ecma_is_value_undefined (ecma_value_t value);
extern bool ecma_is_value_unused (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);
Expand Down
5 changes: 5 additions & 0 deletions jerry-core/ecma/operations/ecma-array-object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_unused (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 ();
Expand Down
38 changes: 38 additions & 0 deletions jerry-core/parser/js/opcodes-dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,44 @@ dump_undefined_assignment_res (void)
return op;
}

/**
* Dump unused value assigment for an operand.
*/
void
dump_unused_assignment (operand op) /**< operand */
{
switch (op.type)
{
case OPERAND_LITERAL:
{
const opcode_t opcode = getop_assignment (LITERAL_TO_REWRITE,
OPCODE_ARG_TYPE_SIMPLE,
ECMA_SIMPLE_VALUE_UNUSED);
serializer_dump_op_meta (create_op_meta_100 (opcode, op.data.lit_id));
break;
}
case OPERAND_TMP:
{
const opcode_t opcode = getop_assignment (op.data.uid, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_UNUSED);
serializer_dump_op_meta (create_op_meta_000 (opcode));
break;
}
}
} /* dump_unused_assignment */

/**
* Dump unused value assigment into a temp operand.
*
* @return operand with unused value assigned to it.
*/
operand
dump_unused_assignment_res (void)
{
operand op = tmp_operand ();
dump_unused_assignment (op);
return op;
} /* dump_unused_assignment_res */

void
dump_null_assignment (operand op)
{
Expand Down
2 changes: 2 additions & 0 deletions jerry-core/parser/js/opcodes-dumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ void dump_smallint_assignment (operand, idx_t);
operand dump_smallint_assignment_res (idx_t);
void dump_undefined_assignment (operand);
operand dump_undefined_assignment_res (void);
void dump_unused_assignment (operand);
operand dump_unused_assignment_res (void);
void dump_null_assignment (operand);
operand dump_null_assignment_res (void);
void dump_variable_assignment (operand, operand);
Expand Down
2 changes: 1 addition & 1 deletion jerry-core/parser/js/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ parse_argument_list (varg_list_type vlt, operand obj, uint8_t *args_count, opera
{
if (token_is (TOK_COMMA))
{
op = dump_undefined_assignment_res ();
op = dump_unused_assignment_res ();
dump_varg (op);
}
else
Expand Down
1 change: 1 addition & 0 deletions jerry-core/vm/pretty-printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ pp_op_meta (const opcode_t *opcodes_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_UNUSED: printf ("<unused>"); break;
default: JERRY_UNREACHABLE ();
}
printf (": SIMPLE;");
Expand Down
2 changes: 2 additions & 0 deletions tests/jerry/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ assert(Array.prototype[0] === 'string value');

var c = [0,,,'3'];
assert (c[0] === 0);
assert (c.hasOwnProperty("1") === false);
assert (c[1] === undefined);
assert (c.hasOwnProperty(2) === false);
assert (c[2] === undefined);
assert (c[3] === '3');

Expand Down