Index: src/runtime/runtime-object.cc |
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc |
index 5cf8c308a8d199b4fc35f4d583748444aedc2ea7..c20f7a0d5cdc56851a85f67e0b65641bd4cdf17a 100644 |
--- a/src/runtime/runtime-object.cc |
+++ b/src/runtime/runtime-object.cc |
@@ -1007,41 +1007,24 @@ RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { |
static Object* Runtime_NewObjectHelper(Isolate* isolate, |
- Handle<Object> constructor, |
- Handle<Object> new_target, |
+ Handle<JSFunction> constructor, |
+ Handle<JSReceiver> new_target, |
Handle<AllocationSite> site) { |
- // If the constructor isn't a proper function we throw a type error. |
- if (!constructor->IsJSFunction()) { |
- THROW_NEW_ERROR_RETURN_FAILURE( |
- isolate, NewTypeError(MessageTemplate::kNotConstructor, constructor)); |
- } |
- |
- Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); |
- |
- CHECK(new_target->IsJSFunction()); |
+ // TODO(verwaest): new_target could be a proxy. Read new.target.prototype in |
+ // that case. |
Handle<JSFunction> original_function = Handle<JSFunction>::cast(new_target); |
- |
- // Check that function is a constructor. |
- if (!function->IsConstructor()) { |
- THROW_NEW_ERROR_RETURN_FAILURE( |
- isolate, NewTypeError(MessageTemplate::kNotConstructor, constructor)); |
- } |
- |
// The function should be compiled for the optimization hints to be |
// available. |
- Compiler::Compile(function, CLEAR_EXCEPTION); |
+ Compiler::Compile(constructor, CLEAR_EXCEPTION); |
- JSFunction::EnsureHasInitialMap(function); |
- if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { |
- // The 'Function' function ignores the receiver object when |
- // called using 'new' and creates a new JSFunction object that |
- // is returned. |
- return isolate->heap()->undefined_value(); |
- } |
+ JSFunction::EnsureHasInitialMap(constructor); |
+ DCHECK_NE(JS_FUNCTION_TYPE, constructor->initial_map()->instance_type()); |
+ // TODO(verwaest): original_function could have non-instance-prototype |
+ // (non-JSReceiver), requiring fallback to the intrinsicDefaultProto. |
Handle<Map> initial_map = |
- JSFunction::EnsureDerivedHasInitialMap(original_function, function); |
+ JSFunction::EnsureDerivedHasInitialMap(original_function, constructor); |
Handle<JSObject> result = |
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); |
@@ -1056,8 +1039,23 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate, |
RUNTIME_FUNCTION(Runtime_NewObject) { |
HandleScope scope(isolate); |
DCHECK(args.length() == 2); |
- CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0); |
- CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 1); |
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, 1); |
+ |
+ // TODO(verwaest): Make sure |constructor| is guaranteed to be a constructor. |
+ if (!constructor->IsConstructor()) { |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, NewTypeError(MessageTemplate::kNotConstructor, constructor)); |
+ } |
+ |
+ // If called through new, new.target can be: |
+ // - a subclass of constructor, |
+ // - a proxy wrapper around constructor, or |
+ // - the constructor itself. |
+ // If called through Reflect.construct, it's guaranteed to be a constructor by |
+ // REFLECT_CONSTRUCT_PREPARE. |
+ DCHECK(new_target->IsConstructor()); |
+ |
return Runtime_NewObjectHelper(isolate, constructor, new_target, |
Handle<AllocationSite>::null()); |
} |