diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp index 0209b0364c..0d2b436101 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp @@ -59,6 +59,107 @@ ecma_builtin_array_prototype_object_to_string (ecma_value_t this_arg) /**< this ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg); } /* ecma_builtin_array_prototype_object_to_string */ +/** + * The Array.prototype object's 'push' routine + * + * See also: + * ECMA-262 v5, 15.4.4.7 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value. + */ +static ecma_completion_value_t +ecma_builtin_array_prototype_object_push (ecma_value_t this_arg, /**< this argument */ + const ecma_value_t *argument_list_p, /**< arguments list */ + ecma_length_t arguments_number) /**< number of arguments */ +{ + JERRY_ASSERT (argument_list_p == NULL || arguments_number > 0); + + ecma_completion_value_t ret_value = ecma_make_empty_completion_value(); + + // 1. + ECMA_TRY_CATCH (obj_this_value, ecma_op_to_object (this_arg), ret_value); + + ecma_object_t *obj_p = ecma_get_object_from_value (obj_this_value); + + // 2. + ecma_string_t *length_str_p = ecma_new_ecma_string_from_magic_string_id (ECMA_MAGIC_STRING_LENGTH); + + ECMA_TRY_CATCH (length_value, ecma_op_object_get (obj_p, length_str_p), ret_value); + + // 3. + ECMA_OP_TO_NUMBER_TRY_CATCH (length_var, length_value, ret_value); + + uint32_t n = ecma_number_to_uint32 (length_var); + + // 5. + for (uint32_t index = 0; + index < arguments_number; + ++index, ++n) + { + // a. + ecma_value_t e_value = argument_list_p[index]; + + // b. + ecma_string_t *n_str_p = ecma_new_ecma_string_from_uint32 (n); + + ecma_completion_value_t completion = ecma_op_object_put (obj_p, n_str_p, e_value, true); + + ecma_deref_ecma_string (n_str_p); + + if (unlikely (ecma_is_completion_value_throw (completion) + || ecma_is_completion_value_exit (completion))) + { + ret_value = completion; + break; + } + else + { + JERRY_ASSERT (ecma_is_completion_value_normal (completion)); + ecma_free_completion_value (completion); + } + } + + // 6. + if (ecma_is_completion_value_empty (ret_value)) + { + ecma_number_t *num_length_p = ecma_alloc_number (); + *num_length_p = ecma_uint32_to_number (n); + + ecma_value_t num_length_value = ecma_make_number_value (num_length_p); + + ecma_completion_value_t completion = ecma_op_object_put (obj_p, + length_str_p, + num_length_value, + true); + + if (unlikely (ecma_is_completion_value_throw (completion) + || ecma_is_completion_value_exit(completion))) + { + ret_value = completion; + + ecma_dealloc_number (num_length_p); + } + else + { + JERRY_ASSERT (ecma_is_completion_value_normal (completion)); + ecma_free_completion_value (completion); + + ret_value = ecma_make_normal_completion_value (num_length_value); + } + } + + ECMA_OP_TO_NUMBER_FINALIZE (length_var); + + ECMA_FINALIZE (length_value); + + ecma_deref_ecma_string (length_str_p); + + ECMA_FINALIZE (obj_this_value); + + return ret_value; +} /* ecma_builtin_array_prototype_object_push */ + /** * @} * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h index f066818203..4e09fd7b71 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h @@ -59,6 +59,7 @@ NUMBER_VALUE (ECMA_MAGIC_STRING_LENGTH, /* Routine properties: * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ ROUTINE (ECMA_MAGIC_STRING_TO_STRING_UL, ecma_builtin_array_prototype_object_to_string, 0, 0) +ROUTINE (ECMA_MAGIC_STRING_PUSH, ecma_builtin_array_prototype_object_push, NON_FIXED, 1) #undef OBJECT_ID #undef SIMPLE_VALUE diff --git a/tests/jerry/array.js b/tests/jerry/array.js index 14c2339d67..f00f3c8e63 100644 --- a/tests/jerry/array.js +++ b/tests/jerry/array.js @@ -81,3 +81,28 @@ assert (c[3] === '3'); b[0] = 1; c[0] += b[0]; assert (c[0] == 1); + +var len; +var d = []; +assert (d.length === 0); +len = d.push(); +assert (d.length === 0); +assert (d.length === len); +len = d.push(1); +assert (d.length === 1); +assert (d.length === len); +len = d.push(2); +assert (d.length === 2); +assert (d.length === len); +len = d.push('a'); +assert (d.length === 3); +assert (d.length === len); +len = d.push('b', 'c', 3); +assert (d.length == 6); +assert (d.length === len); +assert (d[0] === 1); +assert (d[1] === 2); +assert (d[2] === 'a'); +assert (d[3] === 'b'); +assert (d[4] === 'c'); +assert (d[5] === 3);