aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/torque/csa-generator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque/csa-generator.cc')
-rw-r--r--deps/v8/src/torque/csa-generator.cc463
1 files changed, 351 insertions, 112 deletions
diff --git a/deps/v8/src/torque/csa-generator.cc b/deps/v8/src/torque/csa-generator.cc
index 902b1b7f4a..68bb170863 100644
--- a/deps/v8/src/torque/csa-generator.cc
+++ b/deps/v8/src/torque/csa-generator.cc
@@ -14,11 +14,11 @@ namespace torque {
base::Optional<Stack<std::string>> CSAGenerator::EmitGraph(
Stack<std::string> parameters) {
for (Block* block : cfg_.blocks()) {
- out_ << " PLabel<";
+ out_ << " compiler::CodeAssemblerParameterizedLabel<";
PrintCommaSeparatedList(out_, block->InputTypes(), [](const Type* t) {
return t->GetGeneratedTNodeTypeName();
});
- out_ << "> " << BlockName(block) << "(this, compiler::CodeAssemblerLabel::"
+ out_ << "> " << BlockName(block) << "(&ca_, compiler::CodeAssemblerLabel::"
<< (block->IsDeferred() ? "kDeferred" : "kNonDeferred") << ");\n";
}
@@ -40,10 +40,10 @@ Stack<std::string> CSAGenerator::EmitBlock(const Block* block) {
Stack<std::string> stack;
for (const Type* t : block->InputTypes()) {
stack.Push(FreshNodeName());
- out_ << " TNode<" << t->GetGeneratedTNodeTypeName() << "> "
+ out_ << " compiler::TNode<" << t->GetGeneratedTNodeTypeName() << "> "
<< stack.Top() << ";\n";
}
- out_ << " Bind(&" << BlockName(block);
+ out_ << " ca_.Bind(&" << BlockName(block);
for (const std::string& name : stack) {
out_ << ", &" << name;
}
@@ -87,27 +87,27 @@ void CSAGenerator::EmitInstruction(
// TODO(tebbi): This can trigger an error in CSA if it is used. Instead, we
// should prevent usage of uninitialized in the type system. This
// requires "if constexpr" being evaluated at Torque time.
- stack->Push("Uninitialized<" + instruction.type->GetGeneratedTNodeTypeName() +
- ">()");
+ stack->Push("ca_.Uninitialized<" +
+ instruction.type->GetGeneratedTNodeTypeName() + ">()");
}
void CSAGenerator::EmitInstruction(
- const PushCodePointerInstruction& instruction, Stack<std::string>* stack) {
- stack->Push(
- "UncheckedCast<Code>(HeapConstant(Builtins::CallableFor(isolate(), "
- "Builtins::k" +
- instruction.external_name + ").code()))");
+ const PushBuiltinPointerInstruction& instruction,
+ Stack<std::string>* stack) {
+ stack->Push("ca_.UncheckedCast<BuiltinPtr>(ca_.SmiConstant(Builtins::k" +
+ instruction.external_name + "))");
}
-void CSAGenerator::EmitInstruction(const ModuleConstantInstruction& instruction,
- Stack<std::string>* stack) {
+void CSAGenerator::EmitInstruction(
+ const NamespaceConstantInstruction& instruction,
+ Stack<std::string>* stack) {
const Type* type = instruction.constant->type();
std::vector<std::string> results;
for (const Type* lowered : LowerType(type)) {
results.push_back(FreshNodeName());
stack->Push(results.back());
- out_ << " TNode<" << lowered->GetGeneratedTNodeTypeName() << "> "
- << stack->Top() << ";\n";
+ out_ << " compiler::TNode<" << lowered->GetGeneratedTNodeTypeName()
+ << "> " << stack->Top() << ";\n";
out_ << " USE(" << stack->Top() << ");\n";
}
out_ << " ";
@@ -118,7 +118,8 @@ void CSAGenerator::EmitInstruction(const ModuleConstantInstruction& instruction,
} else if (results.size() == 1) {
out_ << results[0] << " = ";
}
- out_ << instruction.constant->constant_name() << "()";
+ out_ << instruction.constant->ExternalAssemblerName() << "(state_)."
+ << instruction.constant->constant_name() << "()";
if (type->IsStructType()) {
out_ << ".Flatten();\n";
} else {
@@ -126,39 +127,152 @@ void CSAGenerator::EmitInstruction(const ModuleConstantInstruction& instruction,
}
}
-void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
- Stack<std::string>* stack) {
- std::vector<std::string> constexpr_arguments =
- instruction.constexpr_arguments;
- std::vector<std::string> args;
- TypeVector parameter_types =
- instruction.macro->signature().parameter_types.types;
+void CSAGenerator::ProcessArgumentsCommon(
+ const TypeVector& parameter_types, std::vector<std::string>* args,
+ std::vector<std::string>* constexpr_arguments, Stack<std::string>* stack) {
for (auto it = parameter_types.rbegin(); it != parameter_types.rend(); ++it) {
const Type* type = *it;
VisitResult arg;
if (type->IsConstexpr()) {
- args.push_back(std::move(constexpr_arguments.back()));
- constexpr_arguments.pop_back();
+ args->push_back(std::move(constexpr_arguments->back()));
+ constexpr_arguments->pop_back();
} else {
std::stringstream s;
size_t slot_count = LoweredSlotCount(type);
VisitResult arg = VisitResult(type, stack->TopRange(slot_count));
EmitCSAValue(arg, *stack, s);
- args.push_back(s.str());
+ args->push_back(s.str());
stack->PopMany(slot_count);
}
}
- std::reverse(args.begin(), args.end());
+ std::reverse(args->begin(), args->end());
+}
+
+void CSAGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
+ Stack<std::string>* stack) {
+ std::vector<std::string> constexpr_arguments =
+ instruction.constexpr_arguments;
+ std::vector<std::string> args;
+ TypeVector parameter_types =
+ instruction.intrinsic->signature().parameter_types.types;
+ ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);
+
+ Stack<std::string> pre_call_stack = *stack;
+ const Type* return_type = instruction.intrinsic->signature().return_type;
+ std::vector<std::string> results;
+ for (const Type* type : LowerType(return_type)) {
+ results.push_back(FreshNodeName());
+ stack->Push(results.back());
+ out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
+ << stack->Top() << ";\n";
+ out_ << " USE(" << stack->Top() << ");\n";
+ }
+ out_ << " ";
+
+ if (return_type->IsStructType()) {
+ out_ << "std::tie(";
+ PrintCommaSeparatedList(out_, results);
+ out_ << ") = ";
+ } else {
+ if (results.size() == 1) {
+ out_ << results[0] << " = ";
+ }
+ }
+
+ if (instruction.intrinsic->ExternalName() == "%RawObjectCast") {
+ if (parameter_types.size() != 1) {
+ ReportError("%RawObjectCast must take a single parameter");
+ }
+ if (return_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
+ if (return_type->GetGeneratedTNodeTypeName() !=
+ parameter_types[0]->GetGeneratedTNodeTypeName()) {
+ out_ << "TORQUE_CAST";
+ }
+ } else {
+ std::stringstream s;
+ s << "%RawObjectCast must cast to subtype of Tagged (" << *return_type
+ << " is not)";
+ ReportError(s.str());
+ }
+ } else if (instruction.intrinsic->ExternalName() == "%RawPointerCast") {
+ if (parameter_types.size() != 1) {
+ ReportError("%RawPointerCast must take a single parameter");
+ }
+ if (!return_type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
+ std::stringstream s;
+ s << "%RawObjectCast must cast to subtype of RawPtr (" << *return_type
+ << " is not)";
+ ReportError(s.str());
+ }
+ } else if (instruction.intrinsic->ExternalName() == "%FromConstexpr") {
+ if (parameter_types.size() != 1 || !parameter_types[0]->IsConstexpr()) {
+ ReportError(
+ "%FromConstexpr must take a single parameter with constexpr "
+ "type");
+ }
+ if (return_type->IsConstexpr()) {
+ ReportError("%FromConstexpr must return a non-constexpr type");
+ }
+ if (return_type->IsSubtypeOf(TypeOracle::GetSmiType())) {
+ out_ << "ca_.SmiConstant";
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetNumberType())) {
+ out_ << "ca_.NumberConstant";
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetStringType())) {
+ out_ << "ca_.StringConstant";
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
+ ReportError(
+ "%FromConstexpr cannot cast to subclass of HeapObject unless it's a "
+ "String or Number");
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
+ out_ << "ca_.IntPtrConstant";
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
+ out_ << "ca_.UintPtrConstant";
+ } else if (return_type->IsSubtypeOf(TypeOracle::GetInt32Type())) {
+ out_ << "ca_.Int32Constant";
+ } else {
+ std::stringstream s;
+ s << "%FromConstexpr does not support return type " << *return_type;
+ ReportError(s.str());
+ }
+ } else if (instruction.intrinsic->ExternalName() == "%Allocate") {
+ out_ << "ca_.UncheckedCast<" << return_type->GetGeneratedTNodeTypeName()
+ << ">(CodeStubAssembler(state_).Allocate";
+ } else {
+ ReportError("no built in intrinsic with name " +
+ instruction.intrinsic->ExternalName());
+ }
+ out_ << "(";
+ PrintCommaSeparatedList(out_, args);
+ if (instruction.intrinsic->ExternalName() == "%Allocate") out_ << ")";
+ if (return_type->IsStructType()) {
+ out_ << ").Flatten();\n";
+ } else {
+ out_ << ");\n";
+ }
+}
+
+void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
+ Stack<std::string>* stack) {
+ std::vector<std::string> constexpr_arguments =
+ instruction.constexpr_arguments;
+ std::vector<std::string> args;
+ TypeVector parameter_types =
+ instruction.macro->signature().parameter_types.types;
+ ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);
+
+ Stack<std::string> pre_call_stack = *stack;
const Type* return_type = instruction.macro->signature().return_type;
std::vector<std::string> results;
for (const Type* type : LowerType(return_type)) {
results.push_back(FreshNodeName());
stack->Push(results.back());
- out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> "
+ out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
<< stack->Top() << ";\n";
out_ << " USE(" << stack->Top() << ");\n";
}
+ std::string catch_name =
+ PreCallableExceptionPreparation(instruction.catch_block);
out_ << " ";
if (return_type->IsStructType()) {
out_ << "std::tie(";
@@ -166,11 +280,12 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
out_ << ") = ";
} else {
if (results.size() == 1) {
- out_ << results[0] << " = UncheckedCast<"
+ out_ << results[0] << " = ca_.UncheckedCast<"
<< return_type->GetGeneratedTNodeTypeName() << ">(";
}
}
- out_ << instruction.macro->name() << "(";
+ out_ << instruction.macro->external_assembler_name() << "(state_)."
+ << instruction.macro->ExternalName() << "(";
PrintCommaSeparatedList(out_, args);
if (return_type->IsStructType()) {
out_ << ").Flatten();\n";
@@ -178,6 +293,8 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
if (results.size() == 1) out_ << ")";
out_ << ");\n";
}
+ PostCallableExceptionPreparation(catch_name, return_type,
+ instruction.catch_block, &pre_call_stack);
}
void CSAGenerator::EmitInstruction(
@@ -188,31 +305,17 @@ void CSAGenerator::EmitInstruction(
std::vector<std::string> args;
TypeVector parameter_types =
instruction.macro->signature().parameter_types.types;
- for (auto it = parameter_types.rbegin(); it != parameter_types.rend(); ++it) {
- const Type* type = *it;
- VisitResult arg;
- if (type->IsConstexpr()) {
- args.push_back(std::move(constexpr_arguments.back()));
- constexpr_arguments.pop_back();
- } else {
- std::stringstream s;
- size_t slot_count = LoweredSlotCount(type);
- VisitResult arg = VisitResult(type, stack->TopRange(slot_count));
- EmitCSAValue(arg, *stack, s);
- args.push_back(s.str());
- stack->PopMany(slot_count);
- }
- }
- std::reverse(args.begin(), args.end());
+ ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);
+ Stack<std::string> pre_call_stack = *stack;
std::vector<std::string> results;
const Type* return_type = instruction.macro->signature().return_type;
if (return_type != TypeOracle::GetNeverType()) {
for (const Type* type :
LowerType(instruction.macro->signature().return_type)) {
results.push_back(FreshNodeName());
- out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> "
- << results.back() << ";\n";
+ out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName()
+ << "> " << results.back() << ";\n";
out_ << " USE(" << results.back() << ");\n";
}
}
@@ -228,13 +331,16 @@ void CSAGenerator::EmitInstruction(
for (size_t j = 0; j < label_parameters.size(); ++j) {
var_names[i].push_back("result_" + std::to_string(i) + "_" +
std::to_string(j));
- out_ << " TVariable<"
+ out_ << " compiler::TypedCodeAssemblerVariable<"
<< label_parameters[j]->GetGeneratedTNodeTypeName() << "> "
- << var_names[i][j] << "(this);\n";
+ << var_names[i][j] << "(&ca_);\n";
}
- out_ << " Label " << label_names[i] << "(this);\n";
+ out_ << " compiler::CodeAssemblerLabel " << label_names[i]
+ << "(&ca_);\n";
}
+ std::string catch_name =
+ PreCallableExceptionPreparation(instruction.catch_block);
out_ << " ";
if (results.size() == 1) {
out_ << results[0] << " = ";
@@ -243,7 +349,8 @@ void CSAGenerator::EmitInstruction(
PrintCommaSeparatedList(out_, results);
out_ << ") = ";
}
- out_ << instruction.macro->name() << "(";
+ out_ << instruction.macro->external_assembler_name() << "(state_)."
+ << instruction.macro->ExternalName() << "(";
PrintCommaSeparatedList(out_, args);
bool first = args.empty();
for (size_t i = 0; i < label_names.size(); ++i) {
@@ -254,9 +361,17 @@ void CSAGenerator::EmitInstruction(
out_ << ", &" << var_names[i][j];
}
}
- out_ << ");\n";
+ if (return_type->IsStructType()) {
+ out_ << ").Flatten();\n";
+ } else {
+ out_ << ");\n";
+ }
+
+ PostCallableExceptionPreparation(catch_name, return_type,
+ instruction.catch_block, &pre_call_stack);
+
if (instruction.return_continuation) {
- out_ << " Goto(&" << BlockName(*instruction.return_continuation);
+ out_ << " ca_.Goto(&" << BlockName(*instruction.return_continuation);
for (const std::string& value : *stack) {
out_ << ", " << value;
}
@@ -267,8 +382,8 @@ void CSAGenerator::EmitInstruction(
}
for (size_t i = 0; i < label_names.size(); ++i) {
out_ << " if (" << label_names[i] << ".is_used()) {\n";
- out_ << " Bind(&" << label_names[i] << ");\n";
- out_ << " Goto(&" << BlockName(instruction.label_blocks[i]);
+ out_ << " ca_.Bind(&" << label_names[i] << ");\n";
+ out_ << " ca_.Goto(&" << BlockName(instruction.label_blocks[i]);
for (const std::string& value : *stack) {
out_ << ", " << value;
}
@@ -287,30 +402,44 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
std::vector<const Type*> result_types =
LowerType(instruction.builtin->signature().return_type);
if (instruction.is_tailcall) {
- out_ << " TailCallBuiltin(Builtins::k" << instruction.builtin->name()
- << ", ";
+ out_ << " CodeStubAssembler(state_).TailCallBuiltin(Builtins::k"
+ << instruction.builtin->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
out_ << ");\n";
} else {
+ std::string result_name = FreshNodeName();
+ if (result_types.size() == 1) {
+ out_ << " compiler::TNode<"
+ << result_types[0]->GetGeneratedTNodeTypeName() << "> "
+ << result_name << ";\n";
+ }
+ std::string catch_name =
+ PreCallableExceptionPreparation(instruction.catch_block);
+ Stack<std::string> pre_call_stack = *stack;
if (result_types.size() == 1) {
std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
- stack->Push(FreshNodeName());
- out_ << " TNode<" << generated_type << "> " << stack->Top() << " = ";
- if (generated_type != "Object") out_ << "CAST(";
- out_ << "CallBuiltin(Builtins::k" << instruction.builtin->name() << ", ";
+ stack->Push(result_name);
+ out_ << " " << result_name << " = ";
+ if (generated_type != "Object") out_ << "TORQUE_CAST(";
+ out_ << "CodeStubAssembler(state_).CallBuiltin(Builtins::k"
+ << instruction.builtin->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
if (generated_type != "Object") out_ << ")";
out_ << ");\n";
- out_ << " USE(" << stack->Top() << ");\n";
+ out_ << " USE(" << result_name << ");\n";
} else {
DCHECK_EQ(0, result_types.size());
// TODO(tebbi): Actually, builtins have to return a value, so we should
// not have to handle this case.
- out_ << " CallBuiltin(Builtins::k" << instruction.builtin->name()
- << ", ";
+ out_ << " CodeStubAssembler(state_).CallBuiltin(Builtins::k"
+ << instruction.builtin->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
out_ << ");\n";
}
+ PostCallableExceptionPreparation(
+ catch_name,
+ result_types.size() == 0 ? TypeOracle::GetVoidType() : result_types[0],
+ instruction.catch_block, &pre_call_stack);
}
}
@@ -320,67 +449,127 @@ void CSAGenerator::EmitInstruction(
std::vector<std::string> function_and_arguments =
stack->PopMany(1 + instruction.argc);
std::vector<const Type*> result_types =
- LowerType(instruction.example_builtin->signature().return_type);
+ LowerType(instruction.type->return_type());
if (result_types.size() != 1) {
ReportError("builtins must have exactly one result");
}
if (instruction.is_tailcall) {
- out_ << " Tail (Builtins::CallableFor(isolate(), Builtins::k"
- << instruction.example_builtin->name() << ").descriptor(), ";
- PrintCommaSeparatedList(out_, function_and_arguments);
- out_ << ");\n";
- } else {
- stack->Push(FreshNodeName());
- std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
- out_ << " TNode<" << generated_type << "> " << stack->Top() << " = ";
- if (generated_type != "Object") out_ << "CAST(";
- out_ << "CallStub(Builtins::CallableFor(isolate(), Builtins::k"
- << instruction.example_builtin->name() << ").descriptor(), ";
- PrintCommaSeparatedList(out_, function_and_arguments);
- out_ << ")";
- if (generated_type != "Object") out_ << ")";
- out_ << "; \n";
- out_ << " USE(" << stack->Top() << ");\n";
+ ReportError("tail-calls to builtin pointers are not supported");
+ }
+
+ stack->Push(FreshNodeName());
+ std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
+ out_ << " compiler::TNode<" << generated_type << "> " << stack->Top()
+ << " = ";
+ if (generated_type != "Object") out_ << "TORQUE_CAST(";
+ out_ << "CodeStubAssembler(state_).CallBuiltinPointer(Builtins::"
+ "CallableFor(ca_."
+ "isolate(),"
+ "ExampleBuiltinForTorqueFunctionPointerType("
+ << instruction.type->function_pointer_type_id() << ")).descriptor(), ";
+ PrintCommaSeparatedList(out_, function_and_arguments);
+ out_ << ")";
+ if (generated_type != "Object") out_ << ")";
+ out_ << "; \n";
+ out_ << " USE(" << stack->Top() << ");\n";
+}
+
+std::string CSAGenerator::PreCallableExceptionPreparation(
+ base::Optional<Block*> catch_block) {
+ std::string catch_name;
+ if (catch_block) {
+ catch_name = FreshCatchName();
+ out_ << " compiler::CodeAssemblerExceptionHandlerLabel " << catch_name
+ << "_label(&ca_, compiler::CodeAssemblerLabel::kDeferred);\n";
+ out_ << " { compiler::CodeAssemblerScopedExceptionHandler s(&ca_, &"
+ << catch_name << "_label);\n";
+ }
+ return catch_name;
+}
+
+void CSAGenerator::PostCallableExceptionPreparation(
+ const std::string& catch_name, const Type* return_type,
+ base::Optional<Block*> catch_block, Stack<std::string>* stack) {
+ if (catch_block) {
+ std::string block_name = BlockName(*catch_block);
+ out_ << " }\n";
+ out_ << " if (" << catch_name << "_label.is_used()) {\n";
+ out_ << " compiler::CodeAssemblerLabel " << catch_name
+ << "_skip(&ca_);\n";
+ if (!return_type->IsNever()) {
+ out_ << " ca_.Goto(&" << catch_name << "_skip);\n";
+ }
+ out_ << " compiler::TNode<Object> " << catch_name
+ << "_exception_object;\n";
+ out_ << " ca_.Bind(&" << catch_name << "_label, &" << catch_name
+ << "_exception_object);\n";
+ out_ << " ca_.Goto(&" << block_name;
+ for (size_t i = 0; i < stack->Size(); ++i) {
+ out_ << ", " << stack->begin()[i];
+ }
+ out_ << ", " << catch_name << "_exception_object);\n";
+ if (!return_type->IsNever()) {
+ out_ << " ca_.Bind(&" << catch_name << "_skip);\n";
+ }
+ out_ << " }\n";
}
}
void CSAGenerator::EmitInstruction(const CallRuntimeInstruction& instruction,
Stack<std::string>* stack) {
std::vector<std::string> arguments = stack->PopMany(instruction.argc);
- std::vector<const Type*> result_types =
- LowerType(instruction.runtime_function->signature().return_type);
+ const Type* return_type =
+ instruction.runtime_function->signature().return_type;
+ std::vector<const Type*> result_types;
+ if (return_type != TypeOracle::GetNeverType()) {
+ result_types = LowerType(return_type);
+ }
if (result_types.size() > 1) {
ReportError("runtime function must have at most one result");
}
if (instruction.is_tailcall) {
- out_ << " TailCallRuntime(Runtime::k"
- << instruction.runtime_function->name() << ", ";
+ out_ << " CodeStubAssembler(state_).TailCallRuntime(Runtime::k"
+ << instruction.runtime_function->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
out_ << ");\n";
} else {
+ std::string result_name = FreshNodeName();
+ if (result_types.size() == 1) {
+ out_ << " compiler::TNode<"
+ << result_types[0]->GetGeneratedTNodeTypeName() << "> "
+ << result_name << ";\n";
+ }
+ std::string catch_name =
+ PreCallableExceptionPreparation(instruction.catch_block);
+ Stack<std::string> pre_call_stack = *stack;
if (result_types.size() == 1) {
- stack->Push(FreshNodeName());
- out_ << " TNode<" << result_types[0]->GetGeneratedTNodeTypeName()
- << "> " << stack->Top() << " = CAST(CallRuntime(Runtime::k"
- << instruction.runtime_function->name() << ", ";
+ stack->Push(result_name);
+ out_ << " " << result_name
+ << " = TORQUE_CAST(CodeStubAssembler(state_).CallRuntime(Runtime::k"
+ << instruction.runtime_function->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
out_ << "));\n";
- out_ << " USE(" << stack->Top() << ");\n";
+ out_ << " USE(" << result_name << ");\n";
} else {
DCHECK_EQ(0, result_types.size());
- // TODO(tebbi): Actually, runtime functions have to return a value, so we
- // should not have to handle this case.
- out_ << " CallRuntime(Runtime::k"
- << instruction.runtime_function->name() << ", ";
+ out_ << " CodeStubAssembler(state_).CallRuntime(Runtime::k"
+ << instruction.runtime_function->ExternalName() << ", ";
PrintCommaSeparatedList(out_, arguments);
out_ << ");\n";
+ if (return_type == TypeOracle::GetNeverType()) {
+ out_ << " CodeStubAssembler(state_).Unreachable();\n";
+ } else {
+ DCHECK(return_type == TypeOracle::GetVoidType());
+ }
}
+ PostCallableExceptionPreparation(catch_name, return_type,
+ instruction.catch_block, &pre_call_stack);
}
}
void CSAGenerator::EmitInstruction(const BranchInstruction& instruction,
Stack<std::string>* stack) {
- out_ << " Branch(" << stack->Pop() << ", &"
+ out_ << " ca_.Branch(" << stack->Pop() << ", &"
<< BlockName(instruction.if_true) << ", &"
<< BlockName(instruction.if_false);
for (const std::string& value : *stack) {
@@ -392,13 +581,13 @@ void CSAGenerator::EmitInstruction(const BranchInstruction& instruction,
void CSAGenerator::EmitInstruction(
const ConstexprBranchInstruction& instruction, Stack<std::string>* stack) {
out_ << " if (" << instruction.condition << ") {\n";
- out_ << " Goto(&" << BlockName(instruction.if_true);
+ out_ << " ca_.Goto(&" << BlockName(instruction.if_true);
for (const std::string& value : *stack) {
out_ << ", " << value;
}
out_ << ");\n";
out_ << " } else {\n";
- out_ << " Goto(&" << BlockName(instruction.if_false);
+ out_ << " ca_.Goto(&" << BlockName(instruction.if_false);
for (const std::string& value : *stack) {
out_ << ", " << value;
}
@@ -409,7 +598,7 @@ void CSAGenerator::EmitInstruction(
void CSAGenerator::EmitInstruction(const GotoInstruction& instruction,
Stack<std::string>* stack) {
- out_ << " Goto(&" << BlockName(instruction.destination);
+ out_ << " ca_.Goto(&" << BlockName(instruction.destination);
for (const std::string& value : *stack) {
out_ << ", " << value;
}
@@ -422,7 +611,7 @@ void CSAGenerator::EmitInstruction(const GotoExternalInstruction& instruction,
it != instruction.variable_names.rend(); ++it) {
out_ << " *" << *it << " = " << stack->Pop() << ";\n";
}
- out_ << " Goto(" << instruction.destination << ");\n";
+ out_ << " ca_.Goto(" << instruction.destination << ");\n";
}
void CSAGenerator::EmitInstruction(const ReturnInstruction& instruction,
@@ -430,7 +619,7 @@ void CSAGenerator::EmitInstruction(const ReturnInstruction& instruction,
if (*linkage_ == Builtin::kVarArgsJavaScript) {
out_ << " " << ARGUMENTS_VARIABLE_STRING << "->PopAndReturn(";
} else {
- out_ << " Return(";
+ out_ << " CodeStubAssembler(state_).Return(";
}
out_ << stack->Pop() << ");\n";
}
@@ -438,26 +627,75 @@ void CSAGenerator::EmitInstruction(const ReturnInstruction& instruction,
void CSAGenerator::EmitInstruction(
const PrintConstantStringInstruction& instruction,
Stack<std::string>* stack) {
- out_ << " Print(" << StringLiteralQuote(instruction.message) << ");\n";
+ out_ << " CodeStubAssembler(state_).Print("
+ << StringLiteralQuote(instruction.message) << ");\n";
}
-void CSAGenerator::EmitInstruction(const DebugBreakInstruction& instruction,
+void CSAGenerator::EmitInstruction(const AbortInstruction& instruction,
Stack<std::string>* stack) {
- if (instruction.never_continues) {
- out_ << " Unreachable();\n";
- } else {
- out_ << " DebugBreak();\n";
+ switch (instruction.kind) {
+ case AbortInstruction::Kind::kUnreachable:
+ DCHECK(instruction.message.empty());
+ out_ << " CodeStubAssembler(state_).Unreachable();\n";
+ break;
+ case AbortInstruction::Kind::kDebugBreak:
+ DCHECK(instruction.message.empty());
+ out_ << " CodeStubAssembler(state_).DebugBreak();\n";
+ break;
+ case AbortInstruction::Kind::kAssertionFailure: {
+ std::string file =
+ StringLiteralQuote(SourceFileMap::GetSource(instruction.pos.source));
+ out_ << " CodeStubAssembler(state_).FailAssert("
+ << StringLiteralQuote(instruction.message) << ", " << file << ", "
+ << instruction.pos.line + 1 << ");\n";
+ break;
+ }
}
}
void CSAGenerator::EmitInstruction(const UnsafeCastInstruction& instruction,
Stack<std::string>* stack) {
stack->Poke(stack->AboveTop() - 1,
- "UncheckedCast<" +
+ "ca_.UncheckedCast<" +
instruction.destination_type->GetGeneratedTNodeTypeName() +
">(" + stack->Top() + ")");
}
+void CSAGenerator::EmitInstruction(
+ const LoadObjectFieldInstruction& instruction, Stack<std::string>* stack) {
+ const Field& field =
+ instruction.class_type->LookupField(instruction.field_name);
+ std::string result_name = FreshNodeName();
+ std::string type_string =
+ field.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())
+ ? "MachineType::TaggedSigned()"
+ : "MachineType::AnyTagged()";
+ out_ << field.name_and_type.type->GetGeneratedTypeName() << " " << result_name
+ << " = "
+ << "ca_.UncheckedCast<"
+ << field.name_and_type.type->GetGeneratedTNodeTypeName()
+ << ">(CodeStubAssembler(state_).LoadObjectField("
+ << stack->Top() + ", " + std::to_string(field.offset) + ", "
+ << type_string + "));\n";
+ stack->Poke(stack->AboveTop() - 1, result_name);
+}
+
+void CSAGenerator::EmitInstruction(
+ const StoreObjectFieldInstruction& instruction, Stack<std::string>* stack) {
+ auto value = stack->Pop();
+ auto object = stack->Pop();
+ stack->Push(value);
+ const Field& field =
+ instruction.class_type->LookupField(instruction.field_name);
+ if (field.offset == 0) {
+ out_ << " CodeStubAssembler(state_).StoreMap(" + object + ", " + value +
+ ");\n";
+ } else {
+ out_ << " CodeStubAssembler(state_).StoreObjectField(" + object + ", " +
+ std::to_string(field.offset) + ", " + value + ");\n";
+ }
+}
+
// static
void CSAGenerator::EmitCSAValue(VisitResult result,
const Stack<std::string>& values,
@@ -465,20 +703,21 @@ void CSAGenerator::EmitCSAValue(VisitResult result,
if (!result.IsOnStack()) {
out << result.constexpr_value();
} else if (auto* struct_type = StructType::DynamicCast(result.type())) {
- out << struct_type->name() << "{";
+ out << struct_type->GetGeneratedTypeName() << "{";
bool first = true;
for (auto& field : struct_type->fields()) {
if (!first) {
out << ", ";
}
first = false;
- EmitCSAValue(ProjectStructField(result, field.name), values, out);
+ EmitCSAValue(ProjectStructField(result, field.name_and_type.name), values,
+ out);
}
out << "}";
} else {
DCHECK_EQ(1, result.stack_range().Size());
- out << "TNode<" << result.type()->GetGeneratedTNodeTypeName() << ">{"
- << values.Peek(result.stack_range().begin()) << "}";
+ out << "compiler::TNode<" << result.type()->GetGeneratedTNodeTypeName()
+ << ">{" << values.Peek(result.stack_range().begin()) << "}";
}
}