From 2feb159fd8a9516018f48a80e3e887c85a96fb98 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 27 Aug 2014 18:28:26 +0400 Subject: [PATCH] Implementing 'array_decl' opcode handler. --- src/libcoreint/opcodes-ecma-support.h | 1 + src/libcoreint/opcodes-native-call.c | 2 + src/libcoreint/opcodes.c | 63 ++++++++++++++++++++++- src/libecmaoperations/ecma-array-object.c | 10 +++- src/libecmaoperations/ecma-array-object.h | 3 +- 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/libcoreint/opcodes-ecma-support.h b/src/libcoreint/opcodes-ecma-support.h index cf05ac8dd..9a02af2fd 100644 --- a/src/libcoreint/opcodes-ecma-support.h +++ b/src/libcoreint/opcodes-ecma-support.h @@ -17,6 +17,7 @@ #define OPCODES_ECMA_SUPPORT_H #include "ecma-alloc.h" +#include "ecma-array-object.h" #include "ecma-comparison.h" #include "ecma-conversion.h" #include "ecma-exceptions.h" diff --git a/src/libcoreint/opcodes-native-call.c b/src/libcoreint/opcodes-native-call.c index 9e00dce3f..6c9203cc6 100644 --- a/src/libcoreint/opcodes-native-call.c +++ b/src/libcoreint/opcodes-native-call.c @@ -50,6 +50,8 @@ opfunc_native_call (opcode_t opdata, /**< operation data */ if (ecma_is_empty_completion_value (get_arg_completion)) { + JERRY_ASSERT (args_read == args_number); + switch ((opcode_native_call_t)native_call_id_idx) { case OPCODE_NATIVE_CALL_LED_TOGGLE: diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index a2e7fbfe6..69863a281 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -45,7 +45,6 @@ */ #define OP_UNIMPLEMENTED_LIST(op) \ - op (array_decl) \ op (prop) \ op (prop_get_decl) \ op (prop_set_decl) \ @@ -780,6 +779,8 @@ opfunc_call_n (opcode_t opdata, /**< operation data */ if (ecma_is_empty_completion_value (get_arg_completion)) { + JERRY_ASSERT (args_read == args_number); + ecma_completion_value_t this_value; opcode_t next_opcode = read_opcode (int_data->pos); @@ -867,6 +868,8 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */ if (ecma_is_empty_completion_value (get_arg_completion)) { + JERRY_ASSERT (args_read == args_number); + if (!ecma_is_constructor (constructor_value.value)) { ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); @@ -905,6 +908,64 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */ return ret_value; } /* opfunc_construct_n */ +/** + * 'Array initializer' opcode handler. + * + * See also: ECMA-262 v5, 11.1.4 + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value. + */ +ecma_completion_value_t +opfunc_array_decl (opcode_t opdata, /**< operation data */ + int_data_t *int_data) /**< interpreter context */ +{ + const idx_t lhs_var_idx = opdata.data.array_decl.lhs; + const idx_t args_number = opdata.data.array_decl.list; + + int_data->pos++; + + ecma_completion_value_t ret_value; + + ecma_value_t arg_values[args_number + 1 /* length of array should not be zero */]; + + ecma_length_t args_read; + ecma_completion_value_t get_arg_completion = fill_varg_list (int_data, + args_number, + arg_values, + &args_read); + + if (ecma_is_empty_completion_value (get_arg_completion)) + { + JERRY_ASSERT (args_read == args_number); + + ecma_object_t *array_obj_p = ecma_op_create_array_object (arg_values, + args_number, + false); + + ret_value = set_variable_value (int_data, + lhs_var_idx, + ecma_make_object_value (array_obj_p)); + + ecma_deref_object (array_obj_p); + } + else + { + JERRY_ASSERT (!ecma_is_completion_value_normal (get_arg_completion)); + + ret_value = get_arg_completion; + } + + for (ecma_length_t arg_index = 0; + arg_index < args_read; + arg_index++) + { + ecma_free_value (arg_values[arg_index], true); + } + + return ret_value; +} /* opfunc_array_decl */ + /** * 'Return with no expression' opcode handler. * diff --git a/src/libecmaoperations/ecma-array-object.c b/src/libecmaoperations/ecma-array-object.c index 8a92909b0..4d0f7c33f 100644 --- a/src/libecmaoperations/ecma-array-object.c +++ b/src/libecmaoperations/ecma-array-object.c @@ -60,12 +60,18 @@ ecma_reject (bool is_throw) /**< Throw flag */ ecma_object_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 */ + ecma_length_t arguments_list_len, /**< length of the arguments' list */ + bool is_treat_single_arg_as_length) /**< if the value is true, + arguments_list_len is 1 + and single argument is Number, + then treat the single argument + as new Array's length rather + than as single item of the Array */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); - JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (arguments_list_p, arguments_list_len); + JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (arguments_list_p, arguments_list_len, is_treat_single_arg_as_length); } /* ecma_op_create_array_object */ /** diff --git a/src/libecmaoperations/ecma-array-object.h b/src/libecmaoperations/ecma-array-object.h index 37142b942..2a5d3c6e4 100644 --- a/src/libecmaoperations/ecma-array-object.h +++ b/src/libecmaoperations/ecma-array-object.h @@ -27,7 +27,8 @@ extern ecma_object_t* ecma_op_create_array_object (ecma_value_t *arguments_list_p, - ecma_length_t arguments_list_len); + ecma_length_t arguments_list_len, + bool is_treat_single_arg_as_length); extern ecma_completion_value_t ecma_op_array_object_define_own_property (ecma_object_t *obj_p,