Skip to content

Commit f2ec124

Browse files
Fix get_variable_value invocation in opfunc_call_n.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan [email protected]
1 parent 9239845 commit f2ec124

File tree

1 file changed

+74
-36
lines changed

1 file changed

+74
-36
lines changed

jerry-core/vm/opcodes.cpp

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
* The operator should return from the opcode handler with it's 'return value'.
4040
*
4141
* 5. No other operations with opcode handler's 'return value' variable should be performed.
42+
*
43+
* Note:
44+
* get_variable_value, taking an idx should be called with instruction counter value,
45+
* corresponding to the instruction, containing the idx argument.
4246
*/
4347

4448
#define OP_UNIMPLEMENTED_LIST(op) \
@@ -690,6 +694,72 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
690694
return ret_value;
691695
} /* opfunc_func_expr_n */
692696

697+
/**
698+
* Get 'this' argument value and call flags mask for function call
699+
*
700+
* See also:
701+
* ECMA-262 v5, 11.2.3, steps 6-7
702+
703+
* @return ecma-value
704+
* Returned value must be freed with ecma_free_value
705+
*/
706+
static ecma_value_t
707+
vm_helper_call_get_call_flags_and_this_arg (int_data_t *int_data_p, /**< interpreter context */
708+
opcode_call_flags_t *out_flags_p) /**< out: call flags */
709+
{
710+
JERRY_ASSERT (out_flags_p != NULL);
711+
712+
bool is_increase_instruction_pointer;
713+
714+
opcode_call_flags_t call_flags = OPCODE_CALL_FLAGS__EMPTY;
715+
idx_t this_arg_var_idx = INVALID_VALUE;
716+
717+
opcode_t next_opcode = vm_get_opcode (int_data_p->opcodes_p, int_data_p->pos);
718+
if (next_opcode.op_idx == __op__idx_meta
719+
&& next_opcode.data.meta.type == OPCODE_META_TYPE_CALL_SITE_INFO)
720+
{
721+
call_flags = (opcode_call_flags_t) next_opcode.data.meta.data_1;
722+
723+
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
724+
{
725+
this_arg_var_idx = next_opcode.data.meta.data_2;
726+
JERRY_ASSERT (is_reg_variable (int_data_p, this_arg_var_idx));
727+
728+
JERRY_ASSERT ((call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) == 0);
729+
}
730+
731+
is_increase_instruction_pointer = true;
732+
}
733+
else
734+
{
735+
is_increase_instruction_pointer = false;
736+
}
737+
738+
ecma_completion_value_t get_this_completion_value;
739+
ecma_value_t this_value;
740+
741+
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
742+
{
743+
get_this_completion_value = get_variable_value (int_data_p, this_arg_var_idx, false);
744+
}
745+
else
746+
{
747+
get_this_completion_value = ecma_op_implicit_this_value (int_data_p->lex_env_p);
748+
}
749+
JERRY_ASSERT (ecma_is_completion_value_normal (get_this_completion_value));
750+
751+
this_value = ecma_get_completion_value_value (get_this_completion_value);
752+
753+
if (is_increase_instruction_pointer)
754+
{
755+
int_data_p->pos++;
756+
}
757+
758+
*out_flags_p = call_flags;
759+
760+
return this_value;
761+
} /* vm_helper_call_get_call_flags_and_this_arg */
762+
693763
/**
694764
* 'Function call' opcode handler.
695765
*
@@ -713,28 +783,10 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
713783

714784
int_data->pos++;
715785

716-
idx_t this_arg_var_idx = INVALID_VALUE;
717-
718-
opcode_call_flags_t call_flags = OPCODE_CALL_FLAGS__EMPTY;
719-
720786
JERRY_ASSERT (!int_data->is_call_in_direct_eval_form);
721787

722-
opcode_t next_opcode = vm_get_opcode (int_data->opcodes_p, int_data->pos);
723-
if (next_opcode.op_idx == __op__idx_meta
724-
&& next_opcode.data.meta.type == OPCODE_META_TYPE_CALL_SITE_INFO)
725-
{
726-
call_flags = (opcode_call_flags_t) next_opcode.data.meta.data_1;
727-
728-
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
729-
{
730-
this_arg_var_idx = next_opcode.data.meta.data_2;
731-
JERRY_ASSERT (is_reg_variable (int_data, this_arg_var_idx));
732-
733-
JERRY_ASSERT ((call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) == 0);
734-
}
735-
736-
int_data->pos++;
737-
}
788+
opcode_call_flags_t call_flags;
789+
ecma_value_t this_value = vm_helper_call_get_call_flags_and_this_arg (int_data, &call_flags);
738790

739791
MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number_idx, ecma_value_t);
740792

@@ -748,20 +800,6 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
748800
{
749801
JERRY_ASSERT (args_read == args_number_idx);
750802

751-
ecma_completion_value_t get_this_completion_value;
752-
753-
if (call_flags & OPCODE_CALL_FLAGS_HAVE_THIS_ARG)
754-
{
755-
get_this_completion_value = get_variable_value (int_data, this_arg_var_idx, false);
756-
}
757-
else
758-
{
759-
get_this_completion_value = ecma_op_implicit_this_value (int_data->lex_env_p);
760-
}
761-
JERRY_ASSERT (ecma_is_completion_value_normal (get_this_completion_value));
762-
763-
ecma_value_t this_value = ecma_get_completion_value_value (get_this_completion_value);
764-
765803
if (!ecma_op_is_callable (func_value))
766804
{
767805
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
@@ -798,8 +836,6 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
798836
JERRY_ASSERT (!int_data->is_call_in_direct_eval_form);
799837
}
800838
}
801-
802-
ecma_free_completion_value (get_this_completion_value);
803839
}
804840
else
805841
{
@@ -817,6 +853,8 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
817853

818854
MEM_FINALIZE_LOCAL_ARRAY (arg_values);
819855

856+
ecma_free_value (this_value, true);
857+
820858
ECMA_FINALIZE (func_value);
821859

822860
return ret_value;

0 commit comments

Comments
 (0)