[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:
parent
f33575be45
commit
365e7d4b9e
1
BUILD.gn
1
BUILD.gn
@ -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
32
src/torque/declarable.cc
Normal 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
|
@ -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_; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 "
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
|
@ -39,7 +39,7 @@ class OperationHandler {
|
||||
public:
|
||||
std::string macro_name;
|
||||
ParameterTypes parameter_types;
|
||||
Type result_type;
|
||||
const Type* result_type;
|
||||
};
|
||||
|
||||
struct SourceFileContext {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user