summaryrefslogtreecommitdiff
path: root/deps/v8/src/torque/implementation-visitor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque/implementation-visitor.cc')
-rw-r--r--deps/v8/src/torque/implementation-visitor.cc773
1 files changed, 389 insertions, 384 deletions
diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc
index 2f2881fd07..00504b5eff 100644
--- a/deps/v8/src/torque/implementation-visitor.cc
+++ b/deps/v8/src/torque/implementation-visitor.cc
@@ -10,6 +10,7 @@
#include "src/base/optional.h"
#include "src/common/globals.h"
+#include "src/torque/cc-generator.h"
#include "src/torque/constants.h"
#include "src/torque/csa-generator.h"
#include "src/torque/declaration-visitor.h"
@@ -56,58 +57,136 @@ const Type* ImplementationVisitor::Visit(Statement* stmt) {
return result;
}
-void ImplementationVisitor::BeginCSAFiles() {
+void ImplementationVisitor::BeginGeneratedFiles() {
+ std::set<SourceId> contains_class_definitions;
+ for (const ClassType* type : TypeOracle::GetClasses()) {
+ if (type->GenerateCppClassDefinitions()) {
+ contains_class_definitions.insert(type->AttributedToFile());
+ }
+ }
+
for (SourceId file : SourceFileMap::AllSources()) {
- std::ostream& source = GlobalContext::GeneratedPerFile(file).csa_ccfile;
- std::ostream& header = GlobalContext::GeneratedPerFile(file).csa_headerfile;
+ // Output beginning of CSA .cc file.
+ {
+ std::ostream& out = GlobalContext::GeneratedPerFile(file).csa_ccfile;
- for (const std::string& include_path : GlobalContext::CppIncludes()) {
- source << "#include " << StringLiteralQuote(include_path) << "\n";
- }
+ for (const std::string& include_path : GlobalContext::CppIncludes()) {
+ out << "#include " << StringLiteralQuote(include_path) << "\n";
+ }
- for (SourceId file : SourceFileMap::AllSources()) {
- source << "#include \"torque-generated/" +
- SourceFileMap::PathFromV8RootWithoutExtension(file) +
- "-tq-csa.h\"\n";
- }
- source << "\n";
-
- source << "namespace v8 {\n"
- << "namespace internal {\n"
- << "\n";
-
- std::string headerDefine =
- "V8_GEN_TORQUE_GENERATED_" +
- UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
- header << "#ifndef " << headerDefine << "\n";
- header << "#define " << headerDefine << "\n\n";
- header << "#include \"src/builtins/torque-csa-header-includes.h\"\n";
- header << "\n";
+ for (SourceId file : SourceFileMap::AllSources()) {
+ out << "#include \"torque-generated/" +
+ SourceFileMap::PathFromV8RootWithoutExtension(file) +
+ "-tq-csa.h\"\n";
+ }
+ out << "\n";
+
+ out << "namespace v8 {\n"
+ << "namespace internal {\n"
+ << "\n";
+ }
+ // Output beginning of CSA .h file.
+ {
+ std::ostream& out = GlobalContext::GeneratedPerFile(file).csa_headerfile;
+ std::string headerDefine =
+ "V8_GEN_TORQUE_GENERATED_" +
+ UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
+ out << "#ifndef " << headerDefine << "\n";
+ out << "#define " << headerDefine << "\n\n";
+ out << "#include \"src/builtins/torque-csa-header-includes.h\"\n";
+ out << "\n";
+
+ out << "namespace v8 {\n"
+ << "namespace internal {\n"
+ << "\n";
+ }
+ // Output beginning of class definition .cc file.
+ {
+ auto& streams = GlobalContext::GeneratedPerFile(file);
+ std::ostream& out = streams.class_definition_ccfile;
+ if (contains_class_definitions.count(file) != 0) {
+ out << "#include \""
+ << SourceFileMap::PathFromV8RootWithoutExtension(file)
+ << "-inl.h\"\n\n";
+ out << "#include \"torque-generated/class-verifiers.h\"\n";
+ out << "#include \"src/objects/instance-type-inl.h\"\n\n";
+ }
- header << "namespace v8 {\n"
- << "namespace internal {\n"
- << "\n";
+ out << "namespace v8 {\n";
+ out << "namespace internal {\n";
+ }
}
}
-void ImplementationVisitor::EndCSAFiles() {
+void ImplementationVisitor::EndGeneratedFiles() {
for (SourceId file : SourceFileMap::AllSources()) {
- std::ostream& source = GlobalContext::GeneratedPerFile(file).csa_ccfile;
- std::ostream& header = GlobalContext::GeneratedPerFile(file).csa_headerfile;
+ {
+ std::ostream& out = GlobalContext::GeneratedPerFile(file).csa_ccfile;
+
+ out << "} // namespace internal\n"
+ << "} // namespace v8\n"
+ << "\n";
+ }
+ {
+ std::ostream& out = GlobalContext::GeneratedPerFile(file).csa_headerfile;
- std::string headerDefine =
- "V8_GEN_TORQUE_GENERATED_" +
- UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
+ std::string headerDefine =
+ "V8_GEN_TORQUE_GENERATED_" +
+ UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
+
+ out << "} // namespace internal\n"
+ << "} // namespace v8\n"
+ << "\n";
+ out << "#endif // " << headerDefine << "\n";
+ }
+ {
+ std::ostream& out =
+ GlobalContext::GeneratedPerFile(file).class_definition_ccfile;
+
+ out << "} // namespace v8\n";
+ out << "} // namespace internal\n";
+ }
+ }
+}
- source << "} // namespace internal\n"
- << "} // namespace v8\n"
- << "\n";
+void ImplementationVisitor::BeginRuntimeMacrosFile() {
+ std::ostream& source = runtime_macros_cc_;
+ std::ostream& header = runtime_macros_h_;
- header << "} // namespace internal\n"
- << "} // namespace v8\n"
- << "\n";
- header << "#endif // " << headerDefine << "\n";
+ source << "#include \"torque-generated/runtime-macros.h\"\n\n";
+ source << "#include \"src/torque/runtime-macro-shims.h\"\n";
+ for (const std::string& include_path : GlobalContext::CppIncludes()) {
+ source << "#include " << StringLiteralQuote(include_path) << "\n";
}
+ source << "\n";
+
+ source << "namespace v8 {\n"
+ << "namespace internal {\n"
+ << "\n";
+
+ const char* kHeaderDefine = "V8_GEN_TORQUE_GENERATED_RUNTIME_MACROS_H_";
+ header << "#ifndef " << kHeaderDefine << "\n";
+ header << "#define " << kHeaderDefine << "\n\n";
+ header << "#include \"src/builtins/torque-csa-header-includes.h\"\n";
+ header << "\n";
+
+ header << "namespace v8 {\n"
+ << "namespace internal {\n"
+ << "\n";
+}
+
+void ImplementationVisitor::EndRuntimeMacrosFile() {
+ std::ostream& source = runtime_macros_cc_;
+ std::ostream& header = runtime_macros_h_;
+
+ source << "} // namespace internal\n"
+ << "} // namespace v8\n"
+ << "\n";
+
+ header << "\n} // namespace internal\n"
+ << "} // namespace v8\n"
+ << "\n";
+ header << "#endif // V8_GEN_TORQUE_GENERATED_RUNTIME_MACROS_H_\n";
}
void ImplementationVisitor::Visit(NamespaceConstant* decl) {
@@ -116,15 +195,15 @@ void ImplementationVisitor::Visit(NamespaceConstant* decl) {
BindingsManagersScope bindings_managers_scope;
- header_out() << " ";
- GenerateFunctionDeclaration(header_out(), "", decl->external_name(),
+ csa_headerfile() << " ";
+ GenerateFunctionDeclaration(csa_headerfile(), "", decl->external_name(),
signature, {});
- header_out() << ";\n";
+ csa_headerfile() << ";\n";
- GenerateFunctionDeclaration(source_out(), "", decl->external_name(),
+ GenerateFunctionDeclaration(csa_ccfile(), "", decl->external_name(),
signature, {});
- source_out() << " {\n";
- source_out() << " compiler::CodeAssembler ca_(state_);\n";
+ csa_ccfile() << " {\n";
+ csa_ccfile() << " compiler::CodeAssembler ca_(state_);\n";
DCHECK(!signature.return_type->IsVoidOrNever());
@@ -134,15 +213,15 @@ void ImplementationVisitor::Visit(NamespaceConstant* decl) {
VisitResult return_result =
GenerateImplicitConvert(signature.return_type, expression_result);
- CSAGenerator csa_generator{assembler().Result(), source_out()};
+ CSAGenerator csa_generator{assembler().Result(), csa_ccfile()};
Stack<std::string> values = *csa_generator.EmitGraph(Stack<std::string>{});
assembler_ = base::nullopt;
- source_out() << " return ";
- CSAGenerator::EmitCSAValue(return_result, values, source_out());
- source_out() << ";\n";
- source_out() << "}\n\n";
+ csa_ccfile() << " return ";
+ CSAGenerator::EmitCSAValue(return_result, values, csa_ccfile());
+ csa_ccfile() << ";\n";
+ csa_ccfile() << "}\n\n";
}
void ImplementationVisitor::Visit(TypeAlias* alias) {
@@ -274,14 +353,21 @@ void ImplementationVisitor::VisitMacroCommon(Macro* macro) {
bool has_return_value =
can_return && return_type != TypeOracle::GetVoidType();
- GenerateMacroFunctionDeclaration(header_out(), "", macro);
- header_out() << ";\n";
+ GenerateMacroFunctionDeclaration(csa_headerfile(), macro);
+ csa_headerfile() << ";\n";
- GenerateMacroFunctionDeclaration(source_out(), "", macro);
- source_out() << " {\n";
- source_out() << " compiler::CodeAssembler ca_(state_);\n";
- source_out()
- << " compiler::CodeAssembler::SourcePositionScope pos_scope(&ca_);\n";
+ GenerateMacroFunctionDeclaration(csa_ccfile(), macro);
+ csa_ccfile() << " {\n";
+
+ if (output_type_ == OutputType::kCC) {
+ // For now, generated C++ is only for field offset computations. If we ever
+ // generate C++ code that can allocate, then it should be handlified.
+ csa_ccfile() << " DisallowHeapAllocation no_gc;\n";
+ } else {
+ csa_ccfile() << " compiler::CodeAssembler ca_(state_);\n";
+ csa_ccfile()
+ << " compiler::CodeAssembler::SourcePositionScope pos_scope(&ca_);\n";
+ }
Stack<std::string> lowered_parameters;
Stack<const Type*> lowered_parameter_types;
@@ -363,18 +449,27 @@ void ImplementationVisitor::VisitMacroCommon(Macro* macro) {
assembler().Bind(end);
}
- CSAGenerator csa_generator{assembler().Result(), source_out()};
- base::Optional<Stack<std::string>> values =
- csa_generator.EmitGraph(lowered_parameters);
+ base::Optional<Stack<std::string>> values;
+ if (output_type_ == OutputType::kCC) {
+ CCGenerator cc_generator{assembler().Result(), csa_ccfile()};
+ values = cc_generator.EmitGraph(lowered_parameters);
+ } else {
+ CSAGenerator csa_generator{assembler().Result(), csa_ccfile()};
+ values = csa_generator.EmitGraph(lowered_parameters);
+ }
assembler_ = base::nullopt;
if (has_return_value) {
- source_out() << " return ";
- CSAGenerator::EmitCSAValue(return_value, *values, source_out());
- source_out() << ";\n";
+ csa_ccfile() << " return ";
+ if (output_type_ == OutputType::kCC) {
+ CCGenerator::EmitCCValue(return_value, *values, csa_ccfile());
+ } else {
+ CSAGenerator::EmitCSAValue(return_value, *values, csa_ccfile());
+ }
+ csa_ccfile() << ";\n";
}
- source_out() << "}\n\n";
+ csa_ccfile() << "}\n\n";
}
void ImplementationVisitor::Visit(TorqueMacro* macro) {
@@ -416,7 +511,7 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
const std::string& name = builtin->ExternalName();
const Signature& signature = builtin->signature();
- source_out() << "TF_BUILTIN(" << name << ", CodeStubAssembler) {\n"
+ csa_ccfile() << "TF_BUILTIN(" << name << ", CodeStubAssembler) {\n"
<< " compiler::CodeAssemblerState* state_ = state();"
<< " compiler::CodeAssembler ca_(state());\n";
@@ -435,17 +530,17 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
.Position(signature.parameter_names[signature.implicit_count]->pos);
}
- source_out()
- << " Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);\n";
- source_out() << " TNode<IntPtrT> "
+ csa_ccfile() << " TNode<Word32T> argc = UncheckedParameter<Word32T>("
+ << "Descriptor::kJSActualArgumentsCount);\n";
+ csa_ccfile() << " TNode<IntPtrT> "
"arguments_length(ChangeInt32ToIntPtr(UncheckedCast<"
"Int32T>(argc)));\n";
- source_out() << " TNode<RawPtrT> arguments_frame = "
+ csa_ccfile() << " TNode<RawPtrT> arguments_frame = "
"UncheckedCast<RawPtrT>(LoadFramePointer());\n";
- source_out() << " TorqueStructArguments "
+ csa_ccfile() << " TorqueStructArguments "
"torque_arguments(GetFrameArguments(arguments_frame, "
"arguments_length));\n";
- source_out()
+ csa_ccfile()
<< " CodeStubArguments arguments(this, torque_arguments);\n";
parameters.Push("torque_arguments.frame");
@@ -468,32 +563,32 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
const Type* actual_type = signature.parameter_types.types[i];
std::vector<const Type*> expected_types;
if (param_name == "context") {
- source_out() << " TNode<NativeContext> " << generated_name
- << " = UncheckedCast<NativeContext>(Parameter("
- << "Descriptor::kContext));\n";
- source_out() << " USE(" << generated_name << ");\n";
+ csa_ccfile() << " TNode<NativeContext> " << generated_name
+ << " = UncheckedParameter<NativeContext>("
+ << "Descriptor::kContext);\n";
+ csa_ccfile() << " USE(" << generated_name << ");\n";
expected_types = {TypeOracle::GetNativeContextType(),
TypeOracle::GetContextType()};
} else if (param_name == "receiver") {
- source_out()
+ csa_ccfile()
<< " TNode<Object> " << generated_name << " = "
<< (builtin->IsVarArgsJavaScript()
? "arguments.GetReceiver()"
- : "UncheckedCast<Object>(Parameter(Descriptor::kReceiver))")
+ : "UncheckedParameter<Object>(Descriptor::kReceiver)")
<< ";\n";
- source_out() << "USE(" << generated_name << ");\n";
+ csa_ccfile() << "USE(" << generated_name << ");\n";
expected_types = {TypeOracle::GetJSAnyType()};
} else if (param_name == "newTarget") {
- source_out() << " TNode<Object> " << generated_name
- << " = UncheckedCast<Object>(Parameter("
- << "Descriptor::kJSNewTarget));\n";
- source_out() << "USE(" << generated_name << ");\n";
+ csa_ccfile() << " TNode<Object> " << generated_name
+ << " = UncheckedParameter<Object>("
+ << "Descriptor::kJSNewTarget);\n";
+ csa_ccfile() << "USE(" << generated_name << ");\n";
expected_types = {TypeOracle::GetJSAnyType()};
} else if (param_name == "target") {
- source_out() << " TNode<JSFunction> " << generated_name
- << " = UncheckedCast<JSFunction>(Parameter("
- << "Descriptor::kJSTarget));\n";
- source_out() << "USE(" << generated_name << ");\n";
+ csa_ccfile() << " TNode<JSFunction> " << generated_name
+ << " = UncheckedParameter<JSFunction>("
+ << "Descriptor::kJSTarget);\n";
+ csa_ccfile() << "USE(" << generated_name << ");\n";
expected_types = {TypeOracle::GetJSFunctionType()};
} else {
Error(
@@ -519,12 +614,12 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
const bool mark_as_used = signature.implicit_count > i;
std::string var = AddParameter(i, builtin, &parameters, &parameter_types,
&parameter_bindings, mark_as_used);
- source_out() << " " << type->GetGeneratedTypeName() << " " << var
+ csa_ccfile() << " " << type->GetGeneratedTypeName() << " " << var
<< " = "
- << "UncheckedCast<" << type->GetGeneratedTNodeTypeName()
- << ">(Parameter(Descriptor::k"
- << CamelifyString(parameter_name) << "));\n";
- source_out() << " USE(" << var << ");\n";
+ << "UncheckedParameter<" << type->GetGeneratedTNodeTypeName()
+ << ">(Descriptor::k" << CamelifyString(parameter_name)
+ << ");\n";
+ csa_ccfile() << " USE(" << var << ");\n";
}
} else {
@@ -536,18 +631,18 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
const bool mark_as_used = signature.implicit_count > i;
std::string var = AddParameter(i, builtin, &parameters, &parameter_types,
&parameter_bindings, mark_as_used);
- source_out() << " " << type->GetGeneratedTypeName() << " " << var
+ csa_ccfile() << " " << type->GetGeneratedTypeName() << " " << var
<< " = "
- << "UncheckedCast<" << type->GetGeneratedTNodeTypeName()
- << ">(Parameter(";
+ << "UncheckedParameter<" << type->GetGeneratedTNodeTypeName()
+ << ">(";
if (i == 0 && has_context_parameter) {
- source_out() << "Descriptor::kContext";
+ csa_ccfile() << "Descriptor::kContext";
} else {
- source_out() << "Descriptor::ParameterIndex<"
+ csa_ccfile() << "Descriptor::ParameterIndex<"
<< (has_context_parameter ? i - 1 : i) << ">()";
}
- source_out() << "));\n";
- source_out() << " USE(" << var << ");\n";
+ csa_ccfile() << ");\n";
+ csa_ccfile() << " USE(" << var << ");\n";
}
}
assembler_ = CfgAssembler(parameter_types);
@@ -555,11 +650,11 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
if (body_result != TypeOracle::GetNeverType()) {
ReportError("control reaches end of builtin, expected return of a value");
}
- CSAGenerator csa_generator{assembler().Result(), source_out(),
+ CSAGenerator csa_generator{assembler().Result(), csa_ccfile(),
builtin->kind()};
csa_generator.EmitGraph(parameters);
assembler_ = base::nullopt;
- source_out() << "}\n\n";
+ csa_ccfile() << "}\n\n";
}
const Type* ImplementationVisitor::Visit(VarDeclarationStatement* stmt) {
@@ -1255,53 +1350,20 @@ InitializerResults ImplementationVisitor::VisitInitializerResults(
LocationReference ImplementationVisitor::GenerateFieldReference(
VisitResult object, const Field& field, const ClassType* class_type) {
+ if (field.index.has_value()) {
+ return LocationReference::HeapSlice(
+ GenerateCall(class_type->GetSliceMacroName(field), {{object}, {}}));
+ }
+ DCHECK(field.offset.has_value());
StackRange result_range = assembler().TopRange(0);
result_range.Extend(GenerateCopy(object).stack_range());
- VisitResult offset;
- if (field.offset.has_value()) {
- offset =
- VisitResult(TypeOracle::GetConstInt31Type(), ToString(*field.offset));
- offset = GenerateImplicitConvert(TypeOracle::GetIntPtrType(), offset);
- } else {
- StackScope stack_scope(this);
- for (const Field& f : class_type->ComputeAllFields()) {
- if (f.offset) {
- offset =
- VisitResult(TypeOracle::GetConstInt31Type(), ToString(*f.offset));
- }
- if (f.name_and_type.name == field.name_and_type.name) break;
- if (f.index) {
- if (!offset.IsOnStack()) {
- offset = GenerateImplicitConvert(TypeOracle::GetIntPtrType(), offset);
- }
- VisitResult array_length = GenerateArrayLength(object, f);
- size_t element_size;
- std::string element_size_string;
- std::tie(element_size, element_size_string) =
- *SizeOf(f.name_and_type.type);
- VisitResult array_element_size =
- VisitResult(TypeOracle::GetConstInt31Type(), element_size_string);
- // In contrast to the code used for allocation, we don't need overflow
- // checks here because we already know all the offsets fit into memory.
- VisitResult array_size =
- GenerateCall("*", {{array_length, array_element_size}, {}});
- offset = GenerateCall("+", {{offset, array_size}, {}});
- }
- }
- DCHECK(offset.IsOnStack());
- offset = stack_scope.Yield(offset);
- }
+ VisitResult offset =
+ VisitResult(TypeOracle::GetConstInt31Type(), ToString(*field.offset));
+ offset = GenerateImplicitConvert(TypeOracle::GetIntPtrType(), offset);
result_range.Extend(offset.stack_range());
- if (field.index) {
- VisitResult length = GenerateArrayLength(object, field);
- result_range.Extend(length.stack_range());
- const Type* slice_type = TypeOracle::GetSliceType(field.name_and_type.type);
- return LocationReference::HeapSlice(VisitResult(slice_type, result_range));
- } else {
- const Type* type = TypeOracle::GetReferenceType(field.name_and_type.type,
- field.const_qualified);
- return LocationReference::HeapReference(VisitResult(type, result_range));
- }
+ const Type* type = TypeOracle::GetReferenceType(field.name_and_type.type,
+ field.const_qualified);
+ return LocationReference::HeapReference(VisitResult(type, result_range));
}
// This is used to generate field references during initialization, where we can
@@ -1625,25 +1687,30 @@ VisitResult ImplementationVisitor::Visit(SpreadExpression* expr) {
void ImplementationVisitor::GenerateImplementation(const std::string& dir) {
for (SourceId file : SourceFileMap::AllSources()) {
- std::string path_from_root =
- SourceFileMap::PathFromV8RootWithoutExtension(file);
-
- std::string new_source(
- GlobalContext::GeneratedPerFile(file).csa_ccfile.str());
+ std::string base_filename =
+ dir + "/" + SourceFileMap::PathFromV8RootWithoutExtension(file);
+ GlobalContext::PerFileStreams& streams =
+ GlobalContext::GeneratedPerFile(file);
- std::string source_file_name = dir + "/" + path_from_root + "-tq-csa.cc";
- WriteFile(source_file_name, new_source);
- std::string new_header(
- GlobalContext::GeneratedPerFile(file).csa_headerfile.str());
- std::string header_file_name = dir + "/" + path_from_root + "-tq-csa.h";
- WriteFile(header_file_name, new_header);
+ WriteFile(base_filename + "-tq-csa.cc", streams.csa_ccfile.str());
+ WriteFile(base_filename + "-tq-csa.h", streams.csa_headerfile.str());
+ WriteFile(base_filename + "-tq.inc",
+ streams.class_definition_headerfile.str());
+ WriteFile(base_filename + "-tq-inl.inc",
+ streams.class_definition_inline_headerfile.str());
+ WriteFile(base_filename + "-tq.cc", streams.class_definition_ccfile.str());
}
+
+ WriteFile(dir + "/runtime-macros.h", runtime_macros_h_.str());
+ WriteFile(dir + "/runtime-macros.cc", runtime_macros_cc_.str());
}
-void ImplementationVisitor::GenerateMacroFunctionDeclaration(
- std::ostream& o, const std::string& macro_prefix, Macro* macro) {
- GenerateFunctionDeclaration(o, macro_prefix, macro->ExternalName(),
- macro->signature(), macro->parameter_names());
+void ImplementationVisitor::GenerateMacroFunctionDeclaration(std::ostream& o,
+ Macro* macro) {
+ GenerateFunctionDeclaration(
+ o, "",
+ output_type_ == OutputType::kCC ? macro->CCName() : macro->ExternalName(),
+ macro->signature(), macro->parameter_names());
}
std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
@@ -1654,12 +1721,17 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
if (signature.return_type->IsVoidOrNever()) {
o << "void";
} else {
- o << signature.return_type->GetGeneratedTypeName();
+ o << (output_type_ == OutputType::kCC
+ ? signature.return_type->GetRuntimeType()
+ : signature.return_type->GetGeneratedTypeName());
}
o << " " << macro_prefix << name << "(";
bool first = true;
- if (pass_code_assembler_state) {
+ if (output_type_ == OutputType::kCC) {
+ first = false;
+ o << "Isolate* isolate";
+ } else if (pass_code_assembler_state) {
first = false;
o << "compiler::CodeAssemblerState* state_";
}
@@ -1670,7 +1742,9 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
first = false;
const Type* parameter_type = signature.types()[i];
const std::string& generated_type_name =
- parameter_type->GetGeneratedTypeName();
+ output_type_ == OutputType::kCC
+ ? parameter_type->GetRuntimeType()
+ : parameter_type->GetGeneratedTypeName();
generated_parameter_names.push_back(ExternalParameterName(
i < parameter_names.size() ? parameter_names[i]->value
@@ -1679,6 +1753,9 @@ std::vector<std::string> ImplementationVisitor::GenerateFunctionDeclaration(
}
for (const LabelDeclaration& label_info : signature.labels) {
+ if (output_type_ == OutputType::kCC) {
+ ReportError("Macros that generate runtime code can't have label exits");
+ }
if (!first) o << ", ";
first = false;
generated_parameter_names.push_back(
@@ -2487,7 +2564,7 @@ VisitResult ImplementationVisitor::GenerateCall(
}
}
- bool inline_macro = callable->ShouldBeInlined();
+ bool inline_macro = callable->ShouldBeInlined(output_type_);
std::vector<VisitResult> implicit_arguments;
for (size_t i = 0; i < callable->signature().implicit_count; ++i) {
std::string implicit_name = callable->signature().parameter_names[i]->value;
@@ -2594,7 +2671,18 @@ VisitResult ImplementationVisitor::GenerateCall(
if (is_tailcall) {
ReportError("can't tail call a macro");
}
+
macro->SetUsed();
+
+ // If we're currently generating a C++ macro and it's calling another macro,
+ // then we need to make sure that we also generate C++ code for the called
+ // macro.
+ if (output_type_ == OutputType::kCC && !inline_macro) {
+ if (auto* torque_macro = TorqueMacro::DynamicCast(macro)) {
+ GlobalContext::EnsureInCCOutputList(torque_macro);
+ }
+ }
+
if (return_type->IsConstexpr()) {
DCHECK_EQ(0, arguments.labels.size());
std::stringstream result;
@@ -2774,6 +2862,15 @@ VisitResult ImplementationVisitor::GenerateCall(
result << constexpr_arguments[0];
result << ")";
return VisitResult(return_type, result.str());
+ } else if (intrinsic->ExternalName() == "%IndexedFieldLength") {
+ const Type* type = specialization_types[0];
+ const ClassType* class_type = ClassType::DynamicCast(type);
+ if (!class_type) {
+ ReportError("%IndexedFieldLength must take a class type parameter");
+ }
+ const Field& field =
+ class_type->LookupField(StringLiteralUnquote(constexpr_arguments[0]));
+ return GenerateArrayLength(VisitResult(type, argument_range), field);
} else {
assembler().Emit(CallIntrinsicInstruction{intrinsic, specialization_types,
constexpr_arguments});
@@ -3065,6 +3162,7 @@ void ImplementationVisitor::VisitAllDeclarables() {
CurrentCallable::Scope current_callable(nullptr);
const std::vector<std::unique_ptr<Declarable>>& all_declarables =
GlobalContext::AllDeclarables();
+
// This has to be an index-based loop because all_declarables can be extended
// during the loop.
for (size_t i = 0; i < all_declarables.size(); ++i) {
@@ -3074,6 +3172,19 @@ void ImplementationVisitor::VisitAllDeclarables() {
// Recover from compile errors here. The error is recorded already.
}
}
+
+ // Do the same for macros which generate C++ code.
+ output_type_ = OutputType::kCC;
+ const std::vector<TorqueMacro*>& cc_macros =
+ GlobalContext::AllMacrosForCCOutput();
+ for (size_t i = 0; i < cc_macros.size(); ++i) {
+ try {
+ Visit(static_cast<Declarable*>(cc_macros[i]));
+ } catch (TorqueAbortCompilation&) {
+ // Recover from compile errors here. The error is recorded already.
+ }
+ }
+ output_type_ = OutputType::kCSA;
}
void ImplementationVisitor::Visit(Declarable* declarable) {
@@ -3082,7 +3193,7 @@ void ImplementationVisitor::Visit(Declarable* declarable) {
CurrentFileStreams::Scope current_file_streams(
&GlobalContext::GeneratedPerFile(declarable->Position().source));
if (Callable* callable = Callable::DynamicCast(declarable)) {
- if (!callable->ShouldGenerateExternalCode())
+ if (!callable->ShouldGenerateExternalCode(output_type_))
CurrentFileStreams::Get() = nullptr;
}
switch (declarable->kind()) {
@@ -3605,6 +3716,17 @@ base::Optional<std::vector<Field>> GetOrderedUniqueIndexFields(
}
void CppClassGenerator::GenerateClass() {
+ hdr_ << "\n";
+ hdr_ << "// Alias for HeapObject::Is" << name_
+ << "() that avoids inlining.\n";
+ hdr_ << "V8_EXPORT_PRIVATE bool Is" << name_ << "_NonInline(HeapObject o);\n";
+ hdr_ << "\n";
+
+ impl_ << "\n";
+ impl_ << "bool Is" << name_ << "_NonInline(HeapObject o) {\n";
+ impl_ << " return o.Is" << name_ << "();\n";
+ impl_ << "}\n\n";
+
hdr_ << template_decl() << "\n";
hdr_ << "class " << gen_name_ << " : public P {\n";
hdr_ << " static_assert(std::is_same<" << name_ << ", D>::value,\n"
@@ -3707,7 +3829,7 @@ void CppClassGenerator::GenerateClass() {
hdr_ << "};\n\n";
- if (!type_->IsExtern()) {
+ if (type_->ShouldGenerateFullClassDefinition()) {
GenerateClassExport(type_, hdr_, inl_);
}
}
@@ -3732,7 +3854,7 @@ void CppClassGenerator::GenerateClassConstructors() {
<< name_ << ".\");\n";
hdr_ << " }\n";
- hdr_ << "protected:\n";
+ hdr_ << " protected:\n";
hdr_ << " inline explicit " << gen_name_ << "(Address ptr);\n";
hdr_ << " // Special-purpose constructor for subclasses that have fast "
"paths where\n";
@@ -3743,16 +3865,17 @@ void CppClassGenerator::GenerateClassConstructors() {
inl_ << "template<class D, class P>\n";
inl_ << "inline " << gen_name_T_ << "::" << gen_name_ << "(Address ptr)\n";
inl_ << " : P(ptr) {\n";
- inl_ << " SLOW_DCHECK(this->Is" << name_ << "());\n";
+ inl_ << " SLOW_DCHECK(Is" << name_ << "_NonInline(*this));\n";
inl_ << "}\n";
inl_ << "template<class D, class P>\n";
inl_ << "inline " << gen_name_T_ << "::" << gen_name_
<< "(Address ptr, HeapObject::AllowInlineSmiStorage allow_smi)\n";
inl_ << " : P(ptr, allow_smi) {\n";
- inl_ << " SLOW_DCHECK((allow_smi == "
- "HeapObject::AllowInlineSmiStorage::kAllowBeingASmi && "
- << "this->IsSmi()) || this->Is" << name_ << "());\n";
+ inl_ << " SLOW_DCHECK("
+ << "(allow_smi == HeapObject::AllowInlineSmiStorage::kAllowBeingASmi"
+ " && this->IsSmi()) || Is"
+ << name_ << "_NonInline(*this));\n";
inl_ << "}\n";
}
@@ -3767,15 +3890,15 @@ std::string GenerateRuntimeTypeCheck(const Type* type,
type_check << value << ".IsCleared()";
at_start = false;
}
- for (const RuntimeType& runtime_type : type->GetRuntimeTypes()) {
+ for (const TypeChecker& runtime_type : type->GetTypeCheckers()) {
if (!at_start) type_check << " || ";
at_start = false;
if (maybe_object) {
bool strong = runtime_type.weak_ref_to.empty();
- if (strong && runtime_type.type == "MaybeObject") {
- // Rather than a generic Weak<T>, this is a basic type Tagged or
- // WeakHeapObject. We can't validate anything more about the type of
- // the object pointed to, so just check that it's weak.
+ if (strong && runtime_type.type == WEAK_HEAP_OBJECT) {
+ // Rather than a generic Weak<T>, this is the basic type WeakHeapObject.
+ // We can't validate anything more about the type of the object pointed
+ // to, so just check that it's weak.
type_check << value << ".IsWeak()";
} else {
type_check << "(" << (strong ? "!" : "") << value << ".IsWeak() && "
@@ -3954,7 +4077,7 @@ void CppClassGenerator::GenerateFieldAccessorForTagged(const Field& f) {
std::string offset = "k" + CamelifyString(name) + "Offset";
bool strong_pointer = field_type->IsSubtypeOf(TypeOracle::GetObjectType());
- std::string type = field_type->GetRuntimeType();
+ std::string type = field_type->UnhandlifiedCppTypeName();
// Generate declarations in header.
if (!field_type->IsClassType() && field_type != TypeOracle::GetObjectType()) {
hdr_ << " // Torque type: " << field_type->ToString() << "\n";
@@ -3962,7 +4085,7 @@ void CppClassGenerator::GenerateFieldAccessorForTagged(const Field& f) {
hdr_ << " inline " << type << " " << name << "(" << (f.index ? "int i" : "")
<< ") const;\n";
- hdr_ << " inline " << type << " " << name << "(const Isolate* isolates"
+ hdr_ << " inline " << type << " " << name << "(IsolateRoot isolates"
<< (f.index ? ", int i" : "") << ") const;\n";
hdr_ << " inline void set_" << name << "(" << (f.index ? "int i, " : "")
<< type << " value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);\n\n";
@@ -3973,15 +4096,14 @@ void CppClassGenerator::GenerateFieldAccessorForTagged(const Field& f) {
inl_ << "template <class D, class P>\n";
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "("
<< (f.index ? "int i" : "") << ") const {\n";
- inl_ << " const Isolate* isolate = GetIsolateForPtrCompr(*this);\n";
+ inl_ << " IsolateRoot isolate = GetIsolateForPtrCompr(*this);\n";
inl_ << " return " << gen_name_ << "::" << name << "(isolate"
<< (f.index ? ", i" : "") << ");\n";
inl_ << "}\n";
inl_ << "template <class D, class P>\n";
inl_ << type << " " << gen_name_ << "<D, P>::" << name
- << "(const Isolate* isolate" << (f.index ? ", int i" : "")
- << ") const {\n";
+ << "(IsolateRoot isolate" << (f.index ? ", int i" : "") << ") const {\n";
// TODO(tebbi): The distinction between relaxed and non-relaxed accesses here
// is pretty arbitrary and just tries to preserve what was there before.
@@ -4031,35 +4153,6 @@ void CppClassGenerator::GenerateFieldAccessorForTagged(const Field& f) {
inl_ << "}\n\n";
}
-void EmitClassDefinitionHeadersIncludes(const std::string& basename,
- std::stringstream& header,
- std::stringstream& inline_header) {
- header << "#include \"src/objects/objects.h\"\n";
- header << "#include \"src/objects/heap-object.h\"\n";
- header << "#include \"src/objects/smi.h\"\n";
- header << "#include \"torque-generated/field-offsets.h\"\n";
- header << "#include <type_traits>\n\n";
-
- inline_header << "#include \"torque-generated/class-definitions.h\"\n";
- inline_header << "#include \"src/objects/js-function.h\"\n";
- inline_header << "#include \"src/objects/js-objects.h\"\n";
- inline_header << "#include \"src/objects/js-promise.h\"\n";
- inline_header << "#include \"src/objects/js-weak-refs.h\"\n";
- inline_header << "#include \"src/objects/module.h\"\n";
- inline_header << "#include \"src/objects/objects-inl.h\"\n";
- inline_header << "#include \"src/objects/script.h\"\n";
- inline_header << "#include \"src/objects/shared-function-info.h\"\n";
- inline_header << "#include \"src/objects/tagged-field.h\"\n\n";
-}
-
-void EmitClassDefinitionHeadersForwardDeclarations(std::stringstream& header) {
- // Generate forward declarations for every class.
- for (const ClassType* type : TypeOracle::GetClasses()) {
- header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
- }
- header << "using BuiltinPtr = Smi;\n\n";
-}
-
void GenerateStructLayoutDescription(std::ostream& header,
const StructType* type) {
header << "struct TorqueGenerated" << CamelifyString(type->name())
@@ -4077,125 +4170,45 @@ void GenerateStructLayoutDescription(std::ostream& header,
void ImplementationVisitor::GenerateClassDefinitions(
const std::string& output_directory) {
- std::stringstream external_header;
- std::stringstream inline_external_header;
- std::stringstream internal_header;
- std::stringstream inline_internal_header;
- std::stringstream exported_header;
- std::stringstream inline_exported_header;
- std::stringstream implementation;
std::stringstream factory_header;
std::stringstream factory_impl;
- std::string basename = "class-definitions";
- std::string internal_basename = "internal-" + basename;
- std::string exported_basename = "exported-" + basename;
- std::string file_basename = output_directory + "/" + basename;
- std::string internal_file_basename =
- output_directory + "/" + internal_basename;
- std::string exported_file_basename =
- output_directory + "/" + exported_basename;
std::string factory_basename = "factory";
- std::string factory_file_basename = output_directory + "/" + factory_basename;
-
- {
- IncludeGuardScope header_guard(external_header, basename + ".h");
-
- IncludeGuardScope inline_header_guard(inline_external_header,
- basename + "-inl.h");
-
- IncludeGuardScope internal_header_guard(internal_header,
- internal_basename + ".h");
-
- IncludeGuardScope internal_inline_header_guard(
- inline_internal_header, internal_basename + "-inl.h");
-
- IncludeGuardScope exported_header_guard(exported_header,
- exported_basename + ".h");
-
- IncludeGuardScope exported_inline_header_guard(
- inline_exported_header, exported_basename + "-inl.h");
-
- internal_header << "#include \"torque-generated/class-definitions.h\"\n";
- internal_header << "#include \"src/objects/fixed-array.h\"\n";
- inline_internal_header
- << "#include \"torque-generated/internal-class-definitions.h\"\n";
- inline_internal_header
- << "#include \"torque-generated/class-definitions-inl.h\"\n";
-
- exported_header << "#include \"src/objects/fixed-array.h\"\n";
- exported_header << "#include \"torque-generated/class-definitions.h\"\n";
- inline_exported_header
- << "#include \"torque-generated/exported-class-definitions.h\"\n";
- inline_exported_header << "#include \"src/objects/fixed-array-inl.h\"\n";
-
- EmitClassDefinitionHeadersIncludes(basename, external_header,
- inline_external_header);
-
- EmitClassDefinitionHeadersIncludes(internal_basename, internal_header,
- inline_internal_header);
-
- IncludeObjectMacrosScope header_macros(external_header);
- IncludeObjectMacrosScope inline_header_macros(inline_external_header);
-
- IncludeObjectMacrosScope internal_header_macros(internal_header);
- IncludeObjectMacrosScope internal_inline_header_macros(
- inline_internal_header);
- IncludeObjectMacrosScope exported_header_macros(exported_header);
- IncludeObjectMacrosScope exported_inline_header_macros(
- inline_exported_header);
-
- NamespaceScope header_namespaces(external_header, {"v8", "internal"});
- NamespaceScope inline_header_namespaces(inline_external_header,
- {"v8", "internal"});
- NamespaceScope internal_header_namespaces(internal_header,
- {"v8", "internal"});
- NamespaceScope internal_inline_header_namespaces(inline_internal_header,
- {"v8", "internal"});
- NamespaceScope exported_header_namespaces(exported_header,
- {"v8", "internal"});
- NamespaceScope exported_inline_header_namespaces(inline_exported_header,
- {"v8", "internal"});
-
- EmitClassDefinitionHeadersForwardDeclarations(external_header);
- EmitClassDefinitionHeadersForwardDeclarations(internal_header);
+ std::stringstream forward_declarations;
+ std::string forward_declarations_filename = "class-forward-declarations.h";
+ {
factory_impl << "#include \"src/heap/factory.h\"\n";
factory_impl << "#include \"src/heap/factory-inl.h\"\n";
factory_impl << "#include \"src/heap/heap.h\"\n";
factory_impl << "#include \"src/heap/heap-inl.h\"\n";
- factory_impl << "#include \"src/execution/isolate.h\"\n\n";
- factory_impl << "#include "
- "\"torque-generated/internal-class-definitions-inl.h\"\n\n";
+ factory_impl << "#include \"src/execution/isolate.h\"\n";
factory_impl << "#include "
- "\"torque-generated/exported-class-definitions-inl.h\"\n\n";
+ "\"src/objects/all-objects-inl.h\"\n\n";
NamespaceScope factory_impl_namespaces(factory_impl, {"v8", "internal"});
factory_impl << "\n";
- implementation << "#include \"torque-generated/class-definitions.h\"\n\n";
- implementation << "#include \"torque-generated/class-verifiers.h\"\n\n";
- implementation
- << "#include \"src/objects/class-definitions-tq-deps-inl.h\"\n\n";
- implementation
- << "#include "
- "\"torque-generated/internal-class-definitions-inl.h\"\n\n";
- implementation
- << "#include "
- "\"torque-generated/exported-class-definitions-inl.h\"\n\n";
- NamespaceScope implementation_namespaces(implementation,
- {"v8", "internal"});
+ IncludeGuardScope include_guard(forward_declarations,
+ forward_declarations_filename);
+ NamespaceScope forward_declarations_namespaces(forward_declarations,
+ {"v8", "internal"});
std::set<const StructType*, TypeLess> structs_used_in_classes;
+ // Emit forward declarations.
+ for (const ClassType* type : TypeOracle::GetClasses()) {
+ auto& streams = GlobalContext::GeneratedPerFile(type->AttributedToFile());
+ std::ostream& header = streams.class_definition_headerfile;
+ header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
+ forward_declarations << "class " << type->GetGeneratedTNodeTypeName()
+ << ";\n";
+ }
+
for (const ClassType* type : TypeOracle::GetClasses()) {
- std::stringstream& header =
- type->IsExtern()
- ? external_header
- : type->ShouldExport() ? exported_header : internal_header;
- std::stringstream& inline_header =
- type->IsExtern() ? inline_external_header
- : type->ShouldExport() ? inline_exported_header
- : inline_internal_header;
+ auto& streams = GlobalContext::GeneratedPerFile(type->AttributedToFile());
+ std::ostream& header = streams.class_definition_headerfile;
+ std::ostream& inline_header = streams.class_definition_inline_headerfile;
+ std::ostream& implementation = streams.class_definition_ccfile;
if (type->GenerateCppClassDefinitions()) {
CppClassGenerator g(type, header, inline_header, implementation);
@@ -4207,7 +4220,8 @@ void ImplementationVisitor::GenerateClassDefinitions(
structs_used_in_classes.insert(*field_as_struct);
}
}
- if (type->ShouldExport() && !type->IsAbstract()) {
+ if (type->ShouldExport() && !type->IsAbstract() &&
+ !type->HasCustomMap()) {
factory_header << type->HandlifiedCppTypeName() << " New"
<< type->name() << "(";
factory_impl << type->HandlifiedCppTypeName() << " Factory::New"
@@ -4251,9 +4265,12 @@ void ImplementationVisitor::GenerateClassDefinitions(
factory_impl << " "
"isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>"
"(size, allocation_type);\n";
+ factory_impl << " WriteBarrierMode write_barrier_mode =\n"
+ << " allocation_type == AllocationType::kYoung\n"
+ << " ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;\n";
factory_impl << " result.set_map_after_allocation(roots."
<< SnakeifyString(type->name())
- << "_map(), SKIP_WRITE_BARRIER);\n";
+ << "_map(), write_barrier_mode);\n";
factory_impl << " " << type->HandlifiedCppTypeName()
<< " result_handle(" << type->name()
<< "::cast(result), isolate());\n";
@@ -4267,7 +4284,7 @@ void ImplementationVisitor::GenerateClassDefinitions(
TypeOracle::GetTaggedType()) &&
!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())) {
factory_impl << "*" << f.name_and_type.name
- << ", SKIP_WRITE_BARRIER";
+ << ", write_barrier_mode";
} else {
factory_impl << f.name_and_type.name;
}
@@ -4281,20 +4298,20 @@ void ImplementationVisitor::GenerateClassDefinitions(
}
for (const StructType* type : structs_used_in_classes) {
+ std::ostream& header =
+ GlobalContext::GeneratedPerFile(type->GetPosition().source)
+ .class_definition_headerfile;
if (type != TypeOracle::GetFloat64OrHoleType()) {
- GenerateStructLayoutDescription(external_header, type);
+ GenerateStructLayoutDescription(header, type);
}
}
}
- WriteFile(file_basename + ".h", external_header.str());
- WriteFile(file_basename + "-inl.h", inline_external_header.str());
- WriteFile(file_basename + ".cc", implementation.str());
- WriteFile(internal_file_basename + ".h", internal_header.str());
- WriteFile(internal_file_basename + "-inl.h", inline_internal_header.str());
- WriteFile(exported_file_basename + ".h", exported_header.str());
- WriteFile(exported_file_basename + "-inl.h", inline_exported_header.str());
- WriteFile(factory_file_basename + ".inc", factory_header.str());
- WriteFile(factory_file_basename + ".cc", factory_impl.str());
+ WriteFile(output_directory + "/" + factory_basename + ".inc",
+ factory_header.str());
+ WriteFile(output_directory + "/" + factory_basename + ".cc",
+ factory_impl.str());
+ WriteFile(output_directory + "/" + forward_declarations_filename,
+ forward_declarations.str());
}
namespace {
@@ -4305,7 +4322,7 @@ void GeneratePrintDefinitionsForClass(std::ostream& impl, const ClassType* type,
impl << template_params << "\n";
impl << "void " << gen_name_T << "::" << type->name()
<< "Print(std::ostream& os) {\n";
- impl << " this->PrintHeader(os, \"" << gen_name << "\");\n";
+ impl << " this->PrintHeader(os, \"" << type->name() << "\");\n";
auto hierarchy = type->GetHierarchy();
std::map<std::string, const AggregateType*> field_names;
for (const AggregateType* aggregate_type : hierarchy) {
@@ -4340,14 +4357,8 @@ void ImplementationVisitor::GeneratePrintDefinitions(
{
IfDefScope object_print(impl, "OBJECT_PRINT");
- impl << "#include \"src/objects/objects.h\"\n\n";
impl << "#include <iosfwd>\n\n";
- impl << "#include "
- "\"torque-generated/internal-class-definitions-inl.h\"\n";
- impl << "#include "
- "\"torque-generated/exported-class-definitions-inl.h\"\n";
- impl << "#include \"src/objects/struct-inl.h\"\n\n";
- impl << "#include \"src/objects/template-objects-inl.h\"\n\n";
+ impl << "#include \"src/objects/all-objects-inl.h\"\n\n";
NamespaceScope impl_namespaces(impl, {"v8", "internal"});
@@ -4532,8 +4543,10 @@ void ImplementationVisitor::GenerateBodyDescriptors(
if (type->size().SingleValue()) {
h_contents << " return " << *type->size().SingleValue() << ";\n";
} else {
+ // We use an unchecked_cast here because this is used for concurrent
+ // marking, where we shouldn't re-read the map.
h_contents << " return " << name
- << "::cast(raw_object).AllocatedSize();\n";
+ << "::unchecked_cast(raw_object).AllocatedSize();\n";
}
h_contents << " }\n\n";
@@ -4548,10 +4561,9 @@ namespace {
// Generate verification code for a single piece of class data, which might be
// nested within a struct or might be a single element in an indexed field (or
// both).
-void GenerateFieldValueVerifier(const std::string& class_name,
- const Field& class_field,
- const Field& leaf_field, size_t struct_offset,
- std::string field_size,
+void GenerateFieldValueVerifier(const std::string& class_name, bool indexed,
+ std::string offset, const Field& leaf_field,
+ std::string indexed_field_size,
std::ostream& cc_contents) {
const Type* field_type = leaf_field.name_and_type.type;
@@ -4560,17 +4572,15 @@ void GenerateFieldValueVerifier(const std::string& class_name,
const char* object_type = maybe_object ? "MaybeObject" : "Object";
const char* verify_fn =
maybe_object ? "VerifyMaybeObjectPointer" : "VerifyPointer";
- std::string index_offset = std::to_string(struct_offset);
- if (class_field.index) {
- index_offset += " + i * " + field_size;
+ if (indexed) {
+ offset += " + i * " + indexed_field_size;
}
// Name the local var based on the field name for nicer CHECK output.
const std::string value = leaf_field.name_and_type.name + "__value";
// Read the field.
cc_contents << " " << object_type << " " << value << " = TaggedField<"
- << object_type << ", " << *class_field.offset << ">::load(o, "
- << index_offset << ");\n";
+ << object_type << ">::load(o, " << offset << ");\n";
// Call VerifyPointer or VerifyMaybeObjectPointer on it.
cc_contents << " " << object_type << "::" << verify_fn << "(isolate, "
@@ -4601,49 +4611,49 @@ void GenerateClassFieldVerifier(const std::string& class_name,
// Do not verify if the field may be uninitialized.
if (TypeOracle::GetUninitializedType()->IsSubtypeOf(field_type)) return;
+ std::string field_start_offset;
if (f.index) {
- base::Optional<NameAndType> array_length =
- ExtractSimpleFieldArraySize(class_type, *f.index);
- if (!array_length) {
- Error("Cannot generate verifier for array field with complex length.")
- .Position((*f.index)->pos)
- .Throw();
- }
-
- std::string length_field_offset =
- class_name + "::k" + CamelifyString(array_length->name) + "Offset";
- cc_contents << " for (int i = 0; i < ";
- if (array_length->type == TypeOracle::GetSmiType()) {
- // We already verified the index field because it was listed earlier, so
- // we can assume it's safe to read here.
- cc_contents << "TaggedField<Smi, " << length_field_offset
- << ">::load(o).value()";
- } else {
- const Type* constexpr_version = array_length->type->ConstexprVersion();
- if (constexpr_version == nullptr) {
- Error("constexpr representation for type ",
- array_length->type->ToString(),
- " is required due to usage as index")
- .Position(f.pos);
- }
- cc_contents << "o.ReadField<" << constexpr_version->GetGeneratedTypeName()
- << ">(" << length_field_offset << ")";
- }
- cc_contents << "; ++i) {\n";
+ field_start_offset = f.name_and_type.name + "__offset";
+ std::string length = f.name_and_type.name + "__length";
+ cc_contents << " intptr_t " << field_start_offset << ", " << length
+ << ";\n";
+ cc_contents << " std::tie(std::ignore, " << field_start_offset << ", "
+ << length << ") = "
+ << Callable::PrefixNameForCCOutput(
+ class_type.GetSliceMacroName(f))
+ << "(isolate, o);\n";
+
+ // Slices use intptr, but TaggedField<T>.load() uses int, so verify that
+ // such a cast is valid.
+ cc_contents << " CHECK_EQ(" << field_start_offset << ", static_cast<int>("
+ << field_start_offset << "));\n";
+ cc_contents << " CHECK_EQ(" << length << ", static_cast<int>(" << length
+ << "));\n";
+ field_start_offset = "static_cast<int>(" + field_start_offset + ")";
+ length = "static_cast<int>(" + length + ")";
+
+ cc_contents << " for (int i = 0; i < " << length << "; ++i) {\n";
} else {
+ // Non-indexed fields have known offsets.
+ field_start_offset = std::to_string(*f.offset);
cc_contents << " {\n";
}
if (auto struct_type = field_type->StructSupertype()) {
- for (const Field& field : (*struct_type)->fields()) {
- if (field_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
- GenerateFieldValueVerifier(class_name, f, field, *field.offset,
- std::to_string((*struct_type)->PackedSize()),
- cc_contents);
+ for (const Field& struct_field : (*struct_type)->fields()) {
+ if (struct_field.name_and_type.type->IsSubtypeOf(
+ TypeOracle::GetTaggedType())) {
+ GenerateFieldValueVerifier(
+ class_name, f.index.has_value(),
+ field_start_offset + " + " + std::to_string(*struct_field.offset),
+ struct_field, std::to_string((*struct_type)->PackedSize()),
+ cc_contents);
}
}
} else {
- GenerateFieldValueVerifier(class_name, f, f, 0, "kTaggedSize", cc_contents);
+ GenerateFieldValueVerifier(class_name, f.index.has_value(),
+ field_start_offset, f, "kTaggedSize",
+ cc_contents);
}
cc_contents << " }\n";
@@ -4668,9 +4678,8 @@ void ImplementationVisitor::GenerateClassVerifiers(
}
cc_contents << "#include \"torque-generated/" << file_name << ".h\"\n";
cc_contents << "#include "
- "\"torque-generated/internal-class-definitions-inl.h\"\n";
- cc_contents << "#include "
- "\"torque-generated/exported-class-definitions-inl.h\"\n";
+ "\"src/objects/all-objects-inl.h\"\n";
+ cc_contents << "#include \"torque-generated/runtime-macros.h\"\n";
IncludeObjectMacrosScope object_macros(cc_contents);
@@ -4781,10 +4790,6 @@ void ImplementationVisitor::GenerateExportedMacrosAssembler(
h_contents << "#include \"src/compiler/code-assembler.h\"\n";
h_contents << "#include \"src/execution/frames.h\"\n";
h_contents << "#include \"torque-generated/csa-types.h\"\n";
- h_contents
- << "#include \"torque-generated/internal-class-definitions.h\"\n";
- h_contents
- << "#include \"torque-generated/exported-class-definitions.h\"\n";
cc_contents << "#include \"src/objects/fixed-array-inl.h\"\n";
cc_contents << "#include \"src/objects/free-space.h\"\n";
cc_contents << "#include \"src/objects/js-regexp-string-iterator.h\"\n";