@@ -699,86 +699,6 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
699
699
}
700
700
} /* ecma_op_function_call */
701
701
702
- /**
703
- * [[Construct]] implementation for Function objects (13.2.2),
704
- * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION) and
705
- * externally defined (host) functions (ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION).
706
- *
707
- * @return ecma value
708
- * Returned value must be freed with ecma_free_value
709
- */
710
- static ecma_value_t
711
- ecma_op_function_construct_ecma_or_external (ecma_object_t * func_obj_p , /**< Function object */
712
- const ecma_value_t * arguments_list_p , /**< arguments list */
713
- ecma_length_t arguments_list_len ) /**< length of arguments list */
714
- {
715
- JERRY_ASSERT (ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_FUNCTION
716
- || ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION );
717
-
718
- /* 5. */
719
- ecma_value_t prototype_prop_value = ecma_op_object_get_by_magic_id (func_obj_p ,
720
- LIT_MAGIC_STRING_PROTOTYPE );
721
-
722
- if (ECMA_IS_VALUE_ERROR (prototype_prop_value ))
723
- {
724
- return prototype_prop_value ;
725
- }
726
-
727
- /* 1., 2., 4. */
728
- ecma_object_t * obj_p ;
729
- if (ecma_is_value_object (prototype_prop_value ))
730
- {
731
- /* 6. */
732
- obj_p = ecma_create_object (ecma_get_object_from_value (prototype_prop_value ),
733
- 0 ,
734
- ECMA_OBJECT_TYPE_GENERAL );
735
- }
736
- else
737
- {
738
- /* 7. */
739
- ecma_object_t * prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE );
740
-
741
- obj_p = ecma_create_object (prototype_p , 0 , ECMA_OBJECT_TYPE_GENERAL );
742
-
743
- ecma_deref_object (prototype_p );
744
- }
745
-
746
- ecma_free_value (prototype_prop_value );
747
-
748
- /* 3. */
749
- /*
750
- * [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
751
- * without ECMA_INTERNAL_PROPERTY_CLASS internal property
752
- * is "Object".
753
- *
754
- * See also: ecma_object_get_class_name.
755
- */
756
-
757
- /* 8. */
758
- ecma_value_t this_obj = ecma_make_object_value (obj_p );
759
- ecma_value_t ret_value ;
760
-
761
- if (ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_FUNCTION )
762
- {
763
- arguments_list_p = ecma_op_function_set_construct_flag (arguments_list_p );
764
- }
765
-
766
- ret_value = ecma_op_function_call (func_obj_p ,
767
- this_obj ,
768
- arguments_list_p ,
769
- arguments_list_len );
770
-
771
- /* 9. */
772
- if (ECMA_IS_VALUE_ERROR (ret_value ) || ecma_is_value_object (ret_value ))
773
- {
774
- ecma_deref_object (obj_p );
775
- return ret_value ;
776
- }
777
-
778
- ecma_fast_free_value (ret_value );
779
- return this_obj ;
780
- } /* ecma_op_function_construct_ecma_or_external */
781
-
782
702
/**
783
703
* [[Construct]] implementation:
784
704
* 13.2.2 - for Function objects, created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION),
@@ -790,51 +710,18 @@ ecma_op_function_construct_ecma_or_external (ecma_object_t *func_obj_p, /**< Fun
790
710
*/
791
711
ecma_value_t
792
712
ecma_op_function_construct (ecma_object_t * func_obj_p , /**< Function object */
713
+ ecma_value_t this_arg_value , /**< optional 'this' argument's value or ECMA_VALUE_UNDEFINED */
793
714
const ecma_value_t * arguments_list_p , /**< arguments list */
794
715
ecma_length_t arguments_list_len ) /**< length of arguments list */
795
716
{
796
717
JERRY_ASSERT (func_obj_p != NULL
797
718
&& !ecma_is_lexical_environment (func_obj_p ));
798
719
799
- while (true)
800
- {
801
- switch (ecma_get_object_type (func_obj_p ))
802
- {
803
- case ECMA_OBJECT_TYPE_FUNCTION :
804
- {
805
- if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p )))
806
- {
807
- if (ecma_builtin_function_is_routine (func_obj_p ))
808
- {
809
- return ecma_raise_type_error (ECMA_ERR_MSG ("Built-in routines have no constructor." ));
810
- }
811
-
812
- return ecma_builtin_dispatch_construct (func_obj_p ,
813
- arguments_list_p ,
814
- arguments_list_len );
815
- }
816
- /* FALLTHRU */
817
- }
818
- case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION :
819
- {
820
- return ecma_op_function_construct_ecma_or_external (func_obj_p ,
821
- arguments_list_p ,
822
- arguments_list_len );
823
- }
824
- #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
825
- case ECMA_OBJECT_TYPE_ARROW_FUNCTION :
826
- {
827
- return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor." ));
828
- }
829
- #endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
830
- default :
831
- {
832
- break ;
833
- }
834
- }
835
-
836
- JERRY_ASSERT (ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_BOUND_FUNCTION );
720
+ JERRY_ASSERT (ecma_is_value_object (this_arg_value )
721
+ || this_arg_value == ECMA_VALUE_UNDEFINED );
837
722
723
+ while (JERRY_UNLIKELY (ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_BOUND_FUNCTION ))
724
+ {
838
725
/* 1-3. */
839
726
ecma_extended_object_t * ext_function_p = (ecma_extended_object_t * ) func_obj_p ;
840
727
@@ -874,13 +761,117 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
874
761
875
762
/* 5. */
876
763
ret_value = ecma_op_function_construct (target_func_obj_p ,
764
+ this_arg_value ,
877
765
merged_args_list_p ,
878
766
merged_args_list_len );
879
767
880
768
JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p );
881
769
882
770
return ret_value ;
883
771
}
772
+
773
+ ecma_object_type_t type = ecma_get_object_type (func_obj_p );
774
+
775
+ #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
776
+ if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_ARROW_FUNCTION ))
777
+ {
778
+ return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor." ));
779
+ }
780
+ #endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
781
+
782
+ if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_get_object_is_builtin (func_obj_p )))
783
+ {
784
+ if (ecma_builtin_function_is_routine (func_obj_p ))
785
+ {
786
+ return ecma_raise_type_error (ECMA_ERR_MSG ("Built-in routines have no constructor." ));
787
+ }
788
+
789
+ return ecma_builtin_dispatch_construct (func_obj_p ,
790
+ arguments_list_p ,
791
+ arguments_list_len );
792
+ }
793
+
794
+ ecma_object_t * new_this_obj_p = NULL ;
795
+
796
+ if (JERRY_LIKELY (this_arg_value == ECMA_VALUE_UNDEFINED ))
797
+ {
798
+ /* 5. */
799
+ ecma_value_t prototype_prop_value = ecma_op_object_get_by_magic_id (func_obj_p ,
800
+ LIT_MAGIC_STRING_PROTOTYPE );
801
+
802
+ if (ECMA_IS_VALUE_ERROR (prototype_prop_value ))
803
+ {
804
+ return prototype_prop_value ;
805
+ }
806
+
807
+ /* 1., 2., 4. */
808
+ if (ecma_is_value_object (prototype_prop_value ))
809
+ {
810
+ /* 6. */
811
+ new_this_obj_p = ecma_create_object (ecma_get_object_from_value (prototype_prop_value ),
812
+ 0 ,
813
+ ECMA_OBJECT_TYPE_GENERAL );
814
+ }
815
+ else
816
+ {
817
+ /* 7. */
818
+ ecma_object_t * prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE );
819
+
820
+ new_this_obj_p = ecma_create_object (prototype_p , 0 , ECMA_OBJECT_TYPE_GENERAL );
821
+
822
+ ecma_deref_object (prototype_p );
823
+ }
824
+
825
+ ecma_free_value (prototype_prop_value );
826
+
827
+ this_arg_value = ecma_make_object_value (new_this_obj_p );
828
+ }
829
+
830
+ /* 8. */
831
+ ecma_value_t ret_value ;
832
+
833
+ switch (type )
834
+ {
835
+ case ECMA_OBJECT_TYPE_FUNCTION :
836
+ {
837
+ arguments_list_p = ecma_op_function_set_construct_flag (arguments_list_p );
838
+
839
+ ret_value = ecma_op_function_call (func_obj_p ,
840
+ this_arg_value ,
841
+ arguments_list_p ,
842
+ arguments_list_len );
843
+ break ;
844
+ }
845
+ default :
846
+ {
847
+ JERRY_ASSERT (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION );
848
+
849
+ ret_value = ecma_op_function_call (func_obj_p ,
850
+ this_arg_value ,
851
+ arguments_list_p ,
852
+ arguments_list_len );
853
+ break ;
854
+ }
855
+ }
856
+
857
+ /* 9. */
858
+ if (ECMA_IS_VALUE_ERROR (ret_value ) || ecma_is_value_object (ret_value ))
859
+ {
860
+ if (new_this_obj_p != NULL )
861
+ {
862
+ ecma_deref_object (new_this_obj_p );
863
+ }
864
+ return ret_value ;
865
+ }
866
+
867
+ ecma_fast_free_value (ret_value );
868
+
869
+ if (JERRY_UNLIKELY (new_this_obj_p == NULL ))
870
+ {
871
+ ecma_ref_object (ecma_get_object_from_value (this_arg_value ));
872
+ }
873
+
874
+ return this_arg_value ;
884
875
} /* ecma_op_function_construct */
885
876
886
877
/**
0 commit comments