diff --git a/jerry-core/vm/opcodes-ecma-support.h b/jerry-core/vm/opcodes-ecma-support.h index 357af960b..148376db4 100644 --- a/jerry-core/vm/opcodes-ecma-support.h +++ b/jerry-core/vm/opcodes-ecma-support.h @@ -37,10 +37,9 @@ bool is_reg_variable (vm_frame_ctx_t *frame_ctx_p, idx_t var_idx); ecma_completion_value_t get_variable_value (vm_frame_ctx_t *, idx_t, bool); ecma_completion_value_t set_variable_value (vm_frame_ctx_t *, vm_instr_counter_t, idx_t, ecma_value_t); -ecma_completion_value_t fill_varg_list (vm_frame_ctx_t *frame_ctx_p, - ecma_length_t args_number, - ecma_value_t args_values[], - ecma_length_t *out_arg_number_p); +ecma_completion_value_t vm_fill_varg_list (vm_frame_ctx_t *frame_ctx_p, + ecma_length_t args_number, + ecma_collection_header_t *args_values_p); void fill_params_list (vm_frame_ctx_t *frame_ctx_p, ecma_length_t params_number, ecma_string_t* params_names[]); diff --git a/jerry-core/vm/opcodes-varg.cpp b/jerry-core/vm/opcodes-varg.cpp index b43f97c5e..1b31ee2d9 100644 --- a/jerry-core/vm/opcodes-varg.cpp +++ b/jerry-core/vm/opcodes-varg.cpp @@ -27,56 +27,44 @@ * of last expression evaluated */ ecma_completion_value_t -fill_varg_list (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ - ecma_length_t args_number, /**< number of arguments */ - ecma_value_t arg_values[], /**< out: arguments' values */ - ecma_length_t *out_arg_number_p) /**< out: number of arguments - successfully read */ +vm_fill_varg_list (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */ + ecma_length_t args_number, /**< number of arguments */ + ecma_collection_header_t *arg_collection_p) /** collection to fill with argument values */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_length_t arg_index; for (arg_index = 0; arg_index < args_number && ecma_is_completion_value_empty (ret_value); - ) + arg_index++) { - ecma_completion_value_t evaluate_arg_completion = vm_loop (frame_ctx_p, NULL); + ECMA_TRY_CATCH (evaluate_arg, + vm_loop (frame_ctx_p, NULL), + ret_value); - if (ecma_is_completion_value_empty (evaluate_arg_completion)) - { - vm_instr_t next_instr = vm_get_instr (frame_ctx_p->instrs_p, frame_ctx_p->pos); - JERRY_ASSERT (next_instr.op_idx == VM_OP_META); - JERRY_ASSERT (next_instr.data.meta.type == OPCODE_META_TYPE_VARG); + vm_instr_t next_instr = vm_get_instr (frame_ctx_p->instrs_p, frame_ctx_p->pos); + JERRY_ASSERT (next_instr.op_idx == VM_OP_META); + JERRY_ASSERT (next_instr.data.meta.type == OPCODE_META_TYPE_VARG); - const idx_t varg_var_idx = next_instr.data.meta.data_1; + const idx_t varg_var_idx = next_instr.data.meta.data_1; - ecma_completion_value_t get_arg_completion = get_variable_value (frame_ctx_p, varg_var_idx, false); + ECMA_TRY_CATCH (get_arg, + get_variable_value (frame_ctx_p, varg_var_idx, false), + ret_value); - if (ecma_is_completion_value_normal (get_arg_completion)) - { - arg_values[arg_index++] = ecma_get_completion_value_value (get_arg_completion); - } - else - { - JERRY_ASSERT (ecma_is_completion_value_throw (get_arg_completion)); + ecma_append_to_values_collection (arg_collection_p, + ecma_get_completion_value_value (get_arg_completion), + true); - ret_value = get_arg_completion; - } - } - else - { - JERRY_ASSERT (ecma_is_completion_value_throw (evaluate_arg_completion)); - - ret_value = evaluate_arg_completion; - } + ECMA_FINALIZE (get_arg); frame_ctx_p->pos++; + + ECMA_FINALIZE (evaluate_arg); } - *out_arg_number_p = arg_index; - return ret_value; -} /* fill_varg_list */ +} /* vm_fill_varg_list */ /** * Fill parameters' list diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index da29f31c0..2a8cdebd7 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -814,13 +814,12 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ function_var_idx, &call_flags); - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number_idx, ecma_value_t); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); - ecma_length_t args_read; - ecma_completion_value_t get_arg_completion = fill_varg_list (frame_ctx_p, - args_number_idx, - arg_values, - &args_read); + ecma_completion_value_t get_arg_completion = vm_fill_varg_list (frame_ctx_p, + args_number_idx, + arg_collection_p); + ecma_length_t args_read = arg_collection_p->unit_number; if (ecma_is_completion_value_empty (get_arg_completion)) { @@ -839,11 +838,24 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); + MEM_DEFINE_LOCAL_ARRAY (arg_values, args_read, ecma_value_t); + + ecma_collection_iterator_t arg_collection_iter; + ecma_collection_iterator_init (&arg_collection_iter, + arg_collection_p); + + for (ecma_length_t arg_index = 0; + ecma_collection_iterator_next (&arg_collection_iter); + arg_index++) + { + arg_values[arg_index] = *arg_collection_iter.current_value_p; + } + ECMA_TRY_CATCH (call_ret_value, ecma_op_function_call (func_obj_p, this_value, arg_values, - args_number_idx), + args_read), ret_value); ret_value = set_variable_value (frame_ctx_p, lit_oc, @@ -852,6 +864,8 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ ECMA_FINALIZE (call_ret_value); + MEM_FINALIZE_LOCAL_ARRAY (arg_values); + if (call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) { JERRY_ASSERT (frame_ctx_p->is_call_in_direct_eval_form); @@ -870,15 +884,7 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ 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); - } - - MEM_FINALIZE_LOCAL_ARRAY (arg_values); - + ecma_free_values_collection (arg_collection_p, true); ecma_free_value (this_value, true); ECMA_FINALIZE (func_value); @@ -908,15 +914,14 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ get_variable_value (frame_ctx_p, constructor_name_lit_idx, false), ret_value); - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number, ecma_value_t); - frame_ctx_p->pos++; - ecma_length_t args_read; - ecma_completion_value_t get_arg_completion = fill_varg_list (frame_ctx_p, - args_number, - arg_values, - &args_read); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); + + ecma_completion_value_t get_arg_completion = vm_fill_varg_list (frame_ctx_p, + args_number, + arg_collection_p); + ecma_length_t args_read = arg_collection_p->unit_number; if (ecma_is_completion_value_empty (get_arg_completion)) { @@ -930,6 +935,19 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ { ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor_value); + MEM_DEFINE_LOCAL_ARRAY (arg_values, args_read, ecma_value_t); + + ecma_collection_iterator_t arg_collection_iter; + ecma_collection_iterator_init (&arg_collection_iter, + arg_collection_p); + + for (ecma_length_t arg_index = 0; + ecma_collection_iterator_next (&arg_collection_iter); + arg_index++) + { + arg_values[arg_index] = *arg_collection_iter.current_value_p; + } + ECMA_TRY_CATCH (construction_ret_value, ecma_op_function_construct (constructor_obj_p, arg_values, @@ -940,6 +958,8 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ construction_ret_value); ECMA_FINALIZE (construction_ret_value); + + MEM_FINALIZE_LOCAL_ARRAY (arg_values); } } else @@ -949,14 +969,7 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ 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); - } - - MEM_FINALIZE_LOCAL_ARRAY (arg_values); + ecma_free_values_collection (arg_collection_p, true); ECMA_FINALIZE (constructor_value); @@ -987,18 +1000,30 @@ opfunc_array_decl (vm_instr_t instr, /**< instruction */ ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number, ecma_value_t); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); - ecma_length_t args_read; - ecma_completion_value_t get_arg_completion = fill_varg_list (frame_ctx_p, - args_number, - arg_values, - &args_read); + ecma_completion_value_t get_arg_completion = vm_fill_varg_list (frame_ctx_p, + args_number, + arg_collection_p); + ecma_length_t args_read = arg_collection_p->unit_number; if (ecma_is_completion_value_empty (get_arg_completion)) { JERRY_ASSERT (args_read == args_number); + MEM_DEFINE_LOCAL_ARRAY (arg_values, args_read, ecma_value_t); + + ecma_collection_iterator_t arg_collection_iter; + ecma_collection_iterator_init (&arg_collection_iter, + arg_collection_p); + + for (ecma_length_t arg_index = 0; + ecma_collection_iterator_next (&arg_collection_iter); + arg_index++) + { + arg_values[arg_index] = *arg_collection_iter.current_value_p; + } + ECMA_TRY_CATCH (array_obj_value, ecma_op_create_array_object (arg_values, args_number, @@ -1010,6 +1035,8 @@ opfunc_array_decl (vm_instr_t instr, /**< instruction */ array_obj_value); ECMA_FINALIZE (array_obj_value); + + MEM_FINALIZE_LOCAL_ARRAY (arg_values); } else { @@ -1018,14 +1045,7 @@ opfunc_array_decl (vm_instr_t instr, /**< instruction */ 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); - } - - MEM_FINALIZE_LOCAL_ARRAY (arg_values); + ecma_free_values_collection (arg_collection_p, true); return ret_value; } /* opfunc_array_decl */