diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index 76120297d..ea3574d04 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -68,7 +68,7 @@ run_int (void) switch ((ecma_completion_type_t) completion.type) { case ECMA_COMPLETION_TYPE_NORMAL: - case ECMA_COMPLETION_TYPE_VARG: + case ECMA_COMPLETION_TYPE_META: { JERRY_UNREACHABLE (); } @@ -170,8 +170,6 @@ run_int_from_pos (opcode_counter_t start_pos, completion = run_int_loop (&int_data); - JERRY_ASSERT (completion.type != ECMA_COMPLETION_TYPE_VARG); - for (uint32_t reg_index = 0; reg_index < regs_num; reg_index++) diff --git a/src/libcoreint/opcodes-ecma-support.h b/src/libcoreint/opcodes-ecma-support.h index 9a02af2fd..495a27019 100644 --- a/src/libcoreint/opcodes-ecma-support.h +++ b/src/libcoreint/opcodes-ecma-support.h @@ -37,4 +37,7 @@ ecma_completion_value_t fill_varg_list (int_data_t *int_data, ecma_length_t args_number, ecma_value_t args_values[], ecma_length_t *out_arg_number_p); +void fill_params_list (int_data_t *int_data, + ecma_length_t params_number, + ecma_string_t* params_names[]); #endif /* OPCODES_ECMA_SUPPORT_H */ diff --git a/src/libcoreint/opcodes-varg.c b/src/libcoreint/opcodes-varg.c index 6c27d0a3e..2faa97c7c 100644 --- a/src/libcoreint/opcodes-varg.c +++ b/src/libcoreint/opcodes-varg.c @@ -33,39 +33,42 @@ fill_varg_list (int_data_t *int_data, /**< interpreter context */ ecma_length_t *out_arg_number_p) /**< out: number of arguments successfully read */ { - ecma_completion_value_t get_arg_completion = ecma_make_empty_completion_value (); + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_length_t arg_index; for (arg_index = 0; arg_index < args_number; arg_index++) { - opcode_t next_opcode = read_opcode (int_data->pos); - if (next_opcode.op_idx == __op__idx_varg) + ecma_completion_value_t evaluate_arg_completion = run_int_loop (int_data); + + if (evaluate_arg_completion.type == ECMA_COMPLETION_TYPE_META) { - get_arg_completion = get_variable_value (int_data, next_opcode.data.varg.arg_lit_idx, false); - if (unlikely (ecma_is_completion_value_throw (get_arg_completion))) + opcode_t next_opcode = read_opcode (int_data->pos); + JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); + JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG); + + const idx_t varg_var_idx = next_opcode.data.meta.data_1; + + ecma_completion_value_t get_arg_completion = get_variable_value (int_data, varg_var_idx, false); + + if (ecma_is_completion_value_normal (get_arg_completion)) { - break; + arg_values[arg_index] = get_arg_completion.value; } else { - JERRY_ASSERT (ecma_is_completion_value_normal (get_arg_completion)); - arg_values[arg_index] = get_arg_completion.value; + ret_value = get_arg_completion; } } else { - get_arg_completion = run_int_loop (int_data); + ret_value = evaluate_arg_completion; + } - if (get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG) - { - arg_values[arg_index] = get_arg_completion.value; - } - else - { - break; - } + if (!ecma_is_empty_completion_value (ret_value)) + { + break; } int_data->pos++; @@ -73,38 +76,32 @@ fill_varg_list (int_data_t *int_data, /**< interpreter context */ *out_arg_number_p = arg_index; - if (get_arg_completion.type == ECMA_COMPLETION_TYPE_NORMAL - || get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG) - { - /* values are copied to arg_values */ - return ecma_make_empty_completion_value (); - } - else - { - return get_arg_completion; - } + return ret_value; } /* fill_varg_list */ /** - * 'varg' opcode handler - * - * @return completion value - * Returned value must be freed with ecma_free_completion_value. + * Fill parameters' list */ -ecma_completion_value_t -opfunc_varg (opcode_t opdata, /**< operation data */ - int_data_t *int_data) /**< interpreter context */ +void +fill_params_list (int_data_t *int_data, /**< interpreter context */ + ecma_length_t params_number, /**< number of parameters */ + ecma_string_t* params_names[]) /**< out: parameters' names */ { - const idx_t arg_lit_idx = opdata.data.varg.arg_lit_idx; - - ecma_completion_value_t completion = get_variable_value (int_data, - arg_lit_idx, - false); - - if (ecma_is_completion_value_normal (completion)) + uint32_t param_index; + for (param_index = 0; + param_index < params_number; + param_index++) { - completion.type = ECMA_COMPLETION_TYPE_VARG; + opcode_t next_opcode = read_opcode (int_data->pos); + JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta); + JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG); + + const idx_t param_name_lit_idx = next_opcode.data.meta.data_1; + + params_names [param_index] = ecma_new_ecma_string_from_lit_index (param_name_lit_idx); + + int_data->pos++; } - return completion; -} /* opfunc_varg */ + JERRY_ASSERT (param_index == params_number); +} /* fill_params_list */ diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 69863a281..ede4ed8b2 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -578,34 +578,21 @@ opfunc_func_decl_n (opcode_t opdata, /**< operation data */ int_data->pos++; const idx_t function_name_idx = opdata.data.func_decl_n.name_lit_idx; - const ecma_length_t args_number = opdata.data.func_decl_n.arg_list; + const ecma_length_t params_number = opdata.data.func_decl_n.arg_list; - ecma_string_t *args_names[args_number + 1 /* length of array should not be zero */]; - - ecma_length_t arg_index = 0; - opcode_t next_opcode = read_opcode (int_data->pos); - while (next_opcode.op_idx == __op__idx_varg) - { - const idx_t arg_lit_idx = next_opcode.data.varg.arg_lit_idx; - args_names[arg_index++] = ecma_new_ecma_string_from_lit_index (arg_lit_idx); - - JERRY_ASSERT (arg_index <= args_number); - - int_data->pos++; - next_opcode = read_opcode (int_data->pos); - } - JERRY_ASSERT (arg_index == args_number); + ecma_string_t *params_names[params_number + 1 /* length of array should not be zero */]; + fill_params_list (int_data, params_number, params_names); ecma_completion_value_t ret_value = function_declaration (int_data, function_name_idx, - args_names, - args_number); + params_names, + params_number); - for (arg_index = 0; - arg_index < args_number; - arg_index++) + for (uint32_t param_index = 0; + param_index < params_number; + param_index++) { - ecma_deref_ecma_string (args_names[arg_index]); + ecma_deref_ecma_string (params_names[param_index]); } return ret_value; @@ -625,7 +612,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ const idx_t dst_var_idx = opdata.data.func_expr_n.lhs; const idx_t function_name_lit_idx = opdata.data.func_expr_n.name_lit_idx; - const ecma_length_t args_number = opdata.data.func_expr_n.arg_list; + const ecma_length_t params_number = opdata.data.func_expr_n.arg_list; const bool is_named_func_expr = (!is_reg_variable (int_data, function_name_lit_idx)); @@ -633,21 +620,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ const bool is_strict = int_data->is_strict; - ecma_string_t *args_names[args_number + 1 /* length of array should not be zero */]; + ecma_string_t *params_names[params_number + 1 /* length of array should not be zero */]; - ecma_length_t arg_index = 0; - opcode_t next_opcode = read_opcode (int_data->pos); - while (next_opcode.op_idx == __op__idx_varg) - { - const idx_t arg_lit_idx = next_opcode.data.varg.arg_lit_idx; - args_names[arg_index++] = ecma_new_ecma_string_from_lit_index (arg_lit_idx); - - JERRY_ASSERT (arg_index <= args_number); - - int_data->pos++; - next_opcode = read_opcode (int_data->pos); - } - JERRY_ASSERT (arg_index == args_number); + fill_params_list (int_data, params_number, params_names); const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos); opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx); @@ -671,8 +646,8 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ ecma_ref_object (scope_p); } - ecma_object_t *func_obj_p = ecma_op_create_function_object (args_names, - args_number, + ecma_object_t *func_obj_p = ecma_op_create_function_object (params_names, + params_number, scope_p, is_strict, function_code_opcode_idx); @@ -692,11 +667,11 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ ecma_deref_object (func_obj_p); ecma_deref_object (scope_p); - for (arg_index = 0; - arg_index < args_number; - arg_index++) + for (uint32_t param_index = 0; + param_index < params_number; + param_index++) { - ecma_deref_ecma_string (args_names[arg_index]); + ecma_deref_ecma_string (params_names[param_index]); } return ret_value; @@ -1549,12 +1524,28 @@ opfunc_delete_prop (opcode_t opdata, /**< operation data */ /** * 'meta' opcode handler. * - * The opcode is meta-opcode that is not supposed to be executed. + * @return implementation-defined meta completion value */ ecma_completion_value_t -opfunc_meta (opcode_t opdata __unused, /**< operation data */ +opfunc_meta (opcode_t opdata, /**< operation data */ int_data_t *int_data __unused) /**< interpreter context */ { + const opcode_meta_type type = opdata.data.meta.type; + + switch (type) + { + case OPCODE_META_TYPE_VARG: + { + return ecma_make_completion_value (ECMA_COMPLETION_TYPE_META, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY), + ECMA_TARGET_ID_RESERVED); + } + case OPCODE_META_TYPE_THIS_ARG: + { + JERRY_UNREACHABLE (); + } + } + JERRY_UNREACHABLE (); } /* opfunc_meta */ diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index bb6cef5b0..aa2ddc7a4 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -52,7 +52,8 @@ typedef enum */ typedef enum { - OPCODE_META_TYPE_THIS_ARG /**< value of this used during call */ + OPCODE_META_TYPE_THIS_ARG, /**< value of this used during call */ + OPCODE_META_TYPE_VARG /**< element of arguments' list */ } opcode_meta_type; typedef struct @@ -78,7 +79,6 @@ typedef struct p##_3 (a, func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx) \ p##_2 (a, func_decl_n, name_lit_idx, arg_list) \ p##_3 (a, func_expr_n, lhs, name_lit_idx, arg_list) \ - p##_1 (a, varg, arg_lit_idx) \ p##_1 (a, exitval, status_code) \ p##_1 (a, retval, ret_value) \ p##_0 (a, ret) diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index 35ffb6ba4..69898cd93 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -106,8 +106,8 @@ typedef enum ECMA_COMPLETION_TYPE_THROW, /**< block completed with throw */ ECMA_COMPLETION_TYPE_EXIT, /**< implementation-defined completion type for finishing script execution */ - ECMA_COMPLETION_TYPE_VARG /**< implementation-defined completion type - for varg (argument value specifier opcode) */ + ECMA_COMPLETION_TYPE_META /**< implementation-defined completion type + for meta opcode */ } ecma_completion_type_t; /** diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index 990c55345..003a1e9ca 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -365,12 +365,11 @@ ecma_copy_completion_value (ecma_completion_value_t value) /**< completion value void ecma_free_completion_value (ecma_completion_value_t completion_value) /**< completion value */ { - switch (completion_value.type) + switch ((ecma_completion_type_t)completion_value.type) { case ECMA_COMPLETION_TYPE_NORMAL: case ECMA_COMPLETION_TYPE_THROW: case ECMA_COMPLETION_TYPE_RETURN: - case ECMA_COMPLETION_TYPE_VARG: { ecma_free_value (completion_value.value, true); break; @@ -382,6 +381,10 @@ ecma_free_completion_value (ecma_completion_value_t completion_value) /**< compl JERRY_ASSERT(completion_value.value.value_type == ECMA_TYPE_SIMPLE); break; } + case ECMA_COMPLETION_TYPE_META: + { + JERRY_UNREACHABLE (); + } } } /* ecma_free_completion_value */ diff --git a/src/liboptimizer/pretty-printer.c b/src/liboptimizer/pretty-printer.c index 70c5cc646..f90672544 100644 --- a/src/liboptimizer/pretty-printer.c +++ b/src/liboptimizer/pretty-printer.c @@ -412,7 +412,6 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite) CASE_VARG_1_NAME (func_decl_1, "function", name_lit_idx, "(", arg1_lit_idx, ")") CASE_VARG_2_NAME (func_decl_2, "function", name_lit_idx, "(", arg1_lit_idx, arg2_lit_idx, ")") CASE_VARG_N_NAME (func_decl_n, "function", name_lit_idx, arg_list) - CASE_VARG_1 (varg, arg_lit_idx); CASE_EXIT (exitval, "exit", status_code) CASE_SINGLE_ADDRESS (retval, "return", ret_value) CASE_ZERO_ADDRESS (ret, "return")