Commit b478e9c1 authored by vabr's avatar vabr Committed by Commit bot

Fix TypeError message for Reflect.construct

If the Reflect.construct receives an argument expected to be a constructor,
and the argument is not a constructor, V8 currently declares that
Reflect.construct is not a function. It should instead say that the offending
argument is not a constructor.

This is the case for all ports of builtins
(Builtins::Generate_ReflectConstruct). All of them make an
attempt to at least pass the right argument to the TypeError parametrised
message, calling out the offending Reflect.construct argument. However,
Runtime::kThrowCalledNonCallable extracts the callsite from those arguments,
discarding the precise information.

This CL adds Runtime::kNotConstructor, which reports the arguments passed
to it, and the CL also modifies the ports of builtins to make use of
Runtime::kNotConstructor

BUG=v8:5671

Review-Url: https://codereview.chromium.org/2688393003
Cr-Commit-Position: refs/heads/master@{#43182}
parent 296553bf
......@@ -2093,14 +2093,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ str(r1, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ str(r3, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -2148,14 +2148,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ Bind(&target_not_constructor);
{
__ Poke(target, 0);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ Bind(&new_target_not_constructor);
{
__ Poke(new_target, 0);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -1650,14 +1650,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ mov(Operand(esp, kPointerSize), edi);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ mov(Operand(esp, kPointerSize), edx);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -2120,14 +2120,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ sw(a1, MemOperand(sp));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ sw(a3, MemOperand(sp));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -2124,14 +2124,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ sd(target, MemOperand(sp));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ sd(new_target, MemOperand(sp));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -2144,14 +2144,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ StoreP(r4, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ StoreP(r6, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -2148,14 +2148,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ StoreP(r3, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ StoreP(r5, MemOperand(sp, 0));
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -1610,7 +1610,7 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
{
StackArgumentsAccessor args(rsp, 0);
__ movp(args.GetReceiverOperand(), rdi);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
......@@ -1618,7 +1618,7 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
{
StackArgumentsAccessor args(rsp, 0);
__ movp(args.GetReceiverOperand(), rdx);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -1617,14 +1617,14 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
__ bind(&target_not_constructor);
{
__ mov(Operand(esp, kPointerSize), edi);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
// 4c. The new.target is not a constructor, throw an appropriate TypeError.
__ bind(&new_target_not_constructor);
{
__ mov(Operand(esp, kPointerSize), edx);
__ TailCallRuntime(Runtime::kThrowCalledNonCallable);
__ TailCallRuntime(Runtime::kThrowNotConstructor);
}
}
......
......@@ -237,6 +237,14 @@ RUNTIME_FUNCTION(Runtime_ThrowNonObjectInInstanceOfCheck) {
isolate, NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck));
}
RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kNotConstructor, object));
}
RUNTIME_FUNCTION(Runtime_ThrowNotGeneric) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......@@ -378,7 +386,6 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) {
} // namespace
RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......
......@@ -321,6 +321,7 @@ namespace internal {
F(ThrowSymbolIteratorInvalid, 0, 1) \
F(ThrowNonCallableInInstanceOfCheck, 0, 1) \
F(ThrowNonObjectInInstanceOfCheck, 0, 1) \
F(ThrowNotConstructor, 1, 1) \
F(ThrowNotGeneric, 1, 1) \
F(ThrowReferenceError, 1, 1) \
F(ThrowStackOverflow, 0, 1) \
......
......@@ -17,6 +17,30 @@
})();
(function testReflectConstructArg1NonConstructor() {
try {
Reflect.construct(() => {}, []);
} catch (e) {
assertInstanceof(e, TypeError);
assertEquals("() => {} is not a constructor", e.message);
return;
}
assertUnreachable("Exception expected");
})();
(function testReflectConstructArg3NonConstructor() {
try {
Reflect.construct(function() {}, [], () => {});
} catch (e) {
assertInstanceof(e, TypeError);
assertEquals("() => {} is not a constructor", e.message);
return;
}
assertUnreachable("Exception expected");
})();
(function testReflectConstructBasic() {
function Constructor() { "use strict"; }
assertInstanceof(Reflect.construct(Constructor, []), Constructor);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment