Commit c7add4ce authored by jgruber's avatar jgruber Committed by Commit bot

[csa] Add Unreachable() and use it after throw sites

This should improve readability, code generation, and ensure that
we verify such locations are never reached.

BUG=

Review-Url: https://codereview.chromium.org/2705163005
Cr-Commit-Position: refs/heads/master@{#43367}
parent 73d45c96
......@@ -652,14 +652,14 @@ TF_BUILTIN(ArrayForEach, ForEachCodeStubAssembler) {
SmiConstant(MessageTemplate::kCalledOnNullOrUndefined),
HeapConstant(isolate()->factory()->NewStringFromAsciiChecked(
"Array.prototype.forEach")));
Return(UndefinedConstant());
Unreachable();
}
Bind(&type_exception);
{
CallRuntime(Runtime::kThrowTypeError, context,
SmiConstant(MessageTemplate::kCalledNonCallable), callbackfn);
Return(UndefinedConstant());
Unreachable();
}
}
......@@ -2836,19 +2836,17 @@ void Builtins::Generate_ArrayIteratorPrototypeNext(
assembler.Bind(&throw_bad_receiver);
{
// The {receiver} is not a valid JSArrayIterator.
Node* result = assembler.CallRuntime(
Runtime::kThrowIncompatibleMethodReceiver, context,
assembler.HeapConstant(operation), iterator);
assembler.Return(result);
assembler.CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
assembler.HeapConstant(operation), iterator);
assembler.Unreachable();
}
assembler.Bind(&if_isdetached);
{
Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation);
Node* result =
assembler.CallRuntime(Runtime::kThrowTypeError, context, message,
assembler.HeapConstant(operation));
assembler.Return(result);
assembler.CallRuntime(Runtime::kThrowTypeError, context, message,
assembler.HeapConstant(operation));
assembler.Unreachable();
}
}
......
......@@ -945,8 +945,8 @@ void Generate_DatePrototype_GetField(CodeStubAssembler* assembler,
// Raise a TypeError if the receiver is not a date.
assembler->Bind(&receiver_not_date);
{
Node* result = assembler->CallRuntime(Runtime::kThrowNotDateError, context);
assembler->Return(result);
assembler->CallRuntime(Runtime::kThrowNotDateError, context);
assembler->Unreachable();
}
}
......@@ -1152,20 +1152,19 @@ void Builtins::Generate_DatePrototypeToPrimitive(
// Raise a TypeError if the {hint} is invalid.
assembler.Bind(&hint_is_invalid);
{
Node* result =
assembler.CallRuntime(Runtime::kThrowInvalidHint, context, hint);
assembler.Return(result);
assembler.CallRuntime(Runtime::kThrowInvalidHint, context, hint);
assembler.Unreachable();
}
// Raise a TypeError if the {receiver} is not a JSReceiver instance.
assembler.Bind(&receiver_is_invalid);
{
Node* result = assembler.CallRuntime(
assembler.CallRuntime(
Runtime::kThrowIncompatibleMethodReceiver, context,
assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked(
"Date.prototype [ @@toPrimitive ]", TENURED)),
receiver);
assembler.Return(result);
assembler.Unreachable();
}
}
......
......@@ -56,12 +56,11 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
Bind(&if_receiverisincompatible);
{
// The {receiver} is not a valid JSGeneratorObject.
Node* result =
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(
method_name, TENURED)),
receiver);
Return(result); // Never reached.
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(
factory()->NewStringFromAsciiChecked(method_name, TENURED)),
receiver);
Unreachable();
}
Bind(&if_receiverisclosed);
......@@ -89,8 +88,8 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume(
Bind(&if_receiverisrunning);
{
Node* result = CallRuntime(Runtime::kThrowGeneratorRunning, context);
Return(result); // Never reached.
CallRuntime(Runtime::kThrowGeneratorRunning, context);
Unreachable();
}
}
......
......@@ -178,8 +178,7 @@ Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context,
StoreObjectField(capability, JSPromiseCapability::kRejectOffset,
UndefinedConstant());
CallRuntime(Runtime::kThrowTypeError, context, message);
var_result.Bind(UndefinedConstant());
Goto(&out);
Unreachable();
}
Bind(&out);
......@@ -251,8 +250,7 @@ Node* PromiseBuiltinsAssembler::ThrowIfNotJSReceiver(
isolate()->factory()->NewStringFromAsciiChecked(method_name));
Node* const message_id = SmiConstant(msg_template);
CallRuntime(Runtime::kThrowTypeError, context, message_id, method);
var_value_map.Bind(UndefinedConstant());
Goto(&out); // Never reached.
Unreachable();
}
Bind(&out);
......@@ -325,7 +323,7 @@ Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object,
Node* const message_id =
SmiConstant(MessageTemplate::kSpeciesNotConstructor);
CallRuntime(Runtime::kThrowTypeError, context, message_id);
Goto(&out);
Unreachable();
}
Bind(&out);
......@@ -1115,7 +1113,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
{
Node* const message_id = SmiConstant(MessageTemplate::kNotAPromise);
CallRuntime(Runtime::kThrowTypeError, context, message_id, new_target);
Return(UndefinedConstant()); // Never reached.
Unreachable();
}
// 2. If IsCallable(executor) is false, throw a TypeError exception.
......@@ -1124,7 +1122,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
Node* const message_id =
SmiConstant(MessageTemplate::kResolverNotAFunction);
CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
Return(UndefinedConstant()); // Never reached.
Unreachable();
}
// Silently fail if the stack looks fishy.
......@@ -1495,7 +1493,8 @@ TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
Bind(&if_alreadyinvoked);
Node* message = SmiConstant(MessageTemplate::kPromiseExecutorAlreadyInvoked);
Return(CallRuntime(Runtime::kThrowTypeError, context, message));
CallRuntime(Runtime::kThrowTypeError, context, message);
Unreachable();
}
TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
......@@ -1652,7 +1651,7 @@ TF_BUILTIN(PromiseThrowerFinally, PromiseBuiltinsAssembler) {
Node* const reason = LoadContextElement(context, kOnFinallySlot);
CallRuntime(Runtime::kThrow, context, reason);
Return(UndefinedConstant());
Unreachable();
}
Node* PromiseBuiltinsAssembler::CreateThrowerFunctionContext(
......
......@@ -398,8 +398,7 @@ Node* RegExpBuiltinsAssembler::ThrowIfNotJSReceiver(
CallRuntime(Runtime::kThrowTypeError, context, message_id, method_name_str,
value_str);
var_value_map.Bind(UndefinedConstant());
Goto(&out); // Never reached.
Unreachable();
}
Bind(&out);
......@@ -1090,7 +1089,7 @@ void RegExpBuiltinsAssembler::FlagGetter(JSRegExp::Flag flag,
isolate->factory()->NewStringFromAsciiChecked(method_name));
CallRuntime(Runtime::kThrowTypeError, context, message_id,
method_name_str);
Return(UndefinedConstant()); // Never reached.
Unreachable();
}
}
}
......
......@@ -85,7 +85,7 @@ void ValidateSharedTypedArray(CodeStubAssembler* a, compiler::Node* tagged,
a->Bind(&invalid);
a->CallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context,
tagged);
a->Return(a->UndefinedConstant());
a->Unreachable();
a->Bind(&not_float_or_clamped);
*out_instance_type = elements_instance_type;
......@@ -136,8 +136,8 @@ compiler::Node* ConvertTaggedAtomicIndexToWord32(CodeStubAssembler* a,
}
a->Bind(&if_indexesarenotequal);
a->Return(
a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context));
a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
a->Unreachable();
}
a->Bind(&done);
......@@ -156,8 +156,8 @@ void ValidateAtomicIndex(CodeStubAssembler* a, compiler::Node* index_word,
a->Int32GreaterThanOrEqual(index_word, array_length_word)),
&if_notinbounds, &if_inbounds);
a->Bind(&if_notinbounds);
a->Return(
a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context));
a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
a->Unreachable();
a->Bind(&if_inbounds);
}
......
......@@ -1906,12 +1906,11 @@ TF_BUILTIN(StringIteratorPrototypeNext, StringBuiltinsAssembler) {
Bind(&throw_bad_receiver);
{
// The {receiver} is not a valid JSGeneratorObject.
Node* result =
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(
"String Iterator.prototype.next", TENURED)),
iterator);
Return(result); // Never reached.
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(
"String Iterator.prototype.next", TENURED)),
iterator);
Unreachable();
}
}
......
......@@ -58,12 +58,11 @@ void TypedArrayBuiltinsAssembler::GenerateTypedArrayPrototypeGetter(
Bind(&receiver_is_incompatible);
{
// The {receiver} is not a valid JSTypedArray.
Node* result =
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(
method_name, TENURED)),
receiver);
Return(result); // Never reached.
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(
factory()->NewStringFromAsciiChecked(method_name, TENURED)),
receiver);
Unreachable();
}
}
......
......@@ -2694,7 +2694,7 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
CallRuntime(Runtime::kThrowCalledOnNullOrUndefined, context,
HeapConstant(factory()->NewStringFromAsciiChecked(
method_name, TENURED)));
Goto(&if_valueisstring); // Never reached.
Unreachable();
}
}
}
......@@ -2793,7 +2793,7 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
CallRuntime(Runtime::kThrowNotGeneric, context,
HeapConstant(factory()->NewStringFromAsciiChecked(method_name,
TENURED)));
Goto(&done_loop); // Never reached.
Unreachable();
}
Bind(&done_loop);
......@@ -2821,8 +2821,7 @@ Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(method_name, TENURED)),
value);
var_value_map.Bind(UndefinedConstant());
Goto(&out); // Never reached.
Unreachable();
Bind(&out);
return var_value_map.value();
......@@ -7809,9 +7808,9 @@ Node* CodeStubAssembler::GetSuperConstructor(Node* active_function,
Bind(&is_not_constructor);
{
result.Bind(CallRuntime(Runtime::kThrowNotSuperConstructor, context,
prototype, active_function));
Goto(&out);
CallRuntime(Runtime::kThrowNotSuperConstructor, context, prototype,
active_function);
Unreachable();
}
Bind(&out);
......@@ -7880,18 +7879,14 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
Bind(&if_notcallable);
{
Node* result =
CallRuntime(Runtime::kThrowNonCallableInInstanceOfCheck, context);
var_result.Bind(result);
Goto(&return_result);
CallRuntime(Runtime::kThrowNonCallableInInstanceOfCheck, context);
Unreachable();
}
Bind(&if_notreceiver);
{
Node* result =
CallRuntime(Runtime::kThrowNonObjectInInstanceOfCheck, context);
var_result.Bind(result);
Goto(&return_result);
CallRuntime(Runtime::kThrowNonObjectInInstanceOfCheck, context);
Unreachable();
}
Bind(&return_true);
......
......@@ -274,6 +274,11 @@ void CodeAssembler::PopAndReturn(Node* pop, Node* value) {
void CodeAssembler::DebugBreak() { raw_assembler()->DebugBreak(); }
void CodeAssembler::Unreachable() {
DebugBreak();
raw_assembler()->Unreachable();
}
void CodeAssembler::Comment(const char* format, ...) {
if (!FLAG_code_comments) return;
char buffer[4 * KB];
......
......@@ -234,6 +234,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void PopAndReturn(Node* pop, Node* value);
void DebugBreak();
void Unreachable();
void Comment(const char* format, ...);
void Bind(Label* label);
......
......@@ -520,6 +520,9 @@ class MachineRepresentationChecker {
}
break;
}
case IrOpcode::kThrow:
CheckValueInputIsTagged(node, 0);
break;
case IrOpcode::kTypedStateValues:
case IrOpcode::kFrameState:
break;
......
......@@ -166,6 +166,13 @@ void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
void RawMachineAssembler::Unreachable() {
Node* values[] = {UndefinedConstant()}; // Unused.
Node* ret = MakeNode(common()->Throw(), 1, values);
schedule()->AddThrow(CurrentBlock(), ret);
current_block_ = nullptr;
}
void RawMachineAssembler::Comment(const char* msg) {
AddNode(machine()->Comment(msg));
}
......
......@@ -769,6 +769,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
void Bind(RawMachineLabel* label);
void Deoptimize(Node* state);
void DebugBreak();
void Unreachable();
void Comment(const char* msg);
// Add success / exception successor blocks and ends the current block ending
......
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