[torque] refactor Type to expose the implementation pointer directly

Change-Id: I61a594e194082577135dbc82b2673bf477105ef3
Reviewed-on: https://chromium-review.googlesource.com/1046949
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Daniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53050}
This commit is contained in:
Tobias Tebbi 2018-05-08 09:14:10 +02:00 committed by Commit Bot
parent f33575be45
commit 365e7d4b9e
13 changed files with 224 additions and 231 deletions

View File

@ -3049,6 +3049,7 @@ if (current_toolchain == v8_snapshot_toolchain) {
"src/torque/ast-generator.cc",
"src/torque/ast-generator.h",
"src/torque/ast.h",
"src/torque/declarable.cc",
"src/torque/declarable.h",
"src/torque/declaration-visitor.cc",
"src/torque/declaration-visitor.h",

32
src/torque/declarable.cc Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fstream>
#include <iostream>
#include "src/torque/declarable.h"
namespace v8 {
namespace internal {
namespace torque {
bool Type::IsSubtypeOf(const Type* supertype) const {
const Type* subtype = this;
while (subtype != nullptr) {
if (subtype == supertype) return true;
subtype = subtype->parent();
}
return false;
}
std::string Type::GetGeneratedTNodeTypeName() const {
std::string result = GetGeneratedTypeName();
DCHECK_EQ(result.substr(0, 6), "TNode<");
result = result.substr(6, result.length() - 7);
return result;
}
} // namespace torque
} // namespace internal
} // namespace v8

View File

@ -23,7 +23,7 @@ class Declarable {
public:
virtual ~Declarable() {}
enum Kind {
kTypeImpl,
kType,
kVariable,
kParameter,
kMacro,
@ -35,7 +35,7 @@ class Declarable {
};
explicit Declarable(Kind kind) : kind_(kind) {}
Kind kind() const { return kind_; }
bool IsTypeImpl() const { return kind() == kTypeImpl; }
bool IsType() const { return kind() == kType; }
bool IsMacro() const { return kind() == kMacro; }
bool IsBuiltin() const { return kind() == kBuiltin; }
bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
@ -62,25 +62,40 @@ class Declarable {
} \
const char* type_name() const override { return #y; }
class TypeImpl : public Declarable {
class Type : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(TypeImpl, type_impl);
TypeImpl(TypeImpl* parent, const std::string& name,
const std::string& generated_type)
: Declarable(Declarable::kTypeImpl),
DECLARE_DECLARABLE_BOILERPLATE(Type, type);
Type(const Type* parent, const std::string& name,
const std::string& generated_type)
: Declarable(Declarable::kType),
parent_(parent),
name_(name),
generated_type_(generated_type) {}
TypeImpl* parent() const { return parent_; }
const Type* parent() const { return parent_; }
const std::string& name() const { return name_; }
const std::string& generated_type() const { return generated_type_; }
const std::string& GetGeneratedTypeName() const { return generated_type_; }
std::string GetGeneratedTNodeTypeName() const;
bool IsSubtypeOf(const Type* supertype) const;
bool IsVoid() const { return name() == VOID_TYPE_STRING; }
bool IsNever() const { return name() == NEVER_TYPE_STRING; }
bool IsBool() const { return name() == BOOL_TYPE_STRING; }
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
bool IsConstexpr() const {
return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) ==
CONSTEXPR_TYPE_PREFIX;
}
private:
TypeImpl* parent_;
std::string name_;
std::string generated_type_;
const Type* const parent_;
const std::string name_;
const std::string generated_type_;
};
inline std::ostream& operator<<(std::ostream& os, const Type* t) {
os << t->name().c_str();
return os;
}
class Value : public Declarable {
public:
const std::string& name() const { return name_; }
@ -91,14 +106,14 @@ class Value : public Declarable {
}
virtual std::string GetValueForWrite() const { UNREACHABLE(); }
DECLARE_DECLARABLE_BOILERPLATE(Value, value);
Type type() const { return type_; }
const Type* type() const { return type_; }
protected:
Value(Kind kind, Type type, const std::string& name)
Value(Kind kind, const Type* type, const std::string& name)
: Declarable(kind), type_(type), name_(name) {}
private:
Type type_;
const Type* type_;
std::string name_;
};
@ -109,7 +124,8 @@ class Parameter : public Value {
private:
friend class Declarations;
Parameter(const std::string& name, Type type, const std::string& var_name)
Parameter(const std::string& name, const Type* type,
const std::string& var_name)
: Value(Declarable::kParameter, type, name), var_name_(var_name) {}
std::string var_name_;
@ -129,7 +145,7 @@ class Variable : public Value {
private:
friend class Declarations;
Variable(const std::string& name, const std::string& value, Type type)
Variable(const std::string& name, const std::string& value, const Type* type)
: Value(Declarable::kVariable, type, name),
value_(value),
defined_(false) {}
@ -173,7 +189,7 @@ class Constant : public Value {
private:
friend class Declarations;
explicit Constant(const std::string& name, Type type,
explicit Constant(const std::string& name, const Type* type,
const std::string& value)
: Value(Declarable::kConstant, type, name), value_(value) {}
@ -198,7 +214,7 @@ class Callable : public Declarable {
return signature_.parameter_names;
}
bool HasReturnValue() const {
return !signature_.return_type.IsVoidOrNever();
return !signature_.return_type->IsVoidOrNever();
}
void IncrementReturns() { ++returns_; }
bool HasReturns() const { return returns_; }

View File

@ -64,7 +64,7 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
DeclareParameterList(decl->pos, signature, {});
if (signature.types().size() == 0 ||
!signature.types()[0].Is(CONTEXT_TYPE_STRING)) {
!(signature.types()[0]->name() == CONTEXT_TYPE_STRING)) {
std::stringstream stream;
stream << "first parameter to builtin " << decl->name
<< " is not a context but should be at "
@ -84,7 +84,7 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
}
if (javascript) {
if (signature.types().size() < 2 ||
!signature.types()[1].Is(OBJECT_TYPE_STRING)) {
!(signature.types()[1]->name() == OBJECT_TYPE_STRING)) {
std::stringstream stream;
stream << "second parameter to javascript builtin " << decl->name
<< " is not a receiver type but should be at "
@ -112,7 +112,7 @@ void DeclarationVisitor::Visit(MacroDeclaration* decl) {
DeclareParameterList(decl->pos, signature, decl->labels);
if (!signature.return_type.IsVoidOrNever()) {
if (!signature.return_type->IsVoidOrNever()) {
declarations()->DeclareVariable(decl->pos, kReturnValueVariable,
signature.return_type);
}

View File

@ -25,8 +25,6 @@ class DeclarationVisitor : public FileVisitor {
explicit DeclarationVisitor(GlobalContext& global_context)
: FileVisitor(global_context),
scope_(declarations(), global_context.ast()->default_module()) {
declarations()->DeclareType(SourcePosition(), EXCEPTION_TYPE_STRING,
"Label*", nullptr);
}
void Visit(Ast* ast) { Visit(ast->default_module()); }
@ -97,7 +95,7 @@ class DeclarationVisitor : public FileVisitor {
MakeSignature(decl->pos, decl->parameters, decl->return_type, {});
if (signature.parameter_types.types.size() == 0 ||
!signature.parameter_types.types[0].Is(CONTEXT_TYPE_STRING)) {
!(signature.parameter_types.types[0]->name() == CONTEXT_TYPE_STRING)) {
std::stringstream stream;
stream << "first parameter to builtin " << decl->name
<< " is not a context but should be at "
@ -115,7 +113,7 @@ class DeclarationVisitor : public FileVisitor {
}
if (javascript) {
if (signature.types().size() < 2 ||
!signature.types()[1].Is(OBJECT_TYPE_STRING)) {
!(signature.types()[1]->name() == OBJECT_TYPE_STRING)) {
std::stringstream stream;
stream << "second parameter to javascript builtin " << decl->name
<< " is not a receiver type but should be at "
@ -135,11 +133,12 @@ class DeclarationVisitor : public FileVisitor {
<< " with signature ";
}
Type return_type = declarations()->LookupType(decl->pos, decl->return_type);
const Type* return_type =
declarations()->LookupType(decl->pos, decl->return_type);
TypeVector parameter_types =
GetTypeVector(decl->pos, decl->parameters.types);
if (parameter_types.size() == 0 ||
!parameter_types[0].Is(CONTEXT_TYPE_STRING)) {
!(parameter_types[0]->name() == CONTEXT_TYPE_STRING)) {
std::stringstream stream;
stream << "first parameter to runtime " << decl->name
<< " is not a context but should be at "
@ -208,7 +207,7 @@ class DeclarationVisitor : public FileVisitor {
void Visit(VarDeclarationStatement* stmt) {
std::string variable_name = stmt->name;
Type type = declarations()->LookupType(stmt->pos, stmt->type);
const Type* type = declarations()->LookupType(stmt->pos, stmt->type);
declarations()->DeclareVariable(stmt->pos, variable_name, type);
if (global_context_.verbose()) {
std::cout << "declared variable " << variable_name << " with type "

View File

@ -29,15 +29,16 @@ void Declarations::CheckAlreadyDeclared(SourcePosition pos,
}
}
Type Declarations::LookupType(SourcePosition pos, const std::string& name) {
const Type* Declarations::LookupType(SourcePosition pos,
const std::string& name) {
Declarable* raw = Lookup(pos, name);
if (!raw->IsTypeImpl()) {
if (!raw->IsType()) {
std::stringstream s;
s << "declaration \"" << name << "\" is not a Type at "
<< PositionAsString(pos);
ReportError(s.str());
}
return Type(TypeImpl::cast(raw));
return Type::cast(raw);
}
Value* Declarations::LookupValue(SourcePosition pos, const std::string& name) {
@ -97,11 +98,12 @@ Builtin* Declarations::LookupBuiltin(SourcePosition pos,
return nullptr;
}
Type Declarations::DeclareType(SourcePosition pos, const std::string& name,
const std::string& generated,
const std::string* parent) {
const Type* Declarations::DeclareType(SourcePosition pos,
const std::string& name,
const std::string& generated,
const std::string* parent) {
CheckAlreadyDeclared(pos, name, "type");
TypeImpl* parent_type = nullptr;
const Type* parent_type = nullptr;
if (parent != nullptr) {
Declarable* maybe_parent_type = Lookup(*parent);
if (maybe_parent_type == nullptr) {
@ -110,18 +112,18 @@ Type Declarations::DeclareType(SourcePosition pos, const std::string& name,
<< PositionAsString(pos);
ReportError(s.str());
}
if (!maybe_parent_type->IsTypeImpl()) {
if (!maybe_parent_type->IsType()) {
std::stringstream s;
s << "parent \"" << *parent << "\" of type \"" << name << "\""
<< " is not a type "
<< " at " << PositionAsString(pos);
ReportError(s.str());
}
parent_type = TypeImpl::cast(maybe_parent_type);
parent_type = Type::cast(maybe_parent_type);
}
TypeImpl* result = new TypeImpl(parent_type, name, generated);
Type* result = new Type(parent_type, name, generated);
Declare(name, std::unique_ptr<Declarable>(result));
return Type(result);
return result;
}
Label* Declarations::DeclareLabel(SourcePosition pos, const std::string& name) {
@ -180,7 +182,8 @@ RuntimeFunction* Declarations::DeclareRuntimeFunction(
}
Variable* Declarations::DeclareVariable(SourcePosition pos,
const std::string& var, Type type) {
const std::string& var,
const Type* type) {
std::string name(var + std::to_string(GetNextUniqueDeclarationNumber()));
CheckAlreadyDeclared(pos, var, "variable");
Variable* result = new Variable(var, name, type);
@ -191,7 +194,7 @@ Variable* Declarations::DeclareVariable(SourcePosition pos,
Parameter* Declarations::DeclareParameter(SourcePosition pos,
const std::string& name,
const std::string& var_name,
Type type) {
const Type* type) {
CheckAlreadyDeclared(pos, name, "parameter");
Parameter* result = new Parameter(name, type, var_name);
Declare(name, std::unique_ptr<Declarable>(result));
@ -209,7 +212,7 @@ Label* Declarations::DeclarePrivateLabel(SourcePosition pos,
}
void Declarations::DeclareConstant(SourcePosition pos, const std::string& name,
Type type, const std::string& value) {
const Type* type, const std::string& value) {
CheckAlreadyDeclared(pos, name, "constant, parameter or arguments");
Constant* result = new Constant(name, type, value);
Declare(name, std::unique_ptr<Declarable>(result));

View File

@ -31,7 +31,7 @@ class Declarations {
return d;
}
Type LookupType(SourcePosition pos, const std::string& name);
const Type* LookupType(SourcePosition pos, const std::string& name);
Value* LookupValue(SourcePosition pos, const std::string& name);
@ -42,9 +42,9 @@ class Declarations {
Label* LookupLabel(SourcePosition pos, const std::string& name);
Type DeclareType(SourcePosition pos, const std::string& name,
const std::string& generated,
const std::string* parent = nullptr);
const Type* DeclareType(SourcePosition pos, const std::string& name,
const std::string& generated,
const std::string* parent = nullptr);
Label* DeclareLabel(SourcePosition pos, const std::string& name);
@ -59,15 +59,16 @@ class Declarations {
const Signature& signature);
Variable* DeclareVariable(SourcePosition pos, const std::string& var,
Type type);
const Type* type);
Parameter* DeclareParameter(SourcePosition pos, const std::string& name,
const std::string& mangled_name, Type type);
const std::string& mangled_name,
const Type* type);
Label* DeclarePrivateLabel(SourcePosition pos, const std::string& name);
void DeclareConstant(SourcePosition pos, const std::string& name, Type type,
const std::string& value);
void DeclareConstant(SourcePosition pos, const std::string& name,
const Type* type, const std::string& value);
std::set<const Variable*> GetLiveVariables() {
return chain_.GetLiveVariables();

View File

@ -39,7 +39,7 @@ class OperationHandler {
public:
std::string macro_name;
ParameterTypes parameter_types;
Type result_type;
const Type* result_type;
};
struct SourceFileContext {

View File

@ -23,7 +23,7 @@ VisitResult ImplementationVisitor::Visit(Expression* expr) {
return VisitResult();
}
Type ImplementationVisitor::Visit(Statement* stmt) {
const Type* ImplementationVisitor::Visit(Statement* stmt) {
switch (stmt->kind) {
#define ENUM_ITEM(name) \
case AstNode::Kind::k##name: \
@ -33,7 +33,8 @@ Type ImplementationVisitor::Visit(Statement* stmt) {
default:
UNIMPLEMENTED();
}
return Type();
UNREACHABLE();
return nullptr;
}
void ImplementationVisitor::Visit(Declaration* decl) {
@ -150,10 +151,10 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
if (macro->HasReturnValue()) {
GenerateIndent();
source_out() << "Node* return_default = &*SmiConstant(0);" << std::endl;
Type return_type = macro->signature().return_type;
const Type* return_type = macro->signature().return_type;
VisitResult init = {return_type,
std::string("UncheckedCast<") +
return_type.GetGeneratedTNodeTypeName() +
return_type->GetGeneratedTNodeTypeName() +
">(return_default)"};
result_var =
GenerateVariableDeclaration(decl, kReturnValueVariable, {}, init);
@ -161,9 +162,9 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
Label* macro_end = declarations()->DeclareLabel(decl->pos, "macro_end");
GenerateLabelDefinition(macro_end, decl);
Type result = Visit(decl->body);
if (result.IsNever()) {
if (!macro->signature().return_type.IsNever() && !macro->HasReturns()) {
const Type* result = Visit(decl->body);
if (result->IsNever()) {
if (!macro->signature().return_type->IsNever() && !macro->HasReturns()) {
std::stringstream s;
s << "macro " << decl->name
<< " that never returns must have return type never at "
@ -171,14 +172,14 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
ReportError(s.str());
}
} else {
if (macro->signature().return_type.IsNever()) {
if (macro->signature().return_type->IsNever()) {
std::stringstream s;
s << "macro " << decl->name
<< " has implicit return at end of its declartion but return type "
"never at "
<< PositionAsString(decl->pos);
ReportError(s.str());
} else if (!macro->signature().return_type.IsVoid()) {
} else if (!macro->signature().return_type->IsVoid()) {
std::stringstream s;
s << "macro " << decl->name
<< " expects to return a value but doesn't on all paths at "
@ -187,7 +188,7 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
}
}
if (macro->HasReturns()) {
if (!result.IsNever()) {
if (!result->IsNever()) {
GenerateLabelGoto(macro_end);
}
GenerateLabelBind(macro_end);
@ -251,7 +252,7 @@ void ImplementationVisitor::Visit(BuiltinDeclaration* decl) {
source_out() << "}" << std::endl << std::endl;
}
Type ImplementationVisitor::Visit(VarDeclarationStatement* stmt) {
const Type* ImplementationVisitor::Visit(VarDeclarationStatement* stmt) {
base::Optional<VisitResult> init_result;
if (stmt->initializer) {
init_result = Visit(*stmt->initializer);
@ -260,7 +261,7 @@ Type ImplementationVisitor::Visit(VarDeclarationStatement* stmt) {
return GetTypeOracle().GetVoidType();
}
Type ImplementationVisitor::Visit(TailCallStatement* stmt) {
const Type* ImplementationVisitor::Visit(TailCallStatement* stmt) {
return Visit(stmt->call, true).type();
}
@ -294,7 +295,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
}
source_out() << ";" << std::endl;
Type common_type = GetCommonType(expr->pos, left.type(), right.type());
const Type* common_type = GetCommonType(expr->pos, left.type(), right.type());
const Variable* result =
GenerateVariableDeclaration(expr, kConditionValueVariable, common_type);
@ -312,7 +313,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
GenerateLabelDefinition(done_label, expr);
VisitResult condition_result = Visit(expr->condition);
if (!condition_result.type().IsNever()) {
if (!condition_result.type()->IsNever()) {
GenerateBranch(condition_result, true_label, false_label);
}
@ -340,7 +341,7 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
declarations()->LookupLabel(expr->pos, kFalseLabelName);
GenerateLabelDefinition(false_label);
VisitResult left_result = Visit(expr->left);
if (left_result.type().IsBool()) {
if (left_result.type()->IsBool()) {
Label* true_label =
declarations()->LookupLabel(expr->pos, kTrueLabelName);
GenerateIndent();
@ -359,7 +360,7 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
Label* true_label = declarations()->LookupLabel(expr->pos, kTrueLabelName);
GenerateLabelDefinition(true_label);
VisitResult left_result = Visit(expr->left);
if (left_result.type().IsBool()) {
if (left_result.type()->IsBool()) {
Label* false_label =
declarations()->LookupLabel(expr->pos, kFalseLabelName);
GenerateIndent();
@ -412,7 +413,7 @@ VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* expr) {
// TODO(tebbi): Do not silently loose precision; support 64bit literals.
double d = std::stod(expr->number.c_str());
int32_t i = static_cast<int32_t>(d);
Type result_type =
const Type* result_type =
declarations()->LookupType(expr->pos, CONST_FLOAT64_TYPE_STRING);
if (i == d) {
if (Internals::IsValidSmi(i)) {
@ -453,7 +454,7 @@ VisitResult ImplementationVisitor::Visit(ConvertExpression* expr) {
declarations()->LookupType(expr->pos, expr->type));
}
Type ImplementationVisitor::Visit(GotoStatement* stmt) {
const Type* ImplementationVisitor::Visit(GotoStatement* stmt) {
Label* label = declarations()->LookupLabel(stmt->pos, stmt->label);
if (stmt->arguments.size() != label->GetParameterCount()) {
@ -477,7 +478,7 @@ Type ImplementationVisitor::Visit(GotoStatement* stmt) {
return GetTypeOracle().GetNeverType();
}
Type ImplementationVisitor::Visit(IfStatement* stmt) {
const Type* ImplementationVisitor::Visit(IfStatement* stmt) {
ScopedIndent indent(this);
bool has_else = stmt->if_false.has_value();
@ -485,7 +486,7 @@ Type ImplementationVisitor::Visit(IfStatement* stmt) {
if (stmt->is_constexpr) {
VisitResult expression_result = Visit(stmt->condition);
if (!expression_result.type().Is(GetTypeOracle().GetConstexprBoolType())) {
if (!(expression_result.type() == GetTypeOracle().GetConstexprBoolType())) {
std::stringstream stream;
stream
<< "expression should return type \"constexpr bool\" but doesn't at"
@ -546,7 +547,7 @@ Type ImplementationVisitor::Visit(IfStatement* stmt) {
}
}
Type ImplementationVisitor::Visit(WhileStatement* stmt) {
const Type* ImplementationVisitor::Visit(WhileStatement* stmt) {
ScopedIndent indent(this);
Label* body_label = nullptr;
@ -575,12 +576,12 @@ Type ImplementationVisitor::Visit(WhileStatement* stmt) {
return GetTypeOracle().GetVoidType();
}
Type ImplementationVisitor::Visit(BlockStatement* block) {
const Type* ImplementationVisitor::Visit(BlockStatement* block) {
Declarations::NodeScopeActivator scope(declarations(), block);
ScopedIndent indent(this);
Type type = GetTypeOracle().GetVoidType();
const Type* type = GetTypeOracle().GetVoidType();
for (Statement* s : block->statements) {
if (type.IsNever()) {
if (type->IsNever()) {
std::stringstream stream;
stream << "statement after non-returning statement at "
<< PositionAsString(s->pos);
@ -591,7 +592,7 @@ Type ImplementationVisitor::Visit(BlockStatement* block) {
return type;
}
Type ImplementationVisitor::Visit(DebugStatement* stmt) {
const Type* ImplementationVisitor::Visit(DebugStatement* stmt) {
#if defined(DEBUG)
GenerateIndent();
source_out() << "Print(\""
@ -608,7 +609,7 @@ Type ImplementationVisitor::Visit(DebugStatement* stmt) {
}
}
Type ImplementationVisitor::Visit(AssertStatement* stmt) {
const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
#if defined(DEBUG)
// CSA_ASSERT & co. are not used here on purpose for two reasons. First,
// Torque allows and handles two types of expressions in the if protocol
@ -653,14 +654,14 @@ Type ImplementationVisitor::Visit(AssertStatement* stmt) {
return GetTypeOracle().GetVoidType();
}
Type ImplementationVisitor::Visit(ExpressionStatement* stmt) {
Type type = Visit(stmt->expression).type();
return type.IsNever() ? type : GetTypeOracle().GetVoidType();
const Type* ImplementationVisitor::Visit(ExpressionStatement* stmt) {
const Type* type = Visit(stmt->expression).type();
return type->IsNever() ? type : GetTypeOracle().GetVoidType();
}
Type ImplementationVisitor::Visit(ReturnStatement* stmt) {
const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
Callable* current_callable = global_context_.GetCurrentCallable();
if (current_callable->signature().return_type.IsNever()) {
if (current_callable->signature().return_type->IsNever()) {
std::stringstream s;
s << "cannot return from a function with return type never at "
<< PositionAsString(stmt->pos);
@ -713,7 +714,7 @@ Type ImplementationVisitor::Visit(ReturnStatement* stmt) {
return GetTypeOracle().GetNeverType();
}
Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
const Type* ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
Declarations::NodeScopeActivator scope(declarations(), stmt);
VisitResult expression_result = Visit(stmt->iterable);
@ -733,7 +734,7 @@ Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
Label* exit_label = declarations()->DeclarePrivateLabel(stmt->pos, "exit");
GenerateLabelDefinition(exit_label);
Type common_type = GetCommonType(stmt->pos, begin.type(), end.type());
const Type* common_type = GetCommonType(stmt->pos, begin.type(), end.type());
Variable* index_var = GenerateVariableDeclaration(
stmt, std::string(kForIndexValueVariable) + "_" + NewTempVariable(),
common_type, begin);
@ -779,11 +780,11 @@ Type ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
return GetTypeOracle().GetVoidType();
}
Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
const Type* ImplementationVisitor::Visit(TryCatchStatement* stmt) {
ScopedIndent indent(this);
Label* try_done = declarations()->DeclarePrivateLabel(stmt->pos, "try_done");
GenerateLabelDefinition(try_done);
Type try_result = GetTypeOracle().GetNeverType();
const Type* try_result = GetTypeOracle().GetNeverType();
std::vector<Label*> labels;
// Output labels for the goto handlers and for the merge after the try.
@ -843,13 +844,13 @@ Type ImplementationVisitor::Visit(TryCatchStatement* stmt) {
try_result = GetTypeOracle().GetVoidType();
}
if (!try_result.IsNever()) {
if (!try_result->IsNever()) {
GenerateLabelBind(try_done);
}
return try_result;
}
Type ImplementationVisitor::Visit(BreakStatement* stmt) {
const Type* ImplementationVisitor::Visit(BreakStatement* stmt) {
Label* break_label = global_context_.GetCurrentBreak();
if (break_label == nullptr) {
ReportError("break used outside of loop at " + PositionAsString(stmt->pos));
@ -858,7 +859,7 @@ Type ImplementationVisitor::Visit(BreakStatement* stmt) {
return GetTypeOracle().GetNeverType();
}
Type ImplementationVisitor::Visit(ContinueStatement* stmt) {
const Type* ImplementationVisitor::Visit(ContinueStatement* stmt) {
Label* continue_label = global_context_.GetCurrentContinue();
if (continue_label == nullptr) {
ReportError("continue used outside of loop at " +
@ -868,7 +869,7 @@ Type ImplementationVisitor::Visit(ContinueStatement* stmt) {
return GetTypeOracle().GetNeverType();
}
Type ImplementationVisitor::Visit(ForLoopStatement* stmt) {
const Type* ImplementationVisitor::Visit(ForLoopStatement* stmt) {
Declarations::NodeScopeActivator scope(declarations(), stmt);
if (stmt->var_declaration) Visit(*stmt->var_declaration);
@ -955,7 +956,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
// Quite a hack here. Make sure that TNode is namespace qualified if the
// macro name is also qualified.
std::string return_type_name(
macro->signature().return_type.GetGeneratedTypeName());
macro->signature().return_type->GetGeneratedTypeName());
if (macro_prefix != "" && (return_type_name.length() > 5) &&
(return_type_name.substr(0, 5) == "TNode")) {
o << "compiler::";
@ -971,9 +972,9 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
o << ", ";
}
const Value* parameter = declarations()->LookupValue(pos, name);
Type parameter_type = *type_iterator;
const Type* parameter_type = *type_iterator;
const std::string& generated_type_name =
parameter_type.GetGeneratedTypeName();
parameter_type->GetGeneratedTypeName();
o << generated_type_name << " " << parameter->GetValueForDeclaration();
type_iterator++;
first = false;
@ -987,7 +988,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
o << "Label* " << label->generated();
for (Variable* var : label->GetParameters()) {
std::string generated_type_name("TVariable<");
generated_type_name += var->type().GetGeneratedTNodeTypeName();
generated_type_name += var->type()->GetGeneratedTNodeTypeName();
generated_type_name += ">*";
o << ", ";
o << generated_type_name << " " << var->GetValueForDeclaration();
@ -999,7 +1000,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
VisitResult ImplementationVisitor::GenerateOperation(
SourcePosition pos, const std::string& operation, Arguments arguments,
base::Optional<Type> return_type) {
base::Optional<const Type*> return_type) {
TypeVector parameter_types(arguments.parameters.GetTypeVector());
auto i = global_context_.op_handlers_.find(operation);
@ -1009,7 +1010,7 @@ VisitResult ImplementationVisitor::GenerateOperation(
parameter_types)) {
// Operators used in a bit context can also be function calls that never
// return but have a True and False label
if (!return_type && handler.result_type.IsNever()) {
if (!return_type && handler.result_type->IsNever()) {
if (arguments.labels.size() == 0) {
Label* true_label =
declarations()->LookupLabel(pos, kTrueLabelName);
@ -1050,9 +1051,10 @@ void ImplementationVisitor::GenerateChangedVarsFromControlSplit(AstNode* node) {
source_out() << "}";
}
Type ImplementationVisitor::GetCommonType(SourcePosition pos, Type left,
Type right) {
Type common_type = GetTypeOracle().GetVoidType();
const Type* ImplementationVisitor::GetCommonType(SourcePosition pos,
const Type* left,
const Type* right) {
const Type* common_type = GetTypeOracle().GetVoidType();
if (GetTypeOracle().IsAssignableFrom(left, right)) {
common_type = left;
} else if (GetTypeOracle().IsAssignableFrom(right, left)) {
@ -1144,7 +1146,8 @@ void ImplementationVisitor::GenerateAssignToLocation(
}
Variable* ImplementationVisitor::GenerateVariableDeclaration(
AstNode* node, const std::string& name, const base::Optional<Type>& type,
AstNode* node, const std::string& name,
const base::Optional<const Type*>& type,
const base::Optional<VisitResult>& initialization) {
SourcePosition pos = node->pos;
@ -1162,7 +1165,7 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
GenerateIndent();
source_out() << "TVARIABLE(";
source_out() << variable->type().GetGeneratedTNodeTypeName();
source_out() << variable->type()->GetGeneratedTNodeTypeName();
source_out() << ", " << variable->GetValueForDeclaration() << "_impl);"
<< std::endl;
GenerateIndent();
@ -1182,9 +1185,9 @@ void ImplementationVisitor::GenerateParameter(
const Value* val = declarations()->LookupValue(pos, parameter_name);
std::string var = val->GetValueForDeclaration();
GenerateIndent();
source_out() << val->type().GetGeneratedTypeName() << " " << var << " = ";
source_out() << val->type()->GetGeneratedTypeName() << " " << var << " = ";
source_out() << "UncheckedCast<" << val->type().GetGeneratedTNodeTypeName()
source_out() << "UncheckedCast<" << val->type()->GetGeneratedTNodeTypeName()
<< ">(Parameter(Descriptor::k" << CamelifyString(parameter_name)
<< "));" << std::endl;
GenerateIndent();
@ -1208,25 +1211,25 @@ VisitResult ImplementationVisitor::GenerateCall(
const Arguments& arguments, bool is_tailcall) {
TypeVector parameter_types(arguments.parameters.GetTypeVector());
Callable* callable = LookupCall(pos, callable_name, parameter_types);
Type result_type = callable->signature().return_type;
const Type* result_type = callable->signature().return_type;
std::vector<std::string> variables;
for (size_t current = 0; current < arguments.parameters.size(); ++current) {
Type to_type = (current >= callable->signature().types().size())
? GetTypeOracle().GetObjectType()
: callable->signature().types()[current];
const Type* to_type = (current >= callable->signature().types().size())
? GetTypeOracle().GetObjectType()
: callable->signature().types()[current];
VisitResult result =
GenerateImplicitConvert(pos, to_type, arguments.parameters[current]);
variables.push_back(result.variable());
}
std::string result_variable_name;
if (result_type.IsVoidOrNever() || is_tailcall) {
if (result_type->IsVoidOrNever() || is_tailcall) {
GenerateIndent();
} else {
result_variable_name = GenerateNewTempVariable(result_type);
source_out() << "UncheckedCast<";
source_out() << result_type.GetGeneratedTNodeTypeName();
source_out() << result_type->GetGeneratedTNodeTypeName();
source_out() << ">(";
}
if (callable->IsBuiltin()) {
@ -1294,7 +1297,7 @@ VisitResult ImplementationVisitor::GenerateCall(
for (auto t : callable->signature().labels[i].types) {
source_out() << ", ";
Variable* variable = label->GetParameter(j);
if (!variable->type().Is(t)) {
if (!(variable->type() == t)) {
std::stringstream s;
s << "mismatch of label parameters (expected " << t << " got "
<< label->GetParameter(j)->type() << " for parameter "
@ -1310,7 +1313,7 @@ VisitResult ImplementationVisitor::GenerateCall(
std::cout << "finished generating code for call to " << callable_name
<< " at " << PositionAsString(pos) << "" << std::endl;
}
if (!result_type.IsVoidOrNever() && !is_tailcall) {
if (!result_type->IsVoidOrNever() && !is_tailcall) {
source_out() << ")";
}
source_out() << ");" << std::endl;
@ -1333,7 +1336,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
}
VisitResult result =
GenerateCall(expr->pos, expr->callee, arguments, is_tailcall);
if (!result.type().IsVoidOrNever()) {
if (!result.type()->IsVoidOrNever()) {
GenerateIndent();
source_out() << "USE(" << result.variable() << ");" << std::endl;
}
@ -1350,7 +1353,7 @@ bool ImplementationVisitor::GenerateLabeledStatementBlocks(
auto label_iterator = statement_labels.begin();
for (Statement* block : blocks) {
GenerateLabelBind(*label_iterator++);
if (!Visit(block).IsNever()) {
if (!Visit(block)->IsNever()) {
GenerateLabelGoto(merge_label);
live = true;
}
@ -1390,7 +1393,7 @@ bool ImplementationVisitor::GenerateExpressionBranch(
}
VisitResult ImplementationVisitor::GenerateImplicitConvert(
SourcePosition pos, Type destination_type, VisitResult source) {
SourcePosition pos, const Type* destination_type, VisitResult source) {
if (destination_type == source.type()) {
return source;
}
@ -1419,10 +1422,10 @@ std::string ImplementationVisitor::NewTempVariable() {
return name;
}
std::string ImplementationVisitor::GenerateNewTempVariable(Type type) {
std::string ImplementationVisitor::GenerateNewTempVariable(const Type* type) {
std::string temp = NewTempVariable();
GenerateIndent();
source_out() << type.GetGeneratedTypeName() << " " << temp << " = ";
source_out() << type->GetGeneratedTypeName() << " " << temp << " = ";
return temp;
}

View File

@ -34,7 +34,7 @@ class ImplementationVisitor : public FileVisitor {
void Visit(Ast* ast) { Visit(ast->default_module()); }
VisitResult Visit(Expression* expr);
Type Visit(Statement* stmt);
const Type* Visit(Statement* stmt);
void Visit(Declaration* decl);
LocationReference GetLocationReference(LocationExpression* location);
@ -105,7 +105,7 @@ class ImplementationVisitor : public FileVisitor {
void Visit(ExternalRuntimeDeclaration* decl) {}
VisitResult Visit(CallExpression* expr, bool is_tail = false);
Type Visit(TailCallStatement* stmt);
const Type* Visit(TailCallStatement* stmt);
VisitResult Visit(ConditionalExpression* expr);
@ -120,20 +120,20 @@ class ImplementationVisitor : public FileVisitor {
VisitResult Visit(StringLiteralExpression* expr);
VisitResult Visit(NumberLiteralExpression* expr);
Type Visit(TryCatchStatement* stmt);
Type Visit(ReturnStatement* stmt);
Type Visit(GotoStatement* stmt);
Type Visit(IfStatement* stmt);
Type Visit(WhileStatement* stmt);
Type Visit(BreakStatement* stmt);
Type Visit(ContinueStatement* stmt);
Type Visit(ForLoopStatement* stmt);
Type Visit(VarDeclarationStatement* stmt);
Type Visit(ForOfLoopStatement* stmt);
Type Visit(BlockStatement* block);
Type Visit(ExpressionStatement* stmt);
Type Visit(DebugStatement* stmt);
Type Visit(AssertStatement* stmt);
const Type* Visit(TryCatchStatement* stmt);
const Type* Visit(ReturnStatement* stmt);
const Type* Visit(GotoStatement* stmt);
const Type* Visit(IfStatement* stmt);
const Type* Visit(WhileStatement* stmt);
const Type* Visit(BreakStatement* stmt);
const Type* Visit(ContinueStatement* stmt);
const Type* Visit(ForLoopStatement* stmt);
const Type* Visit(VarDeclarationStatement* stmt);
const Type* Visit(ForOfLoopStatement* stmt);
const Type* Visit(BlockStatement* block);
const Type* Visit(ExpressionStatement* stmt);
const Type* Visit(DebugStatement* stmt);
const Type* Visit(AssertStatement* stmt);
void GenerateImplementation(const std::string& dir, Module* module);
@ -167,7 +167,8 @@ class ImplementationVisitor : public FileVisitor {
void GenerateChangedVarsFromControlSplit(AstNode* node);
Type GetCommonType(SourcePosition pos, Type left, Type right);
const Type* GetCommonType(SourcePosition pos, const Type* left,
const Type* right);
VisitResult GenerateCopy(const VisitResult& to_copy);
@ -179,7 +180,8 @@ class ImplementationVisitor : public FileVisitor {
VisitResult assignment_value);
Variable* GenerateVariableDeclaration(
AstNode* node, const std::string& name, const base::Optional<Type>& type,
AstNode* node, const std::string& name,
const base::Optional<const Type*>& type,
const base::Optional<VisitResult>& initialization = {});
void GenerateParameter(SourcePosition pos, const std::string& parameter_name);
@ -209,14 +211,15 @@ class ImplementationVisitor : public FileVisitor {
VisitResult GenerateOperation(SourcePosition pos,
const std::string& operation,
Arguments arguments,
base::Optional<Type> return_type = {});
base::Optional<const Type*> return_type = {});
VisitResult GenerateImplicitConvert(SourcePosition pos, Type destination_type,
VisitResult GenerateImplicitConvert(SourcePosition pos,
const Type* destination_type,
VisitResult source);
std::string NewTempVariable();
std::string GenerateNewTempVariable(Type type);
std::string GenerateNewTempVariable(const Type* type);
void GenerateLabelDefinition(Label* label, AstNode* node = nullptr);

View File

@ -19,37 +19,41 @@ class TypeOracle {
explicit TypeOracle(Declarations* declarations)
: declarations_(declarations) {}
void RegisterImplicitConversion(Type to, Type from) {
void RegisterImplicitConversion(const Type* to, const Type* from) {
implicit_conversions_.push_back(std::make_pair(to, from));
}
Type GetArgumentsType() { return GetBuiltinType(ARGUMENTS_TYPE_STRING); }
const Type* GetArgumentsType() {
return GetBuiltinType(ARGUMENTS_TYPE_STRING);
}
Type GetBoolType() { return GetBuiltinType(BOOL_TYPE_STRING); }
const Type* GetBoolType() { return GetBuiltinType(BOOL_TYPE_STRING); }
Type GetConstexprBoolType() {
const Type* GetConstexprBoolType() {
return GetBuiltinType(CONSTEXPR_BOOL_TYPE_STRING);
}
Type GetVoidType() { return GetBuiltinType(VOID_TYPE_STRING); }
const Type* GetVoidType() { return GetBuiltinType(VOID_TYPE_STRING); }
Type GetObjectType() { return GetBuiltinType(OBJECT_TYPE_STRING); }
const Type* GetObjectType() { return GetBuiltinType(OBJECT_TYPE_STRING); }
Type GetStringType() { return GetBuiltinType(STRING_TYPE_STRING); }
const Type* GetStringType() { return GetBuiltinType(STRING_TYPE_STRING); }
Type GetIntPtrType() { return GetBuiltinType(INTPTR_TYPE_STRING); }
const Type* GetIntPtrType() { return GetBuiltinType(INTPTR_TYPE_STRING); }
Type GetNeverType() { return GetBuiltinType(NEVER_TYPE_STRING); }
const Type* GetNeverType() { return GetBuiltinType(NEVER_TYPE_STRING); }
Type GetConstInt31Type() { return GetBuiltinType(CONST_INT31_TYPE_STRING); }
const Type* GetConstInt31Type() {
return GetBuiltinType(CONST_INT31_TYPE_STRING);
}
bool IsAssignableFrom(Type to, Type from) {
bool IsAssignableFrom(const Type* to, const Type* from) {
if (to == from) return true;
if (to.IsSubclass(from) && !from.IsConstexpr()) return true;
if (from->IsSubtypeOf(to) && !from->IsConstexpr()) return true;
return IsImplicitlyConverableFrom(to, from);
}
bool IsImplicitlyConverableFrom(Type to, Type from) {
bool IsImplicitlyConverableFrom(const Type* to, const Type* from) {
for (auto& conversion : implicit_conversions_) {
if (conversion.first == to && conversion.second == from) {
return true;
@ -72,14 +76,14 @@ class TypeOracle {
}
private:
Type GetBuiltinType(const std::string& name) {
const Type* GetBuiltinType(const std::string& name) {
Declarable* declarable = declarations_->Lookup(name);
DCHECK(declarable != nullptr);
return Type(TypeImpl::cast(declarable));
return Type::cast(declarable);
}
Declarations* declarations_;
std::vector<std::pair<Type, Type>> implicit_conversions_;
std::vector<std::pair<const Type*, const Type*>> implicit_conversions_;
};
} // namespace torque

View File

@ -12,31 +12,6 @@ namespace v8 {
namespace internal {
namespace torque {
bool Type::Is(const std::string& name) const { return name == impl_->name(); }
const std::string& Type::name() const { return impl_->name(); }
bool Type::IsSubclass(Type from) {
TypeImpl* to_class = type_impl();
TypeImpl* from_class = from.type_impl();
while (from_class != nullptr) {
if (to_class == from_class) return true;
from_class = from_class->parent();
}
return false;
}
const std::string& Type::GetGeneratedTypeName() const {
return type_impl()->generated_type();
}
std::string Type::GetGeneratedTNodeTypeName() const {
std::string result = type_impl()->generated_type();
DCHECK_EQ(result.substr(0, 6), "TNode<");
result = result.substr(6, result.length() - 7);
return result;
}
std::ostream& operator<<(std::ostream& os, const Signature& sig) {
os << "(";
for (size_t i = 0; i < sig.parameter_names.size(); ++i) {
@ -49,7 +24,7 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) {
os << "...";
}
os << ")";
if (!sig.return_type.IsVoid()) {
if (!sig.return_type->IsVoid()) {
os << ": " << sig.return_type;
}
return os;

View File

@ -16,14 +16,11 @@ namespace torque {
static const char* const CONSTEXPR_TYPE_PREFIX = "constexpr ";
static const char* const NEVER_TYPE_STRING = "never";
static const char* const BRANCH_TYPE_STRING = "branch";
static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool";
static const char* const BOOL_TYPE_STRING = "bool";
static const char* const VOID_TYPE_STRING = "void";
static const char* const ARGUMENTS_TYPE_STRING = "Arguments";
static const char* const TAGGED_TYPE_STRING = "tagged";
static const char* const CONTEXT_TYPE_STRING = "Context";
static const char* const EXCEPTION_TYPE_STRING = "Exception";
static const char* const OBJECT_TYPE_STRING = "Object";
static const char* const STRING_TYPE_STRING = "String";
static const char* const INTPTR_TYPE_STRING = "intptr";
@ -32,61 +29,20 @@ static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
class Label;
class Type;
class TypeImpl;
typedef struct Type {
public:
Type() : impl_(nullptr) {}
Type(TypeImpl* type_impl) : impl_(type_impl) {}
bool operator==(const Type& other) const { return impl_ == other.impl_; }
bool operator!=(const Type& other) const { return impl_ != other.impl_; }
bool Is(const Type& other) const { return impl_ == other.impl_; }
bool Is(const std::string& name) const;
bool IsSubclass(Type from);
bool IsException() const { return name() == EXCEPTION_TYPE_STRING; }
bool IsVoid() const { return name() == VOID_TYPE_STRING; }
bool IsNever() const { return name() == NEVER_TYPE_STRING; }
bool IsBool() const { return name() == BOOL_TYPE_STRING; }
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
bool IsConstexpr() const {
return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) ==
CONSTEXPR_TYPE_PREFIX;
}
const std::string& name() const;
const std::string& GetGeneratedTypeName() const;
std::string GetGeneratedTNodeTypeName() const;
protected:
TypeImpl* type_impl() const { return impl_; }
private:
TypeImpl* impl_;
} Type;
inline std::ostream& operator<<(std::ostream& os, Type t) {
os << t.name().c_str();
return os;
}
using TypeVector = std::vector<Type>;
using TypeVector = std::vector<const Type*>;
class VisitResult {
public:
VisitResult() {}
VisitResult(Type type, const std::string& variable)
VisitResult(const Type* type, const std::string& variable)
: type_(type), variable_(variable) {}
Type type() const { return type_; }
const Type* type() const { return type_; }
const std::string& variable() const { return variable_; }
private:
Type type_;
const Type* type_;
std::string variable_;
};
@ -108,7 +64,7 @@ std::ostream& operator<<(std::ostream& os, const TypeVector& types);
struct NameAndType {
std::string name;
Type type;
const Type* type;
};
typedef std::vector<NameAndType> NameAndTypeVector;
@ -138,7 +94,7 @@ struct Signature {
const TypeVector& types() const { return parameter_types.types; }
NameVector parameter_names;
ParameterTypes parameter_types;
Type return_type;
const Type* return_type;
LabelDeclarationVector labels;
};