39
39
* The operator should return from the opcode handler with it's 'return value'.
40
40
*
41
41
* 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.
42
46
*/
43
47
44
48
#define OP_UNIMPLEMENTED_LIST (op ) \
@@ -690,6 +694,72 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
690
694
return ret_value;
691
695
} /* opfunc_func_expr_n */
692
696
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
+
693
763
/* *
694
764
* 'Function call' opcode handler.
695
765
*
@@ -713,28 +783,10 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
713
783
714
784
int_data->pos ++;
715
785
716
- idx_t this_arg_var_idx = INVALID_VALUE;
717
-
718
- opcode_call_flags_t call_flags = OPCODE_CALL_FLAGS__EMPTY;
719
-
720
786
JERRY_ASSERT (!int_data->is_call_in_direct_eval_form );
721
787
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);
738
790
739
791
MEM_DEFINE_LOCAL_ARRAY (arg_values, args_number_idx, ecma_value_t );
740
792
@@ -748,20 +800,6 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
748
800
{
749
801
JERRY_ASSERT (args_read == args_number_idx);
750
802
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
-
765
803
if (!ecma_op_is_callable (func_value))
766
804
{
767
805
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 */
798
836
JERRY_ASSERT (!int_data->is_call_in_direct_eval_form );
799
837
}
800
838
}
801
-
802
- ecma_free_completion_value (get_this_completion_value);
803
839
}
804
840
else
805
841
{
@@ -817,6 +853,8 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
817
853
818
854
MEM_FINALIZE_LOCAL_ARRAY (arg_values);
819
855
856
+ ecma_free_value (this_value, true );
857
+
820
858
ECMA_FINALIZE (func_value);
821
859
822
860
return ret_value;
0 commit comments