Commit 0d726624 authored by adamk's avatar adamk Committed by Commit bot

Improve error message for calling super() twice in a derived constructor

Previously the message was "this is not defined" which is nonsensical.

BUG=v8:4407

Review-Url: https://codereview.chromium.org/2614053002
Cr-Commit-Position: refs/heads/master@{#42114}
parent a5f3c4d1
......@@ -1983,25 +1983,19 @@ void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) {
builder()->Bind(&no_reference_error);
}
void BytecodeGenerator::BuildThrowIfNotHole(Handle<String> name) {
// TODO(interpreter): Can the parser reduce the number of checks
// performed? Or should there be a ThrowIfNotHole bytecode.
BytecodeLabel no_reference_error, reference_error;
builder()
->JumpIfNotHole(&reference_error)
.Jump(&no_reference_error)
.Bind(&reference_error);
BuildThrowReferenceError(name);
builder()->Bind(&no_reference_error);
}
void BytecodeGenerator::BuildHoleCheckForVariableAssignment(Variable* variable,
Token::Value op) {
if (variable->is_this() && variable->mode() == CONST && op == Token::INIT) {
// Perform an initialization check for 'this'. 'this' variable is the
// only variable able to trigger bind operations outside the TDZ
// via 'super' calls.
BuildThrowIfNotHole(variable->name());
BytecodeLabel no_reference_error, reference_error;
builder()
->JumpIfNotHole(&reference_error)
.Jump(&no_reference_error)
.Bind(&reference_error)
.CallRuntime(Runtime::kThrowSuperAlreadyCalledError)
.Bind(&no_reference_error);
} else {
// Perform an initialization check for let/const declared variables.
// E.g. let x = (x = 20); is not allowed.
......
......@@ -110,7 +110,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildReThrow();
void BuildAbort(BailoutReason bailout_reason);
void BuildThrowIfHole(Handle<String> name);
void BuildThrowIfNotHole(Handle<String> name);
void BuildThrowReferenceError(Handle<String> name);
void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
......
......@@ -486,6 +486,7 @@ class ErrorUtils : public AllStatic {
T(WrongArgs, "%: Arguments list has wrong type") \
/* ReferenceError */ \
T(NotDefined, "% is not defined") \
T(SuperAlreadyCalled, "Super constructor may only be called once") \
T(UnsupportedSuper, "Unsupported reference to 'super'") \
/* RangeError */ \
T(DateRange, "Provided date is not in valid range.") \
......
......@@ -45,6 +45,13 @@ RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
isolate, NewTypeError(MessageTemplate::kStaticPrototype));
}
RUNTIME_FUNCTION(Runtime_ThrowSuperAlreadyCalledError) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewReferenceError(MessageTemplate::kSuperAlreadyCalled));
}
namespace {
Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor,
......
......@@ -78,6 +78,7 @@ namespace internal {
F(ThrowUnsupportedSuperError, 0, 1) \
F(ThrowConstructorNonCallableError, 1, 1) \
F(ThrowStaticPrototypeError, 0, 1) \
F(ThrowSuperAlreadyCalledError, 0, 1) \
F(ThrowNotSuperConstructor, 2, 1) \
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 4, 1) \
......
......@@ -107,7 +107,7 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 79
bytecode array length: 75
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
......@@ -122,10 +122,8 @@ bytecodes: [
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
B(Jump), U8(11),
B(LdaConstant), U8(0),
B(Star), R(3),
/* 118 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(Jump), U8(7),
/* 118 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(2), R(this),
/* 128 S> */ B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
......@@ -162,9 +160,9 @@ snippet: "
test = new B().constructor;
})();
"
frame size: 4
frame size: 3
parameter count: 1
bytecode array length: 75
bytecode array length: 71
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
......@@ -177,10 +175,8 @@ bytecodes: [
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
B(Jump), U8(11),
B(LdaConstant), U8(0),
B(Star), R(3),
/* 117 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
B(Jump), U8(7),
/* 117 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(2), R(this),
/* 126 S> */ B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
......
......@@ -55,7 +55,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 66
bytecode array length: 62
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -74,10 +74,8 @@ bytecodes: [
B(Star), R(3),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
B(Jump), U8(11),
B(LdaConstant), U8(0),
B(Star), R(4),
/* 140 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1),
B(Jump), U8(7),
/* 140 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(3), R(this),
B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
......@@ -107,7 +105,7 @@ snippet: "
"
frame size: 9
parameter count: 1
bytecode array length: 96
bytecode array length: 92
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -137,10 +135,8 @@ bytecodes: [
B(Star), R(3),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
B(Jump), U8(11),
B(LdaConstant), U8(2),
B(Star), R(4),
/* 140 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(4), U8(1),
B(Jump), U8(7),
/* 140 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(3), R(this),
B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
......
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