Commit a667b6b3 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[torque] Add @generatePrint annotation

The new @generatePrint annotation automatically generates ...Print
methods for objects from their Torque class definition. While this
is mostly geared towards objects derived from Struct, it works on
any Torque class.

Bug: v8:7793
Change-Id: Iaa772879d397b95c7853dafdd9f09a85dbde8e35
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1557152
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60708}
parent cdeb88e3
...@@ -1021,6 +1021,7 @@ action("run_torque") { ...@@ -1021,6 +1021,7 @@ action("run_torque") {
outputs = [ outputs = [
"$target_gen_dir/torque-generated/builtin-definitions-from-dsl.h", "$target_gen_dir/torque-generated/builtin-definitions-from-dsl.h",
"$target_gen_dir/torque-generated/class-definitions-from-dsl.h", "$target_gen_dir/torque-generated/class-definitions-from-dsl.h",
"$target_gen_dir/torque-generated/objects-printer-from-dsl.cc",
] ]
foreach(namespace, torque_namespaces) { foreach(namespace, torque_namespaces) {
outputs += [ outputs += [
...@@ -1067,6 +1068,26 @@ v8_source_set("torque_generated_initializers") { ...@@ -1067,6 +1068,26 @@ v8_source_set("torque_generated_initializers") {
configs = [ ":internal_config" ] configs = [ ":internal_config" ]
} }
v8_source_set("torque_generated_definitions") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
deps = [
":run_torque",
]
if (v8_enable_i18n_support) {
public_deps = [
"//third_party/icu",
]
}
sources = [
"$target_gen_dir/torque-generated/objects-printer-from-dsl.cc",
]
configs = [ ":internal_config" ]
}
action("generate_bytecode_builtins_list") { action("generate_bytecode_builtins_list") {
script = "tools/run.py" script = "tools/run.py"
outputs = [ outputs = [
...@@ -3096,6 +3117,7 @@ v8_source_set("v8_base") { ...@@ -3096,6 +3117,7 @@ v8_source_set("v8_base") {
defines = [] defines = []
deps = [ deps = [
":torque_generated_definitions",
":v8_headers", ":v8_headers",
":v8_libbase", ":v8_libbase",
":v8_libsampler", ":v8_libsampler",
......
...@@ -114,12 +114,16 @@ type NaN extends HeapNumber; ...@@ -114,12 +114,16 @@ type NaN extends HeapNumber;
extern class Struct extends HeapObject {} extern class Struct extends HeapObject {}
@generatePrint
extern class Tuple2 extends Struct { extern class Tuple2 extends Struct {
value_1: Object; value1: Object;
value_2: Object; value2: Object;
} }
extern class Tuple3 extends Tuple2 { value_3: Object; } @generatePrint
extern class Tuple3 extends Tuple2 {
value3: Object;
}
// A direct string can be accessed directly through CSA without going into the // A direct string can be accessed directly through CSA without going into the
// C++ runtime. See also: ToDirectStringAssembler. // C++ runtime. See also: ToDirectStringAssembler.
......
...@@ -1766,21 +1766,6 @@ void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT ...@@ -1766,21 +1766,6 @@ void PrototypeInfo::PrototypeInfoPrint(std::ostream& os) { // NOLINT
os << "\n"; os << "\n";
} }
void Tuple2::Tuple2Print(std::ostream& os) { // NOLINT
PrintHeader(os, "Tuple2");
os << "\n - value1: " << Brief(value1());
os << "\n - value2: " << Brief(value2());
os << "\n";
}
void Tuple3::Tuple3Print(std::ostream& os) { // NOLINT
PrintHeader(os, "Tuple3");
os << "\n - value1: " << Brief(value1());
os << "\n - value2: " << Brief(value2());
os << "\n - value3: " << Brief(value3());
os << "\n";
}
void ClassPositions::ClassPositionsPrint(std::ostream& os) { // NOLINT void ClassPositions::ClassPositionsPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "ClassPositions"); PrintHeader(os, "ClassPositions");
os << "\n - start position: " << start(); os << "\n - start position: " << start();
......
...@@ -922,13 +922,15 @@ struct StructDeclaration : Declaration { ...@@ -922,13 +922,15 @@ struct StructDeclaration : Declaration {
struct ClassDeclaration : Declaration { struct ClassDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration) DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration)
ClassDeclaration(SourcePosition pos, Identifier* name, bool is_extern, ClassDeclaration(SourcePosition pos, Identifier* name, bool is_extern,
bool transient, base::Optional<std::string> super, bool generate_print, bool transient,
base::Optional<std::string> super,
base::Optional<std::string> generates, base::Optional<std::string> generates,
std::vector<Declaration*> methods, std::vector<Declaration*> methods,
std::vector<ClassFieldExpression> fields) std::vector<ClassFieldExpression> fields)
: Declaration(kKind, pos), : Declaration(kKind, pos),
name(name), name(name),
is_extern(is_extern), is_extern(is_extern),
generate_print(generate_print),
transient(transient), transient(transient),
super(std::move(super)), super(std::move(super)),
generates(std::move(generates)), generates(std::move(generates)),
...@@ -936,6 +938,7 @@ struct ClassDeclaration : Declaration { ...@@ -936,6 +938,7 @@ struct ClassDeclaration : Declaration {
fields(std::move(fields)) {} fields(std::move(fields)) {}
Identifier* name; Identifier* name;
bool is_extern; bool is_extern;
bool generate_print;
bool transient; bool transient;
base::Optional<std::string> super; base::Optional<std::string> super;
base::Optional<std::string> generates; base::Optional<std::string> generates;
......
...@@ -303,7 +303,8 @@ void DeclarationVisitor::Visit(ClassDeclaration* decl) { ...@@ -303,7 +303,8 @@ void DeclarationVisitor::Visit(ClassDeclaration* decl) {
} }
new_class = Declarations::DeclareClass( new_class = Declarations::DeclareClass(
super_type, decl->name, decl->is_extern, decl->transient, generates); super_type, decl->name, decl->is_extern, decl->generate_print,
decl->transient, generates);
} else { } else {
if (decl->super) { if (decl->super) {
ReportError("Only extern classes can inherit."); ReportError("Only extern classes can inherit.");
...@@ -311,9 +312,9 @@ void DeclarationVisitor::Visit(ClassDeclaration* decl) { ...@@ -311,9 +312,9 @@ void DeclarationVisitor::Visit(ClassDeclaration* decl) {
if (decl->generates) { if (decl->generates) {
ReportError("Only extern classes can specify a generated type."); ReportError("Only extern classes can specify a generated type.");
} }
new_class = Declarations::DeclareClass(TypeOracle::GetTaggedType(), new_class = Declarations::DeclareClass(
decl->name, decl->is_extern, TypeOracle::GetTaggedType(), decl->name, decl->is_extern,
decl->transient, "FixedArray"); decl->generate_print, decl->transient, "FixedArray");
} }
GlobalContext::RegisterClass(decl->name->value, new_class); GlobalContext::RegisterClass(decl->name->value, new_class);
class_declarations_.push_back( class_declarations_.push_back(
......
...@@ -195,10 +195,10 @@ StructType* Declarations::DeclareStruct(const Identifier* name) { ...@@ -195,10 +195,10 @@ StructType* Declarations::DeclareStruct(const Identifier* name) {
ClassType* Declarations::DeclareClass(const Type* super_type, ClassType* Declarations::DeclareClass(const Type* super_type,
const Identifier* name, bool is_extern, const Identifier* name, bool is_extern,
bool transient, bool generate_print, bool transient,
const std::string& generates) { const std::string& generates) {
ClassType* new_type = TypeOracle::GetClassType( ClassType* new_type = TypeOracle::GetClassType(
super_type, name->value, is_extern, transient, generates); super_type, name->value, is_extern, generate_print, transient, generates);
DeclareType(name, new_type, false); DeclareType(name, new_type, false);
return new_type; return new_type;
} }
......
...@@ -85,8 +85,8 @@ class Declarations { ...@@ -85,8 +85,8 @@ class Declarations {
static StructType* DeclareStruct(const Identifier* name); static StructType* DeclareStruct(const Identifier* name);
static ClassType* DeclareClass(const Type* super, const Identifier* name, static ClassType* DeclareClass(const Type* super, const Identifier* name,
bool is_extern, bool transient, bool is_extern, bool generate_print,
const std::string& generates); bool transient, const std::string& generates);
static Macro* CreateMacro(std::string external_name, static Macro* CreateMacro(std::string external_name,
std::string readable_name, std::string readable_name,
......
...@@ -2871,6 +2871,48 @@ void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) { ...@@ -2871,6 +2871,48 @@ void ImplementationVisitor::GenerateClassDefinitions(std::string& file_name) {
ReplaceFileContentsIfDifferent(file_name, new_contents); ReplaceFileContentsIfDifferent(file_name, new_contents);
} }
void ImplementationVisitor::GeneratePrintDefinitions(std::string& file_name) {
std::stringstream new_contents_stream;
new_contents_stream << "#ifdef OBJECT_PRINT\n\n";
new_contents_stream << "#include \"src/objects.h\"\n\n";
new_contents_stream << "#include <iosfwd>\n\n";
new_contents_stream << "#include \"src/objects/struct-inl.h\"\n\n";
new_contents_stream << "namespace v8 {\n";
new_contents_stream << "namespace internal {\n\n";
for (auto i : GlobalContext::GetClasses()) {
ClassType* type = i.second;
if (!type->ShouldGeneratePrint()) continue;
new_contents_stream << "void " << type->name() << "::" << type->name()
<< "Print(std::ostream& os) {\n";
new_contents_stream << " PrintHeader(os, \"" << type->name() << "\");\n";
auto hierarchy = type->GetHierarchy();
std::map<std::string, const AggregateType*> field_names;
for (const AggregateType* aggregate_type : hierarchy) {
for (const Field& f : aggregate_type->fields()) {
if (f.name_and_type.name == "map") continue;
new_contents_stream << " os << \"\\n - " << f.name_and_type.name
<< ": \" << "
<< "Brief(" << f.name_and_type.name << "());\n";
}
}
new_contents_stream << " os << \"\\n\";\n";
new_contents_stream << "}\n\n";
}
new_contents_stream << "} // namespace internal\"\n";
new_contents_stream << "} // namespace v8\"\n";
new_contents_stream << "\n#endif // OBJECT_PRINT\n\n";
std::string new_contents(new_contents_stream.str());
ReplaceFileContentsIfDifferent(file_name, new_contents);
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -257,6 +257,7 @@ class ImplementationVisitor : public FileVisitor { ...@@ -257,6 +257,7 @@ class ImplementationVisitor : public FileVisitor {
public: public:
void GenerateBuiltinDefinitions(std::string& file_name); void GenerateBuiltinDefinitions(std::string& file_name);
void GenerateClassDefinitions(std::string& file_name); void GenerateClassDefinitions(std::string& file_name);
void GeneratePrintDefinitions(std::string& file_name);
VisitResult Visit(Expression* expr); VisitResult Visit(Expression* expr);
const Type* Visit(Statement* stmt); const Type* Visit(Statement* stmt);
......
...@@ -74,6 +74,10 @@ void CompileCurrentAst(TorqueCompilerOptions options) { ...@@ -74,6 +74,10 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
output_header_path = output_directory + "/class-definitions-from-dsl.h"; output_header_path = output_directory + "/class-definitions-from-dsl.h";
implementation_visitor.GenerateClassDefinitions(output_header_path); implementation_visitor.GenerateClassDefinitions(output_header_path);
std::string output_source_path =
output_directory + "/objects-printer-from-dsl.cc";
implementation_visitor.GeneratePrintDefinitions(output_source_path);
for (Namespace* n : GlobalContext::Get().GetNamespaces()) { for (Namespace* n : GlobalContext::Get().GetNamespaces()) {
implementation_visitor.EndNamespaceFile(n); implementation_visitor.EndNamespaceFile(n);
implementation_visitor.GenerateImplementation(output_directory, n); implementation_visitor.GenerateImplementation(output_directory, n);
......
...@@ -572,6 +572,7 @@ base::Optional<ParseResult> MakeMethodDeclaration( ...@@ -572,6 +572,7 @@ base::Optional<ParseResult> MakeMethodDeclaration(
base::Optional<ParseResult> MakeClassDeclaration( base::Optional<ParseResult> MakeClassDeclaration(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto generate_print = child_results->NextAs<bool>();
auto is_extern = child_results->NextAs<bool>(); auto is_extern = child_results->NextAs<bool>();
auto transient = child_results->NextAs<bool>(); auto transient = child_results->NextAs<bool>();
auto name = child_results->NextAs<Identifier*>(); auto name = child_results->NextAs<Identifier*>();
...@@ -583,8 +584,8 @@ base::Optional<ParseResult> MakeClassDeclaration( ...@@ -583,8 +584,8 @@ base::Optional<ParseResult> MakeClassDeclaration(
auto methods = child_results->NextAs<std::vector<Declaration*>>(); auto methods = child_results->NextAs<std::vector<Declaration*>>();
auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>(); auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
Declaration* result = MakeNode<ClassDeclaration>( Declaration* result = MakeNode<ClassDeclaration>(
name, is_extern, transient, std::move(extends), std::move(generates), name, is_extern, generate_print, transient, std::move(extends),
std::move(methods), fields); std::move(generates), std::move(methods), fields);
return ParseResult{result}; return ParseResult{result};
} }
...@@ -1636,8 +1637,8 @@ struct TorqueGrammar : Grammar { ...@@ -1636,8 +1637,8 @@ struct TorqueGrammar : Grammar {
Rule({Token("const"), &name, Token(":"), &type, Token("generates"), Rule({Token("const"), &name, Token(":"), &type, Token("generates"),
&externalString, Token(";")}, &externalString, Token(";")},
MakeExternConstDeclaration), MakeExternConstDeclaration),
Rule({CheckIf(Token("extern")), CheckIf(Token("transient")), Rule({CheckIf(Token("@generatePrint")), CheckIf(Token("extern")),
Token("class"), &name, CheckIf(Token("transient")), Token("class"), &name,
Optional<std::string>(Sequence({Token("extends"), &identifier})), Optional<std::string>(Sequence({Token("extends"), &identifier})),
Optional<std::string>( Optional<std::string>(
Sequence({Token("generates"), &externalString})), Sequence({Token("generates"), &externalString})),
......
...@@ -35,10 +35,11 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -35,10 +35,11 @@ class TypeOracle : public ContextualClass<TypeOracle> {
} }
static ClassType* GetClassType(const Type* parent, const std::string& name, static ClassType* GetClassType(const Type* parent, const std::string& name,
bool is_extern, bool transient, bool is_extern, bool generate_print,
const std::string& generates) { bool transient, const std::string& generates) {
ClassType* result = new ClassType(parent, CurrentNamespace(), name, ClassType* result =
is_extern, transient, generates); new ClassType(parent, CurrentNamespace(), name, is_extern,
generate_print, transient, generates);
Get().struct_types_.push_back(std::unique_ptr<ClassType>(result)); Get().struct_types_.push_back(std::unique_ptr<ClassType>(result));
return result; return result;
} }
......
...@@ -288,10 +288,12 @@ std::string StructType::ToExplicitString() const { ...@@ -288,10 +288,12 @@ std::string StructType::ToExplicitString() const {
} }
ClassType::ClassType(const Type* parent, Namespace* nspace, ClassType::ClassType(const Type* parent, Namespace* nspace,
const std::string& name, bool is_extern, bool transient, const std::string& name, bool is_extern,
bool generate_print, bool transient,
const std::string& generates) const std::string& generates)
: AggregateType(Kind::kClassType, parent, nspace, name), : AggregateType(Kind::kClassType, parent, nspace, name),
is_extern_(is_extern), is_extern_(is_extern),
generate_print_(generate_print),
transient_(transient), transient_(transient),
size_(0), size_(0),
has_indexed_field_(false), has_indexed_field_(false),
......
...@@ -471,6 +471,7 @@ class ClassType final : public AggregateType { ...@@ -471,6 +471,7 @@ class ClassType final : public AggregateType {
std::string GetGeneratedTypeNameImpl() const override; std::string GetGeneratedTypeNameImpl() const override;
std::string GetGeneratedTNodeTypeNameImpl() const override; std::string GetGeneratedTNodeTypeNameImpl() const override;
bool IsExtern() const { return is_extern_; } bool IsExtern() const { return is_extern_; }
bool ShouldGeneratePrint() const { return generate_print_; }
bool IsTransient() const override { return transient_; } bool IsTransient() const override { return transient_; }
bool HasIndexedField() const override; bool HasIndexedField() const override;
size_t size() const { return size_; } size_t size() const { return size_; }
...@@ -490,9 +491,11 @@ class ClassType final : public AggregateType { ...@@ -490,9 +491,11 @@ class ClassType final : public AggregateType {
private: private:
friend class TypeOracle; friend class TypeOracle;
ClassType(const Type* parent, Namespace* nspace, const std::string& name, ClassType(const Type* parent, Namespace* nspace, const std::string& name,
bool is_extern, bool transient, const std::string& generates); bool is_extern, bool generate_print, bool transient,
const std::string& generates);
bool is_extern_; bool is_extern_;
bool generate_print_;
bool transient_; bool transient_;
size_t size_; size_t size_;
bool has_indexed_field_; bool has_indexed_field_;
......
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