Implementing Array construction routine; adding unit test on array operations.
This commit is contained in:
@@ -42,7 +42,7 @@ fill_varg_list (int_data_t *int_data, /**< interpreter context */
|
||||
{
|
||||
ecma_completion_value_t evaluate_arg_completion = run_int_loop (int_data);
|
||||
|
||||
if (ecma_is_completion_value_meta (evaluate_arg_completion))
|
||||
if (ecma_is_completion_value_normal (evaluate_arg_completion))
|
||||
{
|
||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
|
||||
|
||||
@@ -902,15 +902,17 @@ opfunc_array_decl (opcode_t opdata, /**< operation data */
|
||||
{
|
||||
JERRY_ASSERT (args_read == args_number);
|
||||
|
||||
ecma_object_t *array_obj_p = ecma_op_create_array_object (arg_values,
|
||||
args_number,
|
||||
false);
|
||||
ECMA_TRY_CATCH (array_obj_value,
|
||||
ecma_op_create_array_object (arg_values,
|
||||
args_number,
|
||||
false),
|
||||
ret_value);
|
||||
|
||||
ret_value = set_variable_value (int_data,
|
||||
lhs_var_idx,
|
||||
ecma_make_object_value (array_obj_p));
|
||||
array_obj_value.u.value);
|
||||
|
||||
ecma_deref_object (array_obj_p);
|
||||
ECMA_FINALIZE (array_obj_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -957,8 +959,10 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */
|
||||
{
|
||||
ecma_completion_value_t evaluate_prop_completion = run_int_loop (int_data);
|
||||
|
||||
if (ecma_is_completion_value_meta (evaluate_prop_completion))
|
||||
if (ecma_is_completion_value_normal (evaluate_prop_completion))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (evaluate_prop_completion));
|
||||
|
||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
|
||||
|
||||
@@ -1423,8 +1427,10 @@ opfunc_with (opcode_t opdata, /**< operation data */
|
||||
|
||||
ecma_completion_value_t evaluation_completion = run_int_loop (int_data);
|
||||
|
||||
if (ecma_is_completion_value_meta (evaluation_completion))
|
||||
if (ecma_is_completion_value_normal (evaluation_completion))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (evaluation_completion));
|
||||
|
||||
opcode_t meta_opcode = read_opcode (int_data->pos);
|
||||
JERRY_ASSERT (meta_opcode.op_idx == __op__idx_meta);
|
||||
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_WITH);
|
||||
|
||||
@@ -55,9 +55,10 @@ ecma_reject (bool is_throw) /**< Throw flag */
|
||||
* See also: ECMA-262 v5, 15.4.2.1
|
||||
* ECMA-262 v5, 15.4.2.2
|
||||
*
|
||||
* @return pointer to newly created Array object
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
ecma_object_t*
|
||||
ecma_completion_value_t
|
||||
ecma_op_create_array_object (ecma_value_t *arguments_list_p, /**< list of arguments that
|
||||
are passed to Array constructor */
|
||||
ecma_length_t arguments_list_len, /**< length of the arguments' list */
|
||||
@@ -71,7 +72,83 @@ ecma_op_create_array_object (ecma_value_t *arguments_list_p, /**< list of argume
|
||||
JERRY_ASSERT (arguments_list_len == 0
|
||||
|| arguments_list_p != NULL);
|
||||
|
||||
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (arguments_list_p, arguments_list_len, is_treat_single_arg_as_length);
|
||||
uint32_t length;
|
||||
ecma_value_t *array_items_p;
|
||||
ecma_length_t array_items_count;
|
||||
|
||||
if (is_treat_single_arg_as_length
|
||||
&& arguments_list_len == 1
|
||||
&& arguments_list_p[0].value_type == ECMA_TYPE_NUMBER)
|
||||
{
|
||||
ecma_number_t *num_p = ECMA_GET_POINTER (arguments_list_p[0].value);
|
||||
uint32_t num_uint32 = ecma_number_to_uint32 (*num_p);
|
||||
if (*num_p != ecma_uint32_to_number (num_uint32))
|
||||
{
|
||||
return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_RANGE));
|
||||
}
|
||||
else
|
||||
{
|
||||
length = num_uint32;
|
||||
array_items_p = NULL;
|
||||
array_items_count = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = arguments_list_len;
|
||||
array_items_p = arguments_list_p;
|
||||
array_items_count = arguments_list_len;
|
||||
}
|
||||
|
||||
FIXME (/* Set prototype to built-in Array prototype (15.4.3.1) */);
|
||||
ecma_object_t *obj_p = ecma_create_object (NULL, true, ECMA_OBJECT_TYPE_ARRAY);
|
||||
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = ECMA_OBJECT_CLASS_ARRAY;
|
||||
|
||||
ecma_string_t *length_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
|
||||
ecma_number_t *length_num_p = ecma_alloc_number ();
|
||||
*length_num_p = ecma_uint32_to_number (length);
|
||||
|
||||
ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p,
|
||||
length_magic_string_p,
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
length_prop_p->u.named_data_property.value = ecma_make_number_value (length_num_p);
|
||||
|
||||
ecma_deref_ecma_string (length_magic_string_p);
|
||||
|
||||
for (uint32_t index = 0;
|
||||
index < array_items_count;
|
||||
index++)
|
||||
{
|
||||
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 ();
|
||||
{
|
||||
item_prop_desc.is_value_defined = true;
|
||||
item_prop_desc.value = array_items_p [index];
|
||||
|
||||
item_prop_desc.is_writable_defined = true;
|
||||
item_prop_desc.writable = ECMA_PROPERTY_WRITABLE;
|
||||
|
||||
item_prop_desc.is_enumerable_defined = true;
|
||||
item_prop_desc.enumerable = ECMA_PROPERTY_ENUMERABLE;
|
||||
|
||||
item_prop_desc.is_configurable_defined = true;
|
||||
item_prop_desc.configurable = ECMA_PROPERTY_CONFIGURABLE;
|
||||
}
|
||||
|
||||
ecma_op_object_define_own_property (obj_p,
|
||||
item_name_string_p,
|
||||
item_prop_desc,
|
||||
false);
|
||||
|
||||
ecma_deref_ecma_string (item_name_string_p);
|
||||
}
|
||||
|
||||
return ecma_make_normal_completion_value (ecma_make_object_value (obj_p));
|
||||
} /* ecma_op_create_array_object */
|
||||
|
||||
/**
|
||||
@@ -177,8 +254,8 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o
|
||||
uint32_t old_len_uint32 = ecma_number_to_uint32 (*num_p);
|
||||
|
||||
// 3.
|
||||
bool is_property_name_equal_length = (ecma_compare_ecma_strings (property_name_p,
|
||||
magic_string_length_p) == 0);
|
||||
bool is_property_name_equal_length = ecma_compare_ecma_strings (property_name_p,
|
||||
magic_string_length_p);
|
||||
|
||||
ecma_deref_ecma_string (magic_string_length_p);
|
||||
|
||||
@@ -332,13 +409,30 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o
|
||||
else
|
||||
{
|
||||
// 4.a.
|
||||
ecma_number_t number = ecma_string_to_number (property_name_p);
|
||||
uint32_t index = ecma_number_to_uint32 (number);
|
||||
uint32_t index;
|
||||
bool is_index;
|
||||
|
||||
TODO (Check if array index recognition is done according to ECMA);
|
||||
if (property_name_p->container == ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
{
|
||||
index = property_name_p->u.uint32_number;
|
||||
is_index = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_number_t number = ecma_string_to_number (property_name_p);
|
||||
index = ecma_number_to_uint32 (number);
|
||||
|
||||
if (index >= ECMA_MAX_VALUE_OF_VALID_ARRAY_INDEX
|
||||
|| ecma_uint32_to_number (index) != number)
|
||||
ecma_string_t *to_uint32_to_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
|
||||
is_index = ecma_compare_ecma_strings (property_name_p,
|
||||
to_uint32_to_string_p);
|
||||
|
||||
ecma_deref_ecma_string (to_uint32_to_string_p);
|
||||
}
|
||||
|
||||
is_index = is_index && (index != ECMA_MAX_VALUE_OF_VALID_ARRAY_INDEX);
|
||||
|
||||
if (!is_index)
|
||||
{
|
||||
// 5.
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ecma_object_t*
|
||||
extern ecma_completion_value_t
|
||||
ecma_op_create_array_object (ecma_value_t *arguments_list_p,
|
||||
ecma_length_t arguments_list_len,
|
||||
bool is_treat_single_arg_as_length);
|
||||
|
||||
@@ -183,7 +183,20 @@ ecma_op_put_value (ecma_reference_t ref, /**< ECMA-reference */
|
||||
JERRY_ASSERT (obj_p != NULL
|
||||
&& !ecma_is_lexical_environment (obj_p));
|
||||
|
||||
return ecma_op_object_put (obj_p, ref.referenced_name_p, value, ref.is_strict);
|
||||
ecma_completion_value_t ret_value;
|
||||
|
||||
ECMA_TRY_CATCH (put_completion,
|
||||
ecma_op_object_put (obj_p,
|
||||
ref.referenced_name_p,
|
||||
value,
|
||||
ref.is_strict),
|
||||
ret_value);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
ECMA_FINALIZE (put_completion);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-array-object.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-objects-arguments.h"
|
||||
#include "ecma-objects-general.h"
|
||||
@@ -402,6 +403,10 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
}
|
||||
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
{
|
||||
return ecma_op_array_object_define_own_property (obj_p, property_name_p, property_desc, is_throw);
|
||||
}
|
||||
|
||||
case ECMA_OBJECT_TYPE_HOST:
|
||||
{
|
||||
JERRY_UNIMPLEMENTED();
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "interpreter.h"
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
#include "serializer.h"
|
||||
|
||||
/**
|
||||
* Unit test's main function.
|
||||
*/
|
||||
int
|
||||
main( int __unused argc,
|
||||
char __unused **argv)
|
||||
{
|
||||
const opcode_t test_program[] = {
|
||||
[ 0] = getop_reg_var_decl (240, 255),
|
||||
[ 1] = getop_jmp_down (2),
|
||||
[ 2] = getop_exitval (1),
|
||||
|
||||
/* var a, b; */
|
||||
[ 3] = getop_var_decl (0),
|
||||
[ 4] = getop_var_decl (1),
|
||||
|
||||
/* b = null; */
|
||||
[ 5] = getop_assignment (1, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_NULL),
|
||||
|
||||
/* a = [12, 'length', b]; */
|
||||
[ 6] = getop_array_decl (0, 3),
|
||||
[ 7] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 12),
|
||||
[ 8] = getop_meta (OPCODE_META_TYPE_VARG, 240, 255),
|
||||
[ 9] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[10] = getop_meta (OPCODE_META_TYPE_VARG, 240, 255),
|
||||
[11] = getop_assignment (240, OPCODE_ARG_TYPE_VARIABLE, 1),
|
||||
[12] = getop_meta (OPCODE_META_TYPE_VARG, 240, 255),
|
||||
|
||||
/* assert (a.length === 3); */
|
||||
[13] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[14] = getop_prop_getter (240, 0, 240),
|
||||
[15] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 3),
|
||||
[16] = getop_equal_value_type (240, 240, 241),
|
||||
[17] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[0] === 12.0); */
|
||||
[18] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 0),
|
||||
[19] = getop_prop_getter (240, 0, 240),
|
||||
[20] = getop_assignment (241, OPCODE_ARG_TYPE_NUMBER, 5),
|
||||
[21] = getop_equal_value_type (240, 240, 241),
|
||||
[22] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a['1'] === 'length'); */
|
||||
[23] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 3),
|
||||
[24] = getop_prop_getter (240, 0, 240),
|
||||
[25] = getop_assignment (241, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[26] = getop_equal_value_type (240, 240, 241),
|
||||
[27] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[2.0] === null); */
|
||||
[28] = getop_assignment (240, OPCODE_ARG_TYPE_NUMBER, 4),
|
||||
[29] = getop_prop_getter (240, 0, 240),
|
||||
[30] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_NULL),
|
||||
[31] = getop_equal_value_type (240, 240, 241),
|
||||
[32] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[2.5] === undefined); */
|
||||
[33] = getop_assignment (240, OPCODE_ARG_TYPE_NUMBER, 6),
|
||||
[34] = getop_prop_getter (240, 0, 240),
|
||||
[35] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
[36] = getop_equal_value_type (240, 240, 241),
|
||||
[37] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* a.length = 1; */
|
||||
[38] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[39] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 1),
|
||||
[40] = getop_prop_setter (0, 240, 241),
|
||||
|
||||
/* assert (a.length === 1); */
|
||||
[41] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[42] = getop_prop_getter (240, 0, 240),
|
||||
[43] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 1),
|
||||
[44] = getop_equal_value_type (240, 240, 241),
|
||||
[45] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[0] === 12.0); */
|
||||
[46] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 0),
|
||||
[47] = getop_prop_getter (240, 0, 240),
|
||||
[48] = getop_assignment (241, OPCODE_ARG_TYPE_NUMBER, 5),
|
||||
[49] = getop_equal_value_type (240, 240, 241),
|
||||
[50] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a['1'] === undefined); */
|
||||
[51] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 3),
|
||||
[52] = getop_prop_getter (240, 0, 240),
|
||||
[53] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
[54] = getop_equal_value_type (240, 240, 241),
|
||||
[55] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[2.0] === undefined); */
|
||||
[56] = getop_assignment (240, OPCODE_ARG_TYPE_NUMBER, 4),
|
||||
[57] = getop_prop_getter (240, 0, 240),
|
||||
[58] = getop_equal_value_type (240, 240, 241),
|
||||
[59] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* a.length = 8; */
|
||||
[60] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[61] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 8),
|
||||
[62] = getop_prop_setter (0, 240, 241),
|
||||
|
||||
/* assert (a.length === 8); */
|
||||
[63] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[64] = getop_prop_getter (240, 0, 240),
|
||||
[65] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 8),
|
||||
[66] = getop_equal_value_type (240, 240, 241),
|
||||
[67] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* a[10] = true; */
|
||||
[68] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 10),
|
||||
[69] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE),
|
||||
[70] = getop_prop_setter (0, 240, 241),
|
||||
|
||||
/* assert (a.length === 11); */
|
||||
[71] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 2),
|
||||
[72] = getop_prop_getter (240, 0, 240),
|
||||
[73] = getop_assignment (241, OPCODE_ARG_TYPE_SMALLINT, 11),
|
||||
[74] = getop_equal_value_type (240, 240, 241),
|
||||
[75] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[0] === 12.0); */
|
||||
[76] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 0),
|
||||
[77] = getop_prop_getter (240, 0, 240),
|
||||
[78] = getop_assignment (241, OPCODE_ARG_TYPE_NUMBER, 5),
|
||||
[79] = getop_equal_value_type (240, 240, 241),
|
||||
[80] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a['1'] === undefined); */
|
||||
[81] = getop_assignment (240, OPCODE_ARG_TYPE_STRING, 3),
|
||||
[82] = getop_prop_getter (240, 0, 240),
|
||||
[83] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
[84] = getop_equal_value_type (240, 240, 241),
|
||||
[85] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[2.0] === undefined); */
|
||||
[86] = getop_assignment (240, OPCODE_ARG_TYPE_NUMBER, 4),
|
||||
[87] = getop_prop_getter (240, 0, 240),
|
||||
[88] = getop_equal_value_type (240, 240, 241),
|
||||
[89] = getop_is_false_jmp (240, 2),
|
||||
|
||||
/* assert (a[17] === true); */
|
||||
[90] = getop_assignment (240, OPCODE_ARG_TYPE_SMALLINT, 10),
|
||||
[91] = getop_prop_getter (240, 0, 240),
|
||||
[92] = getop_assignment (241, OPCODE_ARG_TYPE_SIMPLE, ECMA_SIMPLE_VALUE_TRUE),
|
||||
[93] = getop_equal_value_type (240, 240, 241),
|
||||
[94] = getop_is_false_jmp (240, 2),
|
||||
|
||||
[95] = getop_exitval (0),
|
||||
};
|
||||
|
||||
mem_init();
|
||||
serializer_init (false);
|
||||
|
||||
const char *strings[] = { "a",
|
||||
"b",
|
||||
"length",
|
||||
"1" };
|
||||
ecma_number_t nums [] = { 2.0,
|
||||
12.0,
|
||||
2.5 };
|
||||
uint16_t offset = serializer_dump_strings( strings, 4);
|
||||
serializer_dump_nums( nums, 3, offset, 4);
|
||||
|
||||
init_int( test_program);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
serializer_free ();
|
||||
mem_finalize (false);
|
||||
|
||||
return (status ? 0 : 1);
|
||||
} /* main */
|
||||
Reference in New Issue
Block a user