@@ -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,19 @@ 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' object value
714
+ * or ECMA_VALUE_UNDEFINED */
793
715
const ecma_value_t * arguments_list_p , /**< arguments list */
794
716
ecma_length_t arguments_list_len ) /**< length of arguments list */
795
717
{
796
718
JERRY_ASSERT (func_obj_p != NULL
797
719
&& !ecma_is_lexical_environment (func_obj_p ));
798
720
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 );
721
+ JERRY_ASSERT (ecma_is_value_object (this_arg_value )
722
+ || this_arg_value == ECMA_VALUE_UNDEFINED );
837
723
724
+ while (JERRY_UNLIKELY (ecma_get_object_type (func_obj_p ) == ECMA_OBJECT_TYPE_BOUND_FUNCTION ))
725
+ {
838
726
/* 1-3. */
839
727
ecma_extended_object_t * ext_function_p = (ecma_extended_object_t * ) func_obj_p ;
840
728
@@ -874,13 +762,117 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
874
762
875
763
/* 5. */
876
764
ret_value = ecma_op_function_construct (target_func_obj_p ,
765
+ this_arg_value ,
877
766
merged_args_list_p ,
878
767
merged_args_list_len );
879
768
880
769
JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p );
881
770
882
771
return ret_value ;
883
772
}
773
+
774
+ ecma_object_type_t type = ecma_get_object_type (func_obj_p );
775
+
776
+ #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
777
+ if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_ARROW_FUNCTION ))
778
+ {
779
+ return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor." ));
780
+ }
781
+ #endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
782
+
783
+ if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_get_object_is_builtin (func_obj_p )))
784
+ {
785
+ if (ecma_builtin_function_is_routine (func_obj_p ))
786
+ {
787
+ return ecma_raise_type_error (ECMA_ERR_MSG ("Built-in routines have no constructor." ));
788
+ }
789
+
790
+ return ecma_builtin_dispatch_construct (func_obj_p ,
791
+ arguments_list_p ,
792
+ arguments_list_len );
793
+ }
794
+
795
+ ecma_object_t * new_this_obj_p = NULL ;
796
+
797
+ if (JERRY_LIKELY (this_arg_value == ECMA_VALUE_UNDEFINED ))
798
+ {
799
+ /* 5. */
800
+ ecma_value_t prototype_prop_value = ecma_op_object_get_by_magic_id (func_obj_p ,
801
+ LIT_MAGIC_STRING_PROTOTYPE );
802
+
803
+ if (ECMA_IS_VALUE_ERROR (prototype_prop_value ))
804
+ {
805
+ return prototype_prop_value ;
806
+ }
807
+
808
+ /* 1., 2., 4. */
809
+ if (ecma_is_value_object (prototype_prop_value ))
810
+ {
811
+ /* 6. */
812
+ new_this_obj_p = ecma_create_object (ecma_get_object_from_value (prototype_prop_value ),
813
+ 0 ,
814
+ ECMA_OBJECT_TYPE_GENERAL );
815
+ }
816
+ else
817
+ {
818
+ /* 7. */
819
+ ecma_object_t * prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE );
820
+
821
+ new_this_obj_p = ecma_create_object (prototype_p , 0 , ECMA_OBJECT_TYPE_GENERAL );
822
+
823
+ ecma_deref_object (prototype_p );
824
+ }
825
+
826
+ ecma_free_value (prototype_prop_value );
827
+
828
+ this_arg_value = ecma_make_object_value (new_this_obj_p );
829
+ }
830
+
831
+ /* 8. */
832
+ ecma_value_t ret_value ;
833
+
834
+ switch (type )
835
+ {
836
+ case ECMA_OBJECT_TYPE_FUNCTION :
837
+ {
838
+ arguments_list_p = ecma_op_function_set_construct_flag (arguments_list_p );
839
+
840
+ ret_value = ecma_op_function_call (func_obj_p ,
841
+ this_arg_value ,
842
+ arguments_list_p ,
843
+ arguments_list_len );
844
+ break ;
845
+ }
846
+ default :
847
+ {
848
+ JERRY_ASSERT (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION );
849
+
850
+ ret_value = ecma_op_function_call (func_obj_p ,
851
+ this_arg_value ,
852
+ arguments_list_p ,
853
+ arguments_list_len );
854
+ break ;
855
+ }
856
+ }
857
+
858
+ /* 9. */
859
+ if (ECMA_IS_VALUE_ERROR (ret_value ) || ecma_is_value_object (ret_value ))
860
+ {
861
+ if (new_this_obj_p != NULL )
862
+ {
863
+ ecma_deref_object (new_this_obj_p );
864
+ }
865
+ return ret_value ;
866
+ }
867
+
868
+ ecma_fast_free_value (ret_value );
869
+
870
+ if (JERRY_UNLIKELY (new_this_obj_p == NULL ))
871
+ {
872
+ ecma_ref_object (ecma_get_object_from_value (this_arg_value ));
873
+ }
874
+
875
+ return this_arg_value ;
884
876
} /* ecma_op_function_construct */
885
877
886
878
/**
0 commit comments