Commit 90415437 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

Refactor/cleanup various Torque classes, inclduing making Type a Declarable

This is a preparatory step for implementing generics. Along the way, clean up
and encapsulate a bunch of code, including:

* Fully encapsulate Scope by adding the new class ScopeChain that provide an
  abstraction for creating and activating scopes.
* Untangle Modules and Scopes.
* Unify scope activation so that it is always associated with an AST node
  and triggered by a RAII helper class.
* Unify (somewhat) how builtins and macros are created, fixing a few
  inconsistencies with when and how parameters and their types are declared.
* Create a new Declarations class that brokers between the visitor classes and
  the ScopeChain. This moves handling of declaration-related errors out of the
  visitors but also makes it possible to do so without polluting Scope and
  ScopeChain with details about resolving SourcePositions in error cases.

Change-Id: I180017d4cf39ccf5ef1d20b84f53284c252f8d87
Reviewed-on: https://chromium-review.googlesource.com/1038504
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52947}
parent c32f6614
...@@ -3036,6 +3036,8 @@ if (current_toolchain == v8_snapshot_toolchain) { ...@@ -3036,6 +3036,8 @@ if (current_toolchain == v8_snapshot_toolchain) {
"src/torque/declarable.h", "src/torque/declarable.h",
"src/torque/declaration-visitor.cc", "src/torque/declaration-visitor.cc",
"src/torque/declaration-visitor.h", "src/torque/declaration-visitor.h",
"src/torque/declarations.cc",
"src/torque/declarations.h",
"src/torque/file-visitor.cc", "src/torque/file-visitor.cc",
"src/torque/file-visitor.h", "src/torque/file-visitor.h",
"src/torque/global-context.h", "src/torque/global-context.h",
......
...@@ -134,8 +134,8 @@ extern operator '>' macro Int32GreaterThan(int32, int32): bit; ...@@ -134,8 +134,8 @@ extern operator '>' macro Int32GreaterThan(int32, int32): bit;
extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bit; extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bit;
extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bit; extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bit;
extern operator '==' macro WordEqual(Smi, Smi): bit; extern operator '==' macro SmiEqual(Smi, Smi): bit;
extern operator '!=' macro WordNotEqual(Smi, Smi): bit; extern operator '!=' macro SmiNotEqual(Smi, Smi): bit;
extern operator '<' macro SmiLessThan(Smi, Smi): bit; extern operator '<' macro SmiLessThan(Smi, Smi): bit;
extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bit; extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bit;
extern operator '>' macro SmiGreaterThan(Smi, Smi): bit; extern operator '>' macro SmiGreaterThan(Smi, Smi): bit;
...@@ -189,7 +189,7 @@ extern operator '.length' macro LoadStringLengthAsWord(String): intptr; ...@@ -189,7 +189,7 @@ extern operator '.length' macro LoadStringLengthAsWord(String): intptr;
extern operator '.length' macro GetArgumentsLength(Arguments): intptr; extern operator '.length' macro GetArgumentsLength(Arguments): intptr;
extern operator '[]' macro GetArgumentValue(Arguments, intptr): Object; extern operator '[]' macro GetArgumentValue(Arguments, intptr): Object;
extern operator '[]' macro GetArgumentValue(Arguments, Smi): Object; extern operator '[]' macro GetArgumentValueSmiIndex(Arguments, Smi): Object;
extern operator 'is<Smi>' macro TaggedIsSmi(Object): bit; extern operator 'is<Smi>' macro TaggedIsSmi(Object): bit;
extern operator 'isnt<Smi>' macro TaggedIsNotSmi(Object): bit; extern operator 'isnt<Smi>' macro TaggedIsNotSmi(Object): bit;
...@@ -209,12 +209,9 @@ extern operator 'cast<>' macro ConvertFixedArrayBaseToFixedDoubleArray( ...@@ -209,12 +209,9 @@ extern operator 'cast<>' macro ConvertFixedArrayBaseToFixedDoubleArray(
extern implicit operator extern implicit operator
'convert<>' macro AllocateHeapNumberWithValue(const_float64): Number; 'convert<>' macro AllocateHeapNumberWithValue(const_float64): Number;
extern implicit operator 'convert<>' macro IntPtrConstant(const_int31): intptr; extern implicit operator 'convert<>' macro IntPtrConstant(const_int31): intptr;
extern implicit operator 'convert<>' macro IntPtrConstant(const_int32): intptr;
extern implicit operator 'convert<>' macro Int32Constant(const_int31): int32; extern implicit operator 'convert<>' macro Int32Constant(const_int31): int32;
extern implicit operator 'convert<>' macro Int32Constant(const_int32): int32;
extern implicit operator 'convert<>' macro SmiConstant(const_int31): Smi; extern implicit operator 'convert<>' macro SmiConstant(const_int31): Smi;
extern implicit operator 'convert<>' macro NumberConstant(const_int31): Number; extern implicit operator 'convert<>' macro NumberConstant(const_int31): Number;
extern implicit operator 'convert<>' macro NumberConstant(const_int32): Number;
extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number; extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number;
extern operator 'convert<>' macro TruncateWordToWord32(intptr): int32; extern operator 'convert<>' macro TruncateWordToWord32(intptr): int32;
......
...@@ -11579,8 +11579,8 @@ TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args, ...@@ -11579,8 +11579,8 @@ TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
return args->GetOptionalArgumentValue(index); return args->GetOptionalArgumentValue(index);
} }
TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args, TNode<Object> CodeStubAssembler::GetArgumentValueSmiIndex(
TNode<Smi> index) { CodeStubArguments* args, TNode<Smi> index) {
return args->GetOptionalArgumentValue(SmiUntag(index)); return args->GetOptionalArgumentValue(SmiUntag(index));
} }
......
...@@ -2239,7 +2239,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -2239,7 +2239,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args); TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args);
TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<IntPtrT> index); TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<IntPtrT> index);
TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<Smi> index); TNode<Object> GetArgumentValueSmiIndex(CodeStubArguments* args,
TNode<Smi> index);
// Support for printf-style debugging // Support for printf-style debugging
void Print(const char* s); void Print(const char* s);
......
...@@ -14,6 +14,7 @@ namespace torque { ...@@ -14,6 +14,7 @@ namespace torque {
namespace { namespace {
std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) { std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
if (!context) return "";
if (!context->type()) return "void"; if (!context->type()) return "void";
return context->type()->IDENTIFIER()->getSymbol()->getText(); return context->type()->IDENTIFIER()->getSymbol()->getText();
} }
...@@ -21,15 +22,18 @@ std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) { ...@@ -21,15 +22,18 @@ std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
LabelAndTypesVector GetOptionalLabelAndTypeList( LabelAndTypesVector GetOptionalLabelAndTypeList(
TorqueParser::OptionalLabelListContext* context) { TorqueParser::OptionalLabelListContext* context) {
LabelAndTypesVector labels; LabelAndTypesVector labels;
if (context) {
for (auto label : context->labelParameter()) { for (auto label : context->labelParameter()) {
LabelAndTypes new_label; LabelAndTypes new_label;
new_label.name = label->IDENTIFIER()->getSymbol()->getText(); new_label.name = label->IDENTIFIER()->getSymbol()->getText();
if (label->typeList() != nullptr) { if (label->typeList() != nullptr) {
for (auto& type : label->typeList()->type()) { for (auto& type : label->typeList()->type()) {
new_label.types.push_back(type->IDENTIFIER()->getSymbol()->getText()); new_label.types.emplace_back(
type->IDENTIFIER()->getSymbol()->getText());
} }
} }
labels.push_back(new_label); labels.emplace_back(new_label);
}
} }
return labels; return labels;
} }
...@@ -67,6 +71,21 @@ std::string StringLiteralUnquote(const std::string& s) { ...@@ -67,6 +71,21 @@ std::string StringLiteralUnquote(const std::string& s) {
} // namespace } // namespace
ParameterList AstGenerator::GetOptionalParameterList(
TorqueParser::ParameterListContext* context) {
if (context != nullptr) {
return context->accept(this).as<ParameterList>();
} else {
return ParameterList();
}
}
Statement* AstGenerator::GetOptionalHelperBody(
TorqueParser::HelperBodyContext* context) {
if (context) return context->accept(this).as<Statement*>();
return nullptr;
}
antlrcpp::Any AstGenerator::visitParameterList( antlrcpp::Any AstGenerator::visitParameterList(
TorqueParser::ParameterListContext* context) { TorqueParser::ParameterListContext* context) {
ParameterList result{{}, {}, context->VARARGS(), {}}; ParameterList result{{}, {}, context->VARARGS(), {}};
...@@ -117,7 +136,7 @@ antlrcpp::Any AstGenerator::visitMacroDeclaration( ...@@ -117,7 +136,7 @@ antlrcpp::Any AstGenerator::visitMacroDeclaration(
TorqueParser::MacroDeclarationContext* context) { TorqueParser::MacroDeclarationContext* context) {
return base::implicit_cast<Declaration*>(RegisterNode(new MacroDeclaration{ return base::implicit_cast<Declaration*>(RegisterNode(new MacroDeclaration{
Pos(context), context->IDENTIFIER()->getSymbol()->getText(), Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
std::move(context->parameterList()->accept(this).as<ParameterList>()), GetOptionalParameterList(context->parameterList()),
GetOptionalType(context->optionalType()), GetOptionalType(context->optionalType()),
GetOptionalLabelAndTypeList(context->optionalLabelList()), GetOptionalLabelAndTypeList(context->optionalLabelList()),
context->helperBody()->accept(this).as<Statement*>()})); context->helperBody()->accept(this).as<Statement*>()}));
...@@ -588,9 +607,7 @@ antlrcpp::Any AstGenerator::visitConditionalExpression( ...@@ -588,9 +607,7 @@ antlrcpp::Any AstGenerator::visitConditionalExpression(
return base::implicit_cast<Expression*>( return base::implicit_cast<Expression*>(
RegisterNode(new ConditionalExpression{ RegisterNode(new ConditionalExpression{
Pos(context), condition->accept(this).as<Expression*>(), Pos(context), condition->accept(this).as<Expression*>(),
context->logicalORExpression(0)->accept(this).as<Expression*>(), context->logicalORExpression(0)->accept(this).as<Expression*>(),
context->logicalORExpression(1)->accept(this).as<Expression*>()})); context->logicalORExpression(1)->accept(this).as<Expression*>()}));
} }
return context->logicalORExpression(0)->accept(this); return context->logicalORExpression(0)->accept(this);
......
...@@ -148,6 +148,11 @@ class AstGenerator : public TorqueBaseVisitor { ...@@ -148,6 +148,11 @@ class AstGenerator : public TorqueBaseVisitor {
return node; return node;
} }
ParameterList GetOptionalParameterList(
TorqueParser::ParameterListContext* context);
Statement* GetOptionalHelperBody(TorqueParser::HelperBodyContext* context);
void visitSourceFile(SourceFileContext* context); void visitSourceFile(SourceFileContext* context);
SourcePosition Pos(antlr4::ParserRuleContext* context); SourcePosition Pos(antlr4::ParserRuleContext* context);
......
...@@ -158,9 +158,32 @@ struct ExplicitModuleDeclaration : ModuleDeclaration { ...@@ -158,9 +158,32 @@ struct ExplicitModuleDeclaration : ModuleDeclaration {
std::string name; std::string name;
}; };
class SourceFileMap {
public:
SourceFileMap() {}
const std::string& GetSource(SourceId id) const {
return sources_[static_cast<int>(id)];
}
std::string PositionAsString(SourcePosition pos) {
return GetSource(pos.source) + ":" + std::to_string(pos.line) + ":" +
std::to_string(pos.column);
}
private:
friend class Ast;
SourceId AddSource(std::string path) {
sources_.push_back(std::move(path));
return static_cast<SourceId>(sources_.size() - 1);
}
std::vector<std::string> sources_;
};
class Ast { class Ast {
public: public:
Ast() : default_module_{SourcePosition(), {}} {} Ast()
: default_module_{SourcePosition(), {}},
source_file_map_(new SourceFileMap()) {}
std::vector<Declaration*>& declarations() { std::vector<Declaration*>& declarations() {
return default_module_.declarations; return default_module_.declarations;
...@@ -172,21 +195,14 @@ class Ast { ...@@ -172,21 +195,14 @@ class Ast {
nodes_.emplace_back(std::move(node)); nodes_.emplace_back(std::move(node));
} }
SourceId AddSource(std::string path) { SourceId AddSource(std::string path) {
sources_.push_back(std::move(path)); return source_file_map_->AddSource(path);
return static_cast<SourceId>(sources_.size() - 1);
}
const std::string& GetSource(SourceId id) const {
return sources_[static_cast<int>(id)];
} }
std::string PositionAsString(SourcePosition pos) { DefaultModuleDeclaration* default_module() { return &default_module_; }
return GetSource(pos.source) + ":" + std::to_string(pos.line) + ":" + SourceFileMap* source_file_map() { return &*source_file_map_; }
std::to_string(pos.column);
}
DefaultModuleDeclaration* GetDefaultModule() { return &default_module_; }
private: private:
DefaultModuleDeclaration default_module_; DefaultModuleDeclaration default_module_;
std::vector<std::string> sources_; std::unique_ptr<SourceFileMap> source_file_map_;
std::vector<std::unique_ptr<AstNode>> nodes_; std::vector<std::unique_ptr<AstNode>> nodes_;
}; };
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_TORQUE_DECLARABLE_H_ #ifndef V8_TORQUE_DECLARABLE_H_
#define V8_TORQUE_DECLARABLE_H_ #define V8_TORQUE_DECLARABLE_H_
#include <cassert>
#include <string> #include <string>
#include "src/base/logging.h" #include "src/base/logging.h"
...@@ -16,25 +17,28 @@ namespace internal { ...@@ -16,25 +17,28 @@ namespace internal {
namespace torque { namespace torque {
class Scope; class Scope;
class ScopeChain;
class Declarable { class Declarable {
public: public:
virtual ~Declarable() {} virtual ~Declarable() {}
enum Kind { enum Kind {
kVariable = 0, kTypeImpl,
kVariable,
kParameter, kParameter,
kMacro, kMacro,
kMacroList, kMacroList,
kBuiltin, kBuiltin,
kRuntime, kRuntimeFunction,
kLabel, kLabel,
kConstant kConstant
}; };
explicit Declarable(Kind kind) : kind_(kind) {} explicit Declarable(Kind kind) : kind_(kind) {}
Kind kind() const { return kind_; } Kind kind() const { return kind_; }
bool IsTypeImpl() const { return kind() == kTypeImpl; }
bool IsMacro() const { return kind() == kMacro; } bool IsMacro() const { return kind() == kMacro; }
bool IsBuiltin() const { return kind() == kBuiltin; } bool IsBuiltin() const { return kind() == kBuiltin; }
bool IsRuntime() const { return kind() == kRuntime; } bool IsRuntimeFunction() const { return kind() == kRuntimeFunction; }
bool IsParameter() const { return kind() == kParameter; } bool IsParameter() const { return kind() == kParameter; }
bool IsLabel() const { return kind() == kLabel; } bool IsLabel() const { return kind() == kLabel; }
bool IsVariable() const { return kind() == kVariable; } bool IsVariable() const { return kind() == kVariable; }
...@@ -60,6 +64,25 @@ class Declarable { ...@@ -60,6 +64,25 @@ class Declarable {
} \ } \
const char* type_name() const override { return #y; } const char* type_name() const override { return #y; }
class TypeImpl : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(TypeImpl, type_impl);
TypeImpl(TypeImpl* parent, const std::string& name,
const std::string& generated_type)
: Declarable(Declarable::kTypeImpl),
parent_(parent),
name_(name),
generated_type_(generated_type) {}
TypeImpl* parent() const { return parent_; }
const std::string& name() const { return name_; }
const std::string& generated_type() const { return generated_type_; }
private:
TypeImpl* parent_;
std::string name_;
std::string generated_type_;
};
class Value : public Declarable { class Value : public Declarable {
public: public:
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
...@@ -87,7 +110,7 @@ class Parameter : public Value { ...@@ -87,7 +110,7 @@ class Parameter : public Value {
std::string GetValueForDeclaration() const override { return var_name_; } std::string GetValueForDeclaration() const override { return var_name_; }
private: private:
friend class Scope; friend class Declarations;
Parameter(const std::string& name, Type type, const std::string& var_name) Parameter(const std::string& name, Type type, const std::string& var_name)
: Value(Declarable::kParameter, type, name), var_name_(var_name) {} : Value(Declarable::kParameter, type, name), var_name_(var_name) {}
...@@ -107,7 +130,7 @@ class Variable : public Value { ...@@ -107,7 +130,7 @@ class Variable : public Value {
bool IsDefined() const { return defined_; } bool IsDefined() const { return defined_; }
private: private:
friend class Scope; friend class Declarations;
Variable(const std::string& name, const std::string& value, Type type) Variable(const std::string& name, const std::string& value, Type type)
: Value(Declarable::kVariable, type, name), : Value(Declarable::kVariable, type, name),
value_(value), value_(value),
...@@ -131,7 +154,7 @@ class Label : public Value { ...@@ -131,7 +154,7 @@ class Label : public Value {
bool IsUsed() const { return used_; } bool IsUsed() const { return used_; }
private: private:
friend class Scope; friend class Declarations;
explicit Label(const std::string& name) explicit Label(const std::string& name)
: Value(Declarable::kLabel, Type(), : Value(Declarable::kLabel, Type(),
"label_" + name + "_" + std::to_string(next_id_++)), "label_" + name + "_" + std::to_string(next_id_++)),
...@@ -150,7 +173,7 @@ class Constant : public Value { ...@@ -150,7 +173,7 @@ class Constant : public Value {
std::string GetValueForDeclaration() const override { return value_; } std::string GetValueForDeclaration() const override { return value_; }
private: private:
friend class Scope; friend class Declarations;
explicit Constant(const std::string& name, Type type, explicit Constant(const std::string& name, Type type,
const std::string& value) const std::string& value)
: Value(Declarable::kConstant, type, name), value_(value) {} : Value(Declarable::kConstant, type, name), value_(value) {}
...@@ -162,15 +185,14 @@ class Callable : public Declarable { ...@@ -162,15 +185,14 @@ class Callable : public Declarable {
public: public:
static Callable* cast(Declarable* declarable) { static Callable* cast(Declarable* declarable) {
assert(declarable->IsMacro() || declarable->IsBuiltin() || assert(declarable->IsMacro() || declarable->IsBuiltin() ||
declarable->IsRuntime()); declarable->IsRuntimeFunction());
return static_cast<Callable*>(declarable); return static_cast<Callable*>(declarable);
} }
static const Callable* cast(const Declarable* declarable) { static const Callable* cast(const Declarable* declarable) {
assert(declarable->IsMacro() || declarable->IsBuiltin() || assert(declarable->IsMacro() || declarable->IsBuiltin() ||
declarable->IsRuntime()); declarable->IsRuntimeFunction());
return static_cast<const Callable*>(declarable); return static_cast<const Callable*>(declarable);
} }
Scope* scope() const { return scope_; }
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
const Signature& signature() const { return signature_; } const Signature& signature() const { return signature_; }
const NameVector& parameter_names() const { const NameVector& parameter_names() const {
...@@ -183,17 +205,12 @@ class Callable : public Declarable { ...@@ -183,17 +205,12 @@ class Callable : public Declarable {
bool HasReturns() const { return returns_; } bool HasReturns() const { return returns_; }
protected: protected:
Callable(Declarable::Kind kind, const std::string& name, Scope* scope, Callable(Declarable::Kind kind, const std::string& name,
const Signature& signature) const Signature& signature)
: Declarable(kind), : Declarable(kind), name_(name), signature_(signature), returns_(0) {}
name_(name),
scope_(scope),
signature_(signature),
returns_(0) {}
private: private:
std::string name_; std::string name_;
Scope* scope_;
Signature signature_; Signature signature_;
size_t returns_; size_t returns_;
}; };
...@@ -203,31 +220,30 @@ class Macro : public Callable { ...@@ -203,31 +220,30 @@ class Macro : public Callable {
DECLARE_DECLARABLE_BOILERPLATE(Macro, macro); DECLARE_DECLARABLE_BOILERPLATE(Macro, macro);
protected: protected:
Macro(Declarable::Kind type, const std::string& name, Scope* scope, Macro(Declarable::Kind type, const std::string& name,
const Signature& signature) const Signature& signature)
: Callable(type, name, scope, signature) {} : Callable(type, name, signature) {}
private: private:
friend class Scope; friend class Declarations;
Macro(const std::string& name, Scope* scope, const Signature& signature) Macro(const std::string& name, const Signature& signature)
: Macro(Declarable::kMacro, name, scope, signature) {} : Macro(Declarable::kMacro, name, signature) {}
}; };
class MacroList : public Declarable { class MacroList : public Declarable {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list); DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list);
const std::vector<std::unique_ptr<Macro>>& list() { return list_; } const std::vector<Macro*>& list() { return list_; }
Macro* AddMacro(std::unique_ptr<Macro> macro) { Macro* AddMacro(Macro* macro) {
Macro* result = macro.get(); list_.emplace_back(macro);
list_.emplace_back(std::move(macro)); return macro;
return result;
} }
private: private:
friend class Scope; friend class Declarations;
MacroList() : Declarable(Declarable::kMacroList) {} MacroList() : Declarable(Declarable::kMacroList) {}
std::vector<std::unique_ptr<Macro>> list_; std::vector<Macro*> list_;
}; };
class Builtin : public Callable { class Builtin : public Callable {
...@@ -240,22 +256,22 @@ class Builtin : public Callable { ...@@ -240,22 +256,22 @@ class Builtin : public Callable {
bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; } bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; }
private: private:
friend class Scope; friend class Declarations;
Builtin(const std::string& name, Builtin::Kind kind, Scope* scope, Builtin(const std::string& name, Builtin::Kind kind,
const Signature& signature) const Signature& signature)
: Callable(Declarable::kBuiltin, name, scope, signature), kind_(kind) {} : Callable(Declarable::kBuiltin, name, signature), kind_(kind) {}
Kind kind_; Kind kind_;
}; };
class Runtime : public Callable { class RuntimeFunction : public Callable {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Runtime, runtime); DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime);
private: private:
friend class Scope; friend class Declarations;
Runtime(const std::string& name, Scope* scope, const Signature& signature) RuntimeFunction(const std::string& name, const Signature& signature)
: Callable(Declarable::kRuntime, name, scope, signature) {} : Callable(Declarable::kRuntimeFunction, name, signature) {}
}; };
inline std::ostream& operator<<(std::ostream& os, const Callable& m) { inline std::ostream& operator<<(std::ostream& os, const Callable& m) {
...@@ -275,8 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const Builtin& b) { ...@@ -275,8 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const Builtin& b) {
return os; return os;
} }
inline std::ostream& operator<<(std::ostream& os, const Runtime& b) { inline std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
os << "runtime " << b.signature().return_type << " " << b.name() os << "runtime function " << b.signature().return_type << " " << b.name()
<< b.signature().parameter_types; << b.signature().parameter_types;
return os; return os;
} }
......
...@@ -48,12 +48,21 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) { ...@@ -48,12 +48,21 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
if (global_context_.verbose()) { if (global_context_.verbose()) {
std::cout << "found declaration of builtin " << decl->name; std::cout << "found declaration of builtin " << decl->name;
} }
Scope* enclosing_scope = TopScope();
Signature signature = MakeSignature(decl->parameters, decl->return_type, {}); const bool javascript = decl->javascript_linkage;
const bool varargs = decl->parameters.has_varargs;
Builtin::Kind kind = !javascript ? Builtin::kStub
: varargs ? Builtin::kVarArgsJavaScript
: Builtin::kFixedArgsJavaScript;
Signature signature =
MakeSignature(decl->pos, decl->parameters, decl->return_type, {});
Builtin* builtin =
declarations()->DeclareBuiltin(decl->pos, decl->name, kind, signature);
CurrentCallableActivator activator(global_context_, builtin, decl);
DeclareParameterList(decl->pos, signature, {});
Scope* new_scope = new Scope(global_context_);
Scope::Activator s(new_scope);
if (signature.types().size() == 0 || if (signature.types().size() == 0 ||
!signature.types()[0].Is(CONTEXT_TYPE_STRING)) { !signature.types()[0].Is(CONTEXT_TYPE_STRING)) {
std::stringstream stream; std::stringstream stream;
...@@ -66,8 +75,6 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) { ...@@ -66,8 +75,6 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
std::cout << decl->name << " with signature " << signature << std::endl; std::cout << decl->name << " with signature " << signature << std::endl;
} }
const bool javascript = decl->javascript_linkage;
const bool varargs = decl->parameters.has_varargs;
if (varargs && !javascript) { if (varargs && !javascript) {
std::stringstream stream; std::stringstream stream;
stream << "builtin " << decl->name stream << "builtin " << decl->name
...@@ -87,50 +94,31 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) { ...@@ -87,50 +94,31 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
} }
if (varargs) { if (varargs) {
TopScope()->DeclareConstant(decl->pos, decl->parameters.arguments_variable, declarations()->DeclareConstant(
GetTypeOracle().GetArgumentsType(), decl->pos, decl->parameters.arguments_variable,
"arguments"); GetTypeOracle().GetArgumentsType(), "arguments");
} }
Builtin::Kind kind = !javascript ? Builtin::kStub
: varargs ? Builtin::kVarArgsJavaScript
: Builtin::kFixedArgsJavaScript;
Builtin* builtin = enclosing_scope->DeclareBuiltin(
decl->pos, decl->name, kind, new_scope, signature);
defined_builtins_.push_back(builtin); defined_builtins_.push_back(builtin);
DeclareParameterList(decl->pos, signature, {});
CurrentCallActivator activator(global_context_, builtin);
Visit(decl->body); Visit(decl->body);
} }
void DeclarationVisitor::Visit(MacroDeclaration* decl) { void DeclarationVisitor::Visit(MacroDeclaration* decl) {
if (global_context_.verbose()) { Signature signature = MakeSignature(decl->pos, decl->parameters,
std::cout << "found declaration of macro " << decl->name; decl->return_type, decl->labels);
}
Scope* enclosing_scope = TopScope();
Scope* new_scope = new Scope(global_context_);
Scope::Activator s(new_scope);
PushControlSplit(); Macro* macro = declarations()->DeclareMacro(decl->pos, decl->name, signature);
CurrentCallableActivator activator(global_context_, macro, decl);
Signature signature = DeclareParameterList(decl->pos, signature, decl->labels);
MakeSignature(decl->parameters, decl->return_type, decl->labels);
if (!signature.return_type.IsVoidOrNever()) { if (!signature.return_type.IsVoidOrNever()) {
TopScope()->DeclareVariable(decl->pos, kReturnValueVariable, declarations()->DeclareVariable(decl->pos, kReturnValueVariable,
signature.return_type); signature.return_type);
} }
if (global_context_.verbose()) { PushControlSplit();
std::cout << " resulting in signature " << signature << "\n";
}
Macro* macro = enclosing_scope->DeclareMacro(decl->pos, decl->name, new_scope,
signature);
DeclareParameterList(decl->pos, signature, decl->labels);
CurrentCallActivator activator(global_context_, macro);
Visit(decl->body); Visit(decl->body);
auto changed_vars = PopControlSplit(); auto changed_vars = PopControlSplit();
global_context_.AddControlSplitChangedVariables(decl, changed_vars); global_context_.AddControlSplitChangedVariables(decl, changed_vars);
} }
...@@ -138,14 +126,14 @@ void DeclarationVisitor::Visit(MacroDeclaration* decl) { ...@@ -138,14 +126,14 @@ void DeclarationVisitor::Visit(MacroDeclaration* decl) {
void DeclarationVisitor::Visit(ReturnStatement* stmt) { void DeclarationVisitor::Visit(ReturnStatement* stmt) {
const Callable* callable = global_context_.GetCurrentCallable(); const Callable* callable = global_context_.GetCurrentCallable();
if (callable->IsMacro() && callable->HasReturnValue()) { if (callable->IsMacro() && callable->HasReturnValue()) {
MarkVariableModified( MarkVariableModified(Variable::cast(
Variable::cast(LookupValue(stmt->pos, kReturnValueVariable))); declarations()->LookupValue(stmt->pos, kReturnValueVariable)));
} }
} }
void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) { void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) {
// Scope for for iteration variable // Scope for for iteration variable
Scope::Activator s(global_context_, stmt); Declarations::NodeScopeActivator scope(declarations(), stmt);
Visit(stmt->var_declaration); Visit(stmt->var_declaration);
Visit(stmt->iterable); Visit(stmt->iterable);
if (stmt->begin) Visit(*stmt->begin); if (stmt->begin) Visit(*stmt->begin);
...@@ -160,13 +148,14 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) { ...@@ -160,13 +148,14 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
// Activate a new scope to declare catch handler labels, they should not be // Activate a new scope to declare catch handler labels, they should not be
// visible outside the catch. // visible outside the catch.
{ {
Scope::Activator s(global_context_, stmt); Declarations::NodeScopeActivator scope(declarations(), stmt);
// Declare catch labels // Declare catch labels
for (LabelBlock* block : stmt->label_blocks) { for (LabelBlock* block : stmt->label_blocks) {
Label* shared_label = TopScope()->DeclareLabel(stmt->pos, block->label); Label* shared_label =
declarations()->DeclareLabel(stmt->pos, block->label);
{ {
Scope::Activator s(global_context_, block->body); Declarations::NodeScopeActivator scope(declarations(), block->body);
if (block->parameters.has_varargs) { if (block->parameters.has_varargs) {
std::stringstream stream; std::stringstream stream;
stream << "cannot use ... for label parameters at " stream << "cannot use ... for label parameters at "
...@@ -176,9 +165,10 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) { ...@@ -176,9 +165,10 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
size_t i = 0; size_t i = 0;
for (auto p : block->parameters.names) { for (auto p : block->parameters.names) {
shared_label->AddVariable(TopScope()->DeclareVariable( shared_label->AddVariable(declarations()->DeclareVariable(
stmt->pos, p, stmt->pos, p,
GetTypeOracle().GetType(block->parameters.types[i]))); declarations()->LookupType(stmt->pos,
block->parameters.types[i])));
++i; ++i;
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <set> #include <set>
#include <string> #include <string>
#include "src/torque/declarations.h"
#include "src/torque/file-visitor.h" #include "src/torque/file-visitor.h"
#include "src/torque/global-context.h" #include "src/torque/global-context.h"
#include "src/torque/scope.h" #include "src/torque/scope.h"
...@@ -21,11 +22,13 @@ namespace torque { ...@@ -21,11 +22,13 @@ namespace torque {
class DeclarationVisitor : public FileVisitor { class DeclarationVisitor : public FileVisitor {
public: public:
explicit DeclarationVisitor(GlobalContext& global_context) explicit DeclarationVisitor(GlobalContext& global_context)
: FileVisitor(global_context) { : FileVisitor(global_context),
GetTypeOracle().RegisterTypeImpl(EXCEPTION_TYPE_STRING, "Label*", nullptr); scope_(declarations(), global_context.ast()->default_module()) {
declarations()->DeclareType(SourcePosition(), EXCEPTION_TYPE_STRING,
"Label*", nullptr);
} }
void Visit(Ast* ast) { Visit(ast->GetDefaultModule()); } void Visit(Ast* ast) { Visit(ast->default_module()); }
void Visit(Expression* expr); void Visit(Expression* expr);
void Visit(Statement* stmt); void Visit(Statement* stmt);
...@@ -34,7 +37,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -34,7 +37,7 @@ class DeclarationVisitor : public FileVisitor {
void Visit(ModuleDeclaration* decl) { void Visit(ModuleDeclaration* decl) {
Module* saved_module = module_; Module* saved_module = module_;
module_ = decl->GetModule(); module_ = decl->GetModule();
Scope::Activator activator(module_->scope()); Declarations::NodeScopeActivator scope(declarations(), decl);
for (Declaration* child : decl->declarations) Visit(child); for (Declaration* child : decl->declarations) Visit(child);
module_ = saved_module; module_ = saved_module;
} }
...@@ -61,7 +64,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -61,7 +64,7 @@ class DeclarationVisitor : public FileVisitor {
void Visit(CastExpression* expr) { Visit(expr->value); } void Visit(CastExpression* expr) { Visit(expr->value); }
void Visit(ConvertExpression* expr) { Visit(expr->value); } void Visit(ConvertExpression* expr) { Visit(expr->value); }
void Visit(BlockStatement* expr) { void Visit(BlockStatement* expr) {
Scope::Activator s(global_context_, expr); Declarations::NodeScopeActivator scope(declarations(), expr);
for (Statement* stmt : expr->statements) Visit(stmt); for (Statement* stmt : expr->statements) Visit(stmt);
} }
void Visit(ExpressionStatement* stmt) { Visit(stmt->expression); } void Visit(ExpressionStatement* stmt) { Visit(stmt->expression); }
...@@ -70,7 +73,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -70,7 +73,7 @@ class DeclarationVisitor : public FileVisitor {
void Visit(TypeDeclaration* decl) { void Visit(TypeDeclaration* decl) {
std::string generates_class_name = std::string generates_class_name =
decl->generates ? *decl->generates : decl->name; decl->generates ? *decl->generates : decl->name;
GetTypeOracle().RegisterTypeImpl(decl->name, generates_class_name, declarations()->DeclareType(decl->pos, decl->name, generates_class_name,
decl->extends ? &*decl->extends : nullptr); decl->extends ? &*decl->extends : nullptr);
} }
...@@ -81,7 +84,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -81,7 +84,7 @@ class DeclarationVisitor : public FileVisitor {
} }
Signature signature = Signature signature =
MakeSignature(decl->parameters, decl->return_type, {}); MakeSignature(decl->pos, decl->parameters, decl->return_type, {});
if (signature.parameter_types.types.size() == 0 || if (signature.parameter_types.types.size() == 0 ||
!signature.parameter_types.types[0].Is(CONTEXT_TYPE_STRING)) { !signature.parameter_types.types[0].Is(CONTEXT_TYPE_STRING)) {
...@@ -113,7 +116,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -113,7 +116,7 @@ class DeclarationVisitor : public FileVisitor {
Builtin::Kind kind = !javascript ? Builtin::kStub Builtin::Kind kind = !javascript ? Builtin::kStub
: varargs ? Builtin::kVarArgsJavaScript : varargs ? Builtin::kVarArgsJavaScript
: Builtin::kFixedArgsJavaScript; : Builtin::kFixedArgsJavaScript;
TopScope()->DeclareBuiltin(decl->pos, decl->name, kind, nullptr, signature); declarations()->DeclareBuiltin(decl->pos, decl->name, kind, signature);
} }
void Visit(ExternalRuntimeDeclaration* decl) { void Visit(ExternalRuntimeDeclaration* decl) {
...@@ -121,8 +124,9 @@ class DeclarationVisitor : public FileVisitor { ...@@ -121,8 +124,9 @@ class DeclarationVisitor : public FileVisitor {
std::cout << "found declaration of external runtime " << decl->name std::cout << "found declaration of external runtime " << decl->name
<< " with signature "; << " with signature ";
} }
Type return_type = GetType(decl->return_type); Type return_type = declarations()->LookupType(decl->pos, decl->return_type);
TypeVector parameter_types = GetTypeVector(decl->parameters.types); TypeVector parameter_types =
GetTypeVector(decl->pos, decl->parameters.types);
if (parameter_types.size() == 0 || if (parameter_types.size() == 0 ||
!parameter_types[0].Is(CONTEXT_TYPE_STRING)) { !parameter_types[0].Is(CONTEXT_TYPE_STRING)) {
std::stringstream stream; std::stringstream stream;
...@@ -136,7 +140,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -136,7 +140,7 @@ class DeclarationVisitor : public FileVisitor {
{parameter_types, decl->parameters.has_varargs}, {parameter_types, decl->parameters.has_varargs},
return_type, return_type,
{}}; {}};
TopScope()->DeclareRuntime(decl->pos, decl->name, nullptr, declarations()->DeclareRuntimeFunction(decl->pos, decl->name,
std::move(signature)); std::move(signature));
} }
...@@ -146,10 +150,10 @@ class DeclarationVisitor : public FileVisitor { ...@@ -146,10 +150,10 @@ class DeclarationVisitor : public FileVisitor {
<< " with signature "; << " with signature ";
} }
Signature signature = Signature signature = MakeSignature(decl->pos, decl->parameters,
MakeSignature(decl->parameters, decl->return_type, decl->labels); decl->return_type, decl->labels);
TopScope()->DeclareMacro(decl->pos, decl->name, nullptr, signature); declarations()->DeclareMacro(decl->pos, decl->name, signature);
if (decl->op) { if (decl->op) {
OperationHandler handler( OperationHandler handler(
{decl->name, signature.parameter_types, signature.return_type}); {decl->name, signature.parameter_types, signature.return_type});
...@@ -188,8 +192,8 @@ class DeclarationVisitor : public FileVisitor { ...@@ -188,8 +192,8 @@ class DeclarationVisitor : public FileVisitor {
void Visit(VarDeclarationStatement* stmt) { void Visit(VarDeclarationStatement* stmt) {
std::string variable_name = stmt->name; std::string variable_name = stmt->name;
Type type = GetType(stmt->type); Type type = declarations()->LookupType(stmt->pos, stmt->type);
TopScope()->DeclareVariable(stmt->pos, variable_name, type); declarations()->DeclareVariable(stmt->pos, variable_name, type);
if (global_context_.verbose()) { if (global_context_.verbose()) {
std::cout << "declared variable " << variable_name << " with type " std::cout << "declared variable " << variable_name << " with type "
<< type << "\n"; << type << "\n";
...@@ -204,14 +208,15 @@ class DeclarationVisitor : public FileVisitor { ...@@ -204,14 +208,15 @@ class DeclarationVisitor : public FileVisitor {
} }
void Visit(ConstDeclaration* decl) { void Visit(ConstDeclaration* decl) {
TopScope()->DeclareConstant(decl->pos, decl->name, GetType(decl->type), declarations()->DeclareConstant(
decl->literal); decl->pos, decl->name,
declarations()->LookupType(decl->pos, decl->type), decl->literal);
} }
void Visit(LogicalOrExpression* expr) { void Visit(LogicalOrExpression* expr) {
{ {
Scope::Activator s(global_context_, expr->left); Declarations::NodeScopeActivator scope(declarations(), expr->left);
TopScope()->DeclareLabel(expr->pos, kFalseLabelName); declarations()->DeclareLabel(expr->pos, kFalseLabelName);
Visit(expr->left); Visit(expr->left);
} }
Visit(expr->right); Visit(expr->right);
...@@ -219,23 +224,23 @@ class DeclarationVisitor : public FileVisitor { ...@@ -219,23 +224,23 @@ class DeclarationVisitor : public FileVisitor {
void Visit(LogicalAndExpression* expr) { void Visit(LogicalAndExpression* expr) {
{ {
Scope::Activator s(global_context_, expr->left); Declarations::NodeScopeActivator scope(declarations(), expr->left);
TopScope()->DeclareLabel(expr->pos, kTrueLabelName); declarations()->DeclareLabel(expr->pos, kTrueLabelName);
Visit(expr->left); Visit(expr->left);
} }
Visit(expr->right); Visit(expr->right);
} }
void DeclareExpressionForBranch(Expression* node) { void DeclareExpressionForBranch(Expression* node) {
Scope::Activator s(global_context_, node); Declarations::NodeScopeActivator scope(declarations(), node);
// Conditional expressions can either explicitly return a bit // Conditional expressions can either explicitly return a bit
// type, or they can be backed by macros that don't return but // type, or they can be backed by macros that don't return but
// take a true and false label. By declaring the labels before // take a true and false label. By declaring the labels before
// visiting the conditional expression, those label-based // visiting the conditional expression, those label-based
// macro conditionals will be able to find them through normal // macro conditionals will be able to find them through normal
// label lookups. // label lookups.
TopScope()->DeclareLabel(node->pos, kTrueLabelName); declarations()->DeclareLabel(node->pos, kTrueLabelName);
TopScope()->DeclareLabel(node->pos, kFalseLabelName); declarations()->DeclareLabel(node->pos, kFalseLabelName);
Visit(node); Visit(node);
} }
...@@ -258,7 +263,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -258,7 +263,7 @@ class DeclarationVisitor : public FileVisitor {
} }
void Visit(WhileStatement* stmt) { void Visit(WhileStatement* stmt) {
Scope::Activator s(global_context_, stmt); Declarations::NodeScopeActivator scope(declarations(), stmt);
DeclareExpressionForBranch(stmt->condition); DeclareExpressionForBranch(stmt->condition);
PushControlSplit(); PushControlSplit();
Visit(stmt->body); Visit(stmt->body);
...@@ -279,7 +284,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -279,7 +284,7 @@ class DeclarationVisitor : public FileVisitor {
void Visit(GotoStatement* expr) {} void Visit(GotoStatement* expr) {}
void Visit(ForLoopStatement* stmt) { void Visit(ForLoopStatement* stmt) {
Scope::Activator s(global_context_, stmt); Declarations::NodeScopeActivator scope(declarations(), stmt);
if (stmt->var_declaration) Visit(*stmt->var_declaration); if (stmt->var_declaration) Visit(*stmt->var_declaration);
PushControlSplit(); PushControlSplit();
DeclareExpressionForBranch(stmt->test); DeclareExpressionForBranch(stmt->test);
...@@ -353,7 +358,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -353,7 +358,7 @@ class DeclarationVisitor : public FileVisitor {
void PushControlSplit() { void PushControlSplit() {
LiveAndChanged live_and_changed; LiveAndChanged live_and_changed;
live_and_changed.live = global_context_.GetLiveTypeVariables(); live_and_changed.live = declarations()->GetLiveVariables();
live_and_changed_variables_.push_back(live_and_changed); live_and_changed_variables_.push_back(live_and_changed);
} }
...@@ -365,7 +370,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -365,7 +370,7 @@ class DeclarationVisitor : public FileVisitor {
void MarkLocationModified(Expression* location) { void MarkLocationModified(Expression* location) {
if (IdentifierExpression* id = IdentifierExpression::cast(location)) { if (IdentifierExpression* id = IdentifierExpression::cast(location)) {
const Value* value = LookupValue(id->pos, id->name); const Value* value = declarations()->LookupValue(id->pos, id->name);
if (value->IsVariable()) { if (value->IsVariable()) {
const Variable* variable = Variable::cast(value); const Variable* variable = Variable::cast(value);
bool was_live = MarkVariableModified(variable); bool was_live = MarkVariableModified(variable);
...@@ -396,23 +401,24 @@ class DeclarationVisitor : public FileVisitor { ...@@ -396,23 +401,24 @@ class DeclarationVisitor : public FileVisitor {
auto name_iterator = signature.parameter_names.begin(); auto name_iterator = signature.parameter_names.begin();
for (auto t : signature.types()) { for (auto t : signature.types()) {
const std::string& name(*name_iterator++); const std::string& name(*name_iterator++);
TopScope()->DeclareParameter(pos, name, declarations()->DeclareParameter(pos, name,
GetParameterVariableFromName(name), t); GetParameterVariableFromName(name), t);
} }
if (labels) { if (labels) {
for (auto label : *labels) { for (auto label : *labels) {
auto label_params = GetTypeVector(label.types); auto label_params = GetTypeVector(pos, label.types);
Label* new_label = TopScope()->DeclareLabel(pos, label.name); Label* new_label = declarations()->DeclareLabel(pos, label.name);
size_t i = 0; size_t i = 0;
for (auto var_type : label_params) { for (auto var_type : label_params) {
std::string var_name = label.name + std::to_string(i++); std::string var_name = label.name + std::to_string(i++);
new_label->AddVariable( new_label->AddVariable(
TopScope()->DeclareVariable(pos, var_name, var_type)); declarations()->DeclareVariable(pos, var_name, var_type));
} }
} }
} }
} }
Declarations::NodeScopeActivator scope_;
std::vector<Builtin*> defined_builtins_; std::vector<Builtin*> defined_builtins_;
std::vector<LiveAndChanged> live_and_changed_variables_; std::vector<LiveAndChanged> live_and_changed_variables_;
}; };
......
// Copyright 2017 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 "src/torque/declarations.h"
#include "src/torque/declarable.h"
namespace v8 {
namespace internal {
namespace torque {
Scope* Declarations::GetNodeScope(const AstNode* node) {
auto i = node_scopes_.find(node);
if (i != node_scopes_.end()) return i->second;
Scope* result = chain_.NewScope();
node_scopes_[node] = result;
return result;
}
void Declarations::CheckAlreadyDeclared(SourcePosition pos,
const std::string& name,
const char* new_type) {
auto i = chain_.ShallowLookup(name);
if (i != nullptr) {
std::stringstream s;
s << "cannot redeclare " << name << " (type " << new_type << ") at "
<< PositionAsString(pos) << std::endl;
ReportError(s.str());
}
}
Type Declarations::LookupType(SourcePosition pos, const std::string& name) {
Declarable* raw = Lookup(pos, name);
if (!raw->IsTypeImpl()) {
std::stringstream s;
s << "declaration \"" << name << "\" is not a Type at "
<< PositionAsString(pos);
ReportError(s.str());
}
return Type(TypeImpl::cast(raw));
}
Value* Declarations::LookupValue(SourcePosition pos, const std::string& name) {
Declarable* d = Lookup(pos, name);
if (!d->IsValue()) {
std::stringstream s;
s << "declaration \"" << name << "\" is not a Value at "
<< PositionAsString(pos);
ReportError(s.str());
}
return Value::cast(d);
}
Macro* Declarations::LookupMacro(SourcePosition pos, const std::string& name,
const TypeVector& types) {
Declarable* declarable = Lookup(name);
if (declarable != nullptr) {
if (declarable->IsMacroList()) {
for (auto& m : MacroList::cast(declarable)->list()) {
if (m->signature().parameter_types.types == types &&
!m->signature().parameter_types.var_args) {
return m;
}
}
}
}
std::stringstream stream;
stream << "macro " << name << " with parameter types " << types
<< " referenced at " << PositionAsString(pos) << " is not defined";
ReportError(stream.str());
return nullptr;
}
Builtin* Declarations::LookupBuiltin(const SourcePosition& pos,
const std::string& name) {
Declarable* declarable = Lookup(name);
if (declarable != nullptr) {
if (declarable->IsBuiltin()) {
return Builtin::cast(declarable);
}
ReportError(name + " referenced at " + PositionAsString(pos) +
" is not a builtin");
}
ReportError(std::string("builtin ") + name + " referenced at " +
PositionAsString(pos) + " is not defined");
return nullptr;
}
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;
if (parent != nullptr) {
Declarable* maybe_parent_type = Lookup(*parent);
if (maybe_parent_type == nullptr) {
std::stringstream s;
s << "cannot find parent type \"" << *parent << "\" at "
<< PositionAsString(pos);
ReportError(s.str());
}
if (!maybe_parent_type->IsTypeImpl()) {
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);
}
TypeImpl* result = new TypeImpl(parent_type, name, generated);
Declare(name, std::unique_ptr<Declarable>(result));
return Type(result);
}
Label* Declarations::DeclareLabel(SourcePosition pos, const std::string& name) {
CheckAlreadyDeclared(pos, name, "label");
Label* result = new Label(name);
Declare(name, std::unique_ptr<Declarable>(result));
return result;
}
Macro* Declarations::DeclareMacro(SourcePosition pos, const std::string& name,
const Signature& signature) {
auto previous = chain_.Lookup(name);
MacroList* macro_list = nullptr;
if (previous == nullptr) {
macro_list = new MacroList();
Declare(name, std::unique_ptr<Declarable>(macro_list));
} else if (!previous->IsMacroList()) {
std::stringstream s;
s << "cannot redeclare non-macro " << name << " as a macro at "
<< PositionAsString(pos);
ReportError(s.str());
} else {
macro_list = MacroList::cast(previous);
}
for (auto& macro : macro_list->list()) {
if (signature.parameter_types.types ==
macro->signature().parameter_types.types &&
signature.parameter_types.var_args ==
macro->signature().parameter_types.var_args) {
std::stringstream s;
s << "cannot redeclare " << name
<< " as a macro with identical parameter list "
<< signature.parameter_types << PositionAsString(pos);
ReportError(s.str());
}
}
return macro_list->AddMacro(new Macro(name, signature));
}
Builtin* Declarations::DeclareBuiltin(SourcePosition pos,
const std::string& name,
Builtin::Kind kind,
const Signature& signature) {
CheckAlreadyDeclared(pos, name, "builtin");
Builtin* result = new Builtin(name, kind, signature);
Declare(name, std::unique_ptr<Declarable>(result));
return result;
}
RuntimeFunction* Declarations::DeclareRuntimeFunction(
SourcePosition pos, const std::string& name, const Signature& signature) {
CheckAlreadyDeclared(pos, name, "runtime function");
RuntimeFunction* result = new RuntimeFunction(name, signature);
Declare(name, std::unique_ptr<Declarable>(result));
return result;
}
Variable* Declarations::DeclareVariable(SourcePosition pos,
const std::string& var, Type type) {
std::string name(var + std::to_string(GetNextUniqueDeclarationNumber()));
CheckAlreadyDeclared(pos, var, "variable");
Variable* result = new Variable(var, name, type);
Declare(var, std::unique_ptr<Declarable>(result));
return result;
}
Parameter* Declarations::DeclareParameter(SourcePosition pos,
const std::string& name,
const std::string& var_name,
Type type) {
CheckAlreadyDeclared(pos, name, "parameter");
Parameter* result = new Parameter(name, type, var_name);
Declare(name, std::unique_ptr<Declarable>(result));
return result;
}
Label* Declarations::DeclarePrivateLabel(SourcePosition pos,
const std::string& raw_name) {
std::string name =
raw_name + "_" + std::to_string(GetNextUniqueDeclarationNumber());
CheckAlreadyDeclared(pos, name, "label");
Label* result = new Label(name);
Declare(name, std::unique_ptr<Declarable>(result));
return result;
}
void Declarations::DeclareConstant(SourcePosition pos, const std::string& name,
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));
}
} // namespace torque
} // namespace internal
} // namespace v8
// Copyright 2017 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.
#ifndef V8_TORQUE_DECLARATIONS_H_
#define V8_TORQUE_DECLARATIONS_H_
#include <string>
#include "src/torque/declarable.h"
#include "src/torque/scope.h"
namespace v8 {
namespace internal {
namespace torque {
class Declarations {
public:
explicit Declarations(SourceFileMap* source_file_map)
: source_file_map_(source_file_map), unique_declaration_number_(0) {}
Declarable* Lookup(const std::string& name) { return chain_.Lookup(name); }
Declarable* Lookup(SourcePosition pos, const std::string& name) {
Declarable* d = Lookup(name);
if (d == nullptr) {
std::stringstream s;
s << "cannot find \"" << name << "\" at " << PositionAsString(pos);
ReportError(s.str());
}
return d;
}
Type LookupType(SourcePosition pos, const std::string& name);
Value* LookupValue(SourcePosition pos, const std::string& name);
Macro* LookupMacro(SourcePosition pos, const std::string& name,
const TypeVector& types);
Builtin* LookupBuiltin(const SourcePosition& pos, const std::string& name);
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);
Macro* DeclareMacro(SourcePosition pos, const std::string& name,
const Signature& signature);
Builtin* DeclareBuiltin(SourcePosition pos, const std::string& name,
Builtin::Kind kind, const Signature& signature);
RuntimeFunction* DeclareRuntimeFunction(SourcePosition pos,
const std::string& name,
const Signature& signature);
Variable* DeclareVariable(SourcePosition pos, const std::string& var,
Type type);
Parameter* DeclareParameter(SourcePosition pos, const std::string& name,
const std::string& mangled_name, Type type);
Label* DeclarePrivateLabel(SourcePosition pos, const std::string& name);
void DeclareConstant(SourcePosition pos, const std::string& name, Type type,
const std::string& value);
std::set<const Variable*> GetLiveVariables() {
return chain_.GetLiveVariables();
}
std::string PositionAsString(SourcePosition pos) {
return source_file_map_->PositionAsString(pos);
}
class NodeScopeActivator;
private:
Scope* GetNodeScope(const AstNode* node);
void Declare(const std::string& name, std::unique_ptr<Declarable> d) {
Declarable* ptr = d.get();
declarables_.emplace_back(std::move(d));
chain_.Declare(name, ptr);
}
int GetNextUniqueDeclarationNumber() { return unique_declaration_number_++; }
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
const char* new_type);
SourceFileMap* source_file_map_;
int unique_declaration_number_;
ScopeChain chain_;
std::vector<std::unique_ptr<Declarable>> declarables_;
std::map<const AstNode*, Scope*> node_scopes_;
};
class Declarations::NodeScopeActivator {
public:
NodeScopeActivator(Declarations* declarations, AstNode* node)
: activator_(declarations->GetNodeScope(node)) {}
private:
Scope::Activator activator_;
};
} // namespace torque
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_DECLARATIONS_H_
...@@ -10,21 +10,69 @@ namespace v8 { ...@@ -10,21 +10,69 @@ namespace v8 {
namespace internal { namespace internal {
namespace torque { namespace torque {
Signature FileVisitor::MakeSignature(const ParameterList& parameters, Signature FileVisitor::MakeSignature(SourcePosition pos,
const ParameterList& parameters,
const std::string& return_type, const std::string& return_type,
const LabelAndTypesVector& labels) { const LabelAndTypesVector& labels) {
LabelDeclarationVector definition_vector; LabelDeclarationVector definition_vector;
for (auto label : labels) { for (auto label : labels) {
LabelDeclaration def = {label.name, GetTypeVector(label.types)}; LabelDeclaration def = {label.name, GetTypeVector(pos, label.types)};
definition_vector.push_back(def); definition_vector.push_back(def);
} }
Signature result{parameters.names, Signature result{
{GetTypeVector(parameters.types), parameters.has_varargs}, parameters.names,
GetType(return_type), {GetTypeVector(pos, parameters.types), parameters.has_varargs},
declarations()->LookupType(pos, return_type),
definition_vector}; definition_vector};
return result; return result;
} }
Callable* FileVisitor::LookupCall(SourcePosition pos, const std::string& name,
const TypeVector& parameter_types) {
Callable* result = nullptr;
Declarable* declarable = declarations()->Lookup(pos, name);
if (declarable->IsBuiltin()) {
result = Builtin::cast(declarable);
} else if (declarable->IsRuntimeFunction()) {
result = RuntimeFunction::cast(declarable);
} else if (declarable->IsMacroList()) {
for (auto& m : MacroList::cast(declarable)->list()) {
if (GetTypeOracle().IsCompatibleSignature(m->signature().parameter_types,
parameter_types)) {
if (result != nullptr) {
std::stringstream stream;
stream << "multiple matching matching parameter list for macro "
<< name << ": (" << parameter_types << ") and ("
<< result->signature().parameter_types << ") at "
<< PositionAsString(pos);
ReportError(stream.str());
}
result = m;
}
}
if (result == nullptr) {
std::stringstream stream;
stream << "no matching matching parameter list for macro " << name
<< ": call parameters were (" << parameter_types << ") at "
<< PositionAsString(pos);
ReportError(stream.str());
}
}
size_t caller_size = parameter_types.size();
size_t callee_size = result->signature().types().size();
if (caller_size != callee_size &&
!result->signature().parameter_types.var_args) {
std::stringstream stream;
stream << "parameter count mismatch calling " << *result << ": expected "
<< std::to_string(callee_size) << ", found "
<< std::to_string(caller_size);
ReportError(stream.str());
}
return result;
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -22,22 +22,20 @@ class FileVisitor { ...@@ -22,22 +22,20 @@ class FileVisitor {
public: public:
explicit FileVisitor(GlobalContext& global_context) explicit FileVisitor(GlobalContext& global_context)
: global_context_(global_context), : global_context_(global_context),
module_(global_context.GetDefaultModule()) { declarations_(global_context.declarations()),
global_context_.PushScope(module_->scope()); module_(global_context.GetDefaultModule()) {}
}
Type GetType(const std::string& s) { return GetTypeOracle().GetType(s); } TypeVector GetTypeVector(SourcePosition pos,
TypeVector GetTypeVector(const std::vector<std::string>& v) { const std::vector<std::string>& v) {
TypeVector result; TypeVector result;
for (const std::string& s : v) { for (const std::string& s : v) {
result.push_back(GetType(s)); result.push_back(declarations()->LookupType(pos, s));
} }
return result; return result;
} }
Scope* TopScope() { return global_context_.TopScope(); }
Ast* ast() { return global_context_.ast(); } Ast* ast() { return global_context_.ast(); }
Declarations* declarations() { return global_context_.declarations(); }
protected: protected:
static constexpr const char* kTrueLabelName = "True"; static constexpr const char* kTrueLabelName = "True";
...@@ -51,110 +49,23 @@ class FileVisitor { ...@@ -51,110 +49,23 @@ class FileVisitor {
TypeOracle& GetTypeOracle() { return global_context_.GetTypeOracle(); } TypeOracle& GetTypeOracle() { return global_context_.GetTypeOracle(); }
bool IsValueDeclared(const std::string& id) {
return global_context_.Lookup(id) != nullptr;
}
Value* LookupValue(SourcePosition pos, const std::string& id) {
Declarable* declarable = global_context_.Lookup(id);
if (declarable != nullptr) {
if (declarable->IsValue()) {
return Value::cast(declarable);
}
ReportError(id + " referenced at " + PositionAsString(pos) +
" is not a variable, parameter or verbatim");
}
ReportError(std::string("identifier ") + id + " referenced at " +
PositionAsString(pos) + " is not defined");
return nullptr;
}
Callable* LookupCall(SourcePosition pos, const std::string& name,
const TypeVector& parameter_types) {
Callable* result = nullptr;
Declarable* declarable = global_context_.Lookup(name);
if (declarable != nullptr) {
if (declarable->IsBuiltin()) {
result = Builtin::cast(declarable);
} else if (declarable->IsRuntime()) {
result = Runtime::cast(declarable);
} else if (declarable->IsMacroList()) {
for (auto& m : MacroList::cast(declarable)->list()) {
if (GetTypeOracle().IsCompatibleSignature(
m->signature().parameter_types, parameter_types)) {
result = m.get();
break;
}
}
}
}
if (result == nullptr) {
std::stringstream stream;
stream << "cannot find macro, builtin or runtime call " << name
<< " matching parameter types " << parameter_types;
ReportError(stream.str());
}
size_t caller_size = parameter_types.size();
size_t callee_size = result->signature().types().size();
if (caller_size != callee_size &&
!result->signature().parameter_types.var_args) {
std::stringstream stream;
stream << "parameter count mismatch calling " << *result << ": expected "
<< std::to_string(callee_size) << ", found "
<< std::to_string(caller_size);
ReportError(stream.str());
}
return result;
}
Macro* LookupMacro(SourcePosition pos, const std::string& name,
const TypeVector& types) {
Declarable* declarable = global_context_.Lookup(name);
if (declarable != nullptr) {
if (declarable->IsMacroList()) {
for (auto& m : MacroList::cast(declarable)->list()) {
if (m->signature().parameter_types.types == types &&
!m->signature().parameter_types.var_args) {
return m.get();
}
}
}
}
std::stringstream stream;
stream << "macro " << name << " with parameter types " << types
<< " referenced at " << PositionAsString(pos) << " is not defined";
ReportError(stream.str());
return nullptr;
}
Builtin* LookupBuiltin(const SourcePosition& pos, const std::string& name) {
Declarable* declarable = global_context_.Lookup(name);
if (declarable != nullptr) {
if (declarable->IsBuiltin()) {
return Builtin::cast(declarable);
}
ReportError(name + " referenced at " + PositionAsString(pos) +
" is not a builtin");
}
ReportError(std::string("builtin ") + name + " referenced at " +
PositionAsString(pos) + " is not defined");
return nullptr;
}
std::string GetParameterVariableFromName(const std::string& name) { std::string GetParameterVariableFromName(const std::string& name) {
return std::string("p_") + name; return std::string("p_") + name;
} }
std::string PositionAsString(SourcePosition pos) { std::string PositionAsString(SourcePosition pos) {
return global_context_.PositionAsString(pos); return global_context_.ast()->source_file_map()->PositionAsString(pos);
} }
Signature MakeSignature(const ParameterList& parameters, Callable* LookupCall(SourcePosition pos, const std::string& name,
const TypeVector& parameter_types);
Signature MakeSignature(SourcePosition pos, const ParameterList& parameters,
const std::string& return_type, const std::string& return_type,
const LabelAndTypesVector& labels); const LabelAndTypesVector& labels);
GlobalContext& global_context_; GlobalContext& global_context_;
Declarations* declarations_;
Callable* current_callable_; Callable* current_callable_;
Module* module_; Module* module_;
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/torque/TorqueLexer.h" #include "src/torque/TorqueLexer.h"
#include "src/torque/TorqueParser.h" #include "src/torque/TorqueParser.h"
#include "src/torque/declarable.h" #include "src/torque/declarable.h"
#include "src/torque/declarations.h"
#include "src/torque/scope.h" #include "src/torque/scope.h"
#include "src/torque/type-oracle.h" #include "src/torque/type-oracle.h"
...@@ -21,19 +22,15 @@ class TypeOracle; ...@@ -21,19 +22,15 @@ class TypeOracle;
class Module { class Module {
public: public:
Module(const std::string& name, GlobalContext& context) : name_(name) { explicit Module(const std::string& name) : name_(name) {}
scope_ = new Scope(context);
}
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
std::ostream& source_stream() { return source_stream_; } std::ostream& source_stream() { return source_stream_; }
std::ostream& header_stream() { return header_stream_; } std::ostream& header_stream() { return header_stream_; }
std::string source() { return source_stream_.str(); } std::string source() { return source_stream_.str(); }
std::string header() { return header_stream_.str(); } std::string header() { return header_stream_.str(); }
Scope* scope() { return scope_; }
private: private:
std::string name_; std::string name_;
Scope* scope_;
std::stringstream header_stream_; std::stringstream header_stream_;
std::stringstream source_stream_; std::stringstream source_stream_;
}; };
...@@ -66,8 +63,9 @@ class GlobalContext { ...@@ -66,8 +63,9 @@ class GlobalContext {
public: public:
explicit GlobalContext(Ast ast) explicit GlobalContext(Ast ast)
: verbose_(false), : verbose_(false),
next_scope_number_(0),
next_label_number_(0), next_label_number_(0),
declarations_(ast.source_file_map()),
type_oracle_(&declarations_),
default_module_(GetModule("base")), default_module_(GetModule("base")),
ast_(std::move(ast)) {} ast_(std::move(ast)) {}
Module* GetDefaultModule() { return default_module_; } Module* GetDefaultModule() { return default_module_; }
...@@ -76,55 +74,17 @@ class GlobalContext { ...@@ -76,55 +74,17 @@ class GlobalContext {
if (i != modules_.end()) { if (i != modules_.end()) {
return i->second.get(); return i->second.get();
} }
Module* module = new Module(name, *this); Module* module = new Module(name);
modules_[name] = std::unique_ptr<Module>(module); modules_[name] = std::unique_ptr<Module>(module);
return module; return module;
} }
int GetNextScopeNumber() { return next_scope_number_++; }
int GetNextLabelNumber() { return next_label_number_++; } int GetNextLabelNumber() { return next_label_number_++; }
const std::map<std::string, std::unique_ptr<Module>>& GetModules() const { const std::map<std::string, std::unique_ptr<Module>>& GetModules() const {
return modules_; return modules_;
} }
Scope* GetParserRuleContextScope(const AstNode* context) {
auto i = context_scopes_.find(context);
if (i != context_scopes_.end()) return i->second;
Scope* new_scope = new Scope(*this);
context_scopes_[context] = new_scope;
return new_scope;
}
Scope* TopScope() const { return current_scopes_.back(); }
Declarable* Lookup(const std::string& name) const {
auto e = current_scopes_.rend();
auto c = current_scopes_.rbegin();
while (c != e) {
Declarable* result = (*c)->Lookup(name);
if (result != nullptr) return result;
++c;
}
return nullptr;
}
void RegisterScope(Scope* scope) {
scopes_.emplace_back(std::unique_ptr<Scope>(scope));
}
void PushScope(Scope* scope) { current_scopes_.push_back(scope); }
void PopScope() { current_scopes_.pop_back(); }
std::set<const Variable*> GetLiveTypeVariables() {
std::set<const Variable*> result;
for (auto scope : current_scopes_) {
scope->AddLiveVariables(result);
}
return result;
}
void SetVerbose() { verbose_ = true; } void SetVerbose() { verbose_ = true; }
bool verbose() const { return verbose_; } bool verbose() const { return verbose_; }
...@@ -144,7 +104,7 @@ class GlobalContext { ...@@ -144,7 +104,7 @@ class GlobalContext {
control_split_changed_variables_[node].insert(var); control_split_changed_variables_[node].insert(var);
} }
friend class CurrentCallActivator; friend class CurrentCallableActivator;
friend class BreakContinueActivator; friend class BreakContinueActivator;
TypeOracle& GetTypeOracle() { return type_oracle_; } TypeOracle& GetTypeOracle() { return type_oracle_; }
...@@ -157,45 +117,39 @@ class GlobalContext { ...@@ -157,45 +117,39 @@ class GlobalContext {
std::map<std::string, std::vector<OperationHandler>> op_handlers_; std::map<std::string, std::vector<OperationHandler>> op_handlers_;
void PrintScopeChain() {
for (auto s : current_scopes_) {
s->Print();
}
}
std::string PositionAsString(SourcePosition pos) { std::string PositionAsString(SourcePosition pos) {
return ast_.PositionAsString(pos); return declarations()->PositionAsString(pos);
} }
Declarations* declarations() { return &declarations_; }
Ast* ast() { return &ast_; } Ast* ast() { return &ast_; }
private: private:
bool verbose_; bool verbose_;
int next_scope_number_;
int next_label_number_; int next_label_number_;
Declarations declarations_;
TypeOracle type_oracle_;
std::map<std::string, std::unique_ptr<Module>> modules_; std::map<std::string, std::unique_ptr<Module>> modules_;
std::vector<std::unique_ptr<Scope>> scopes_;
Module* default_module_; Module* default_module_;
std::vector<Scope*> current_scopes_;
std::vector<std::pair<Label*, Label*>> break_continue_stack_; std::vector<std::pair<Label*, Label*>> break_continue_stack_;
TypeOracle type_oracle_;
Callable* current_callable_; Callable* current_callable_;
std::map<const AstNode*, std::set<const Variable*>> std::map<const AstNode*, std::set<const Variable*>>
control_split_changed_variables_; control_split_changed_variables_;
std::map<const AstNode*, Scope*> context_scopes_;
Ast ast_; Ast ast_;
}; };
class CurrentCallActivator { class CurrentCallableActivator {
public: public:
CurrentCallActivator(GlobalContext& context, Callable* callable) CurrentCallableActivator(GlobalContext& context, Callable* callable,
: context_(context) { Declaration* decl)
: context_(context), scope_activator_(context.declarations(), decl) {
context_.current_callable_ = callable; context_.current_callable_ = callable;
} }
~CurrentCallActivator() { context_.current_callable_ = nullptr; } ~CurrentCallableActivator() { context_.current_callable_ = nullptr; }
private: private:
GlobalContext& context_; GlobalContext& context_;
Declarations::NodeScopeActivator scope_activator_;
}; };
class BreakContinueActivator { class BreakContinueActivator {
......
This diff is collapsed.
...@@ -30,7 +30,7 @@ class ImplementationVisitor : public FileVisitor { ...@@ -30,7 +30,7 @@ class ImplementationVisitor : public FileVisitor {
explicit ImplementationVisitor(GlobalContext& global_context) explicit ImplementationVisitor(GlobalContext& global_context)
: FileVisitor(global_context), indent_(0), next_temp_(0) {} : FileVisitor(global_context), indent_(0), next_temp_(0) {}
void Visit(Ast* ast) { Visit(ast->GetDefaultModule()); } void Visit(Ast* ast) { Visit(ast->default_module()); }
VisitResult Visit(Expression* expr); VisitResult Visit(Expression* expr);
Type Visit(Statement* stmt); Type Visit(Statement* stmt);
...@@ -38,7 +38,8 @@ class ImplementationVisitor : public FileVisitor { ...@@ -38,7 +38,8 @@ class ImplementationVisitor : public FileVisitor {
LocationReference GetLocationReference(LocationExpression* location); LocationReference GetLocationReference(LocationExpression* location);
LocationReference GetLocationReference(IdentifierExpression* expr) { LocationReference GetLocationReference(IdentifierExpression* expr) {
return LocationReference(LookupValue(expr->pos, expr->name), {}, {}); return LocationReference(declarations()->LookupValue(expr->pos, expr->name),
{}, {});
} }
LocationReference GetLocationReference(FieldAccessExpression* expr) { LocationReference GetLocationReference(FieldAccessExpression* expr) {
return LocationReference({}, Visit(expr->object), {}); return LocationReference({}, Visit(expr->object), {});
......
...@@ -14,147 +14,37 @@ namespace v8 { ...@@ -14,147 +14,37 @@ namespace v8 {
namespace internal { namespace internal {
namespace torque { namespace torque {
Scope::Scope(GlobalContext& global_context) Scope::Scope(ScopeChain& scope_chain)
: global_context_(global_context), : scope_chain_(scope_chain),
scope_number_(global_context.GetNextScopeNumber()), scope_number_(scope_chain_.GetNextScopeNumber()),
private_label_number_(0) { private_label_number_(0) {}
global_context.RegisterScope(this);
}
Macro* Scope::DeclareMacro(SourcePosition pos, const std::string& name,
Scope* scope, const Signature& signature) {
auto i = lookup_.find(name);
if (i == lookup_.end()) {
lookup_[name] = std::unique_ptr<MacroList>(new MacroList());
i = lookup_.find(name);
} else if (i->second->kind() != Declarable::kMacroList) {
std::stringstream s;
s << "cannot redeclare " << name << " as a non-macro at "
<< global_context_.PositionAsString(pos);
ReportError(s.str());
}
MacroList* macro_list = MacroList::cast(i->second.get());
for (auto& macro : macro_list->list()) {
if (signature.parameter_types.types ==
macro->signature().parameter_types.types &&
signature.parameter_types.var_args ==
macro->signature().parameter_types.var_args) {
std::stringstream s;
s << "cannot redeclare " << name
<< " as a macro with identical parameter list "
<< signature.parameter_types << global_context_.PositionAsString(pos);
ReportError(s.str());
}
}
Macro* result = macro_list->AddMacro(
std::unique_ptr<Macro>(new Macro(name, scope, signature)));
if (global_context_.verbose()) {
std::cout << "declared " << *result << "\n";
}
return result;
}
Builtin* Scope::DeclareBuiltin(SourcePosition pos, const std::string& name,
Builtin::Kind kind, Scope* scope,
const Signature& signature) {
CheckAlreadyDeclared(pos, name, "builtin");
Builtin* result = new Builtin(name, kind, scope, signature);
lookup_[name] = std::unique_ptr<Builtin>(result);
if (global_context_.verbose()) {
std::cout << "declared " << *result << "\n";
}
return result;
}
Runtime* Scope::DeclareRuntime(SourcePosition pos, const std::string& name,
Scope* scope, const Signature& signature) {
CheckAlreadyDeclared(pos, name, "runtime");
Runtime* result = new Runtime(name, scope, signature);
lookup_[name] = std::unique_ptr<Runtime>(result);
if (global_context_.verbose()) {
std::cout << "declared " << *result << "\n";
}
return result;
}
Variable* Scope::DeclareVariable(SourcePosition pos, const std::string& var, Scope* ScopeChain::NewScope() {
Type type) { Scope* new_scope = new Scope(*this);
std::string name(std::string("v") + "_" + var + scopes_.emplace_back(std::unique_ptr<Scope>(new_scope));
std::to_string(scope_number_)); return new_scope;
CheckAlreadyDeclared(pos, var, "variable");
Variable* result = new Variable(var, name, type);
lookup_[var] = std::unique_ptr<Variable>(result);
if (global_context_.verbose()) {
std::cout << "declared " << var << " (type " << type << ")\n";
}
return result;
}
Parameter* Scope::DeclareParameter(SourcePosition pos, const std::string& name,
const std::string& var_name, Type type) {
CheckAlreadyDeclared(pos, name, "parameter");
Parameter* result = new Parameter(name, type, var_name);
lookup_[name] = std::unique_ptr<Parameter>(result);
return result;
}
Label* Scope::DeclareLabel(SourcePosition pos, const std::string& name) {
CheckAlreadyDeclared(pos, name, "label");
Label* result = new Label(name);
lookup_[name] = std::unique_ptr<Label>(result);
return result;
}
Label* Scope::DeclarePrivateLabel(SourcePosition pos,
const std::string& raw_name) {
std::string name = raw_name + "_" + std::to_string(private_label_number_++);
CheckAlreadyDeclared(pos, name, "label");
Label* result = new Label(name);
lookup_[name] = std::unique_ptr<Label>(result);
return result;
}
void Scope::DeclareConstant(SourcePosition pos, const std::string& name,
Type type, const std::string& value) {
CheckAlreadyDeclared(pos, name, "constant, parameter or arguments");
lookup_[name] = std::unique_ptr<Constant>(new Constant(name, type, value));
} }
void Scope::AddLiveVariables(std::set<const Variable*>& set) { void Scope::AddLiveVariables(std::set<const Variable*>& set) {
for (auto& current : lookup_) { for (auto& current : lookup_) {
if (current.second->IsVariable()) { if (current.second->IsVariable()) {
set.insert(Variable::cast(current.second.get())); set.insert(Variable::cast(current.second));
}
} }
}
void Scope::CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
const char* new_type) {
auto i = lookup_.find(name);
if (i != lookup_.end()) {
std::stringstream s;
s << "cannot redeclare " << name << " (type " << new_type << ") at "
<< global_context_.PositionAsString(pos)
<< " (it's already declared as a " << i->second->type_name() << ")\n";
ReportError(s.str());
} }
} }
void Scope::Print() { void Scope::Print() {
std::cout << "scope #" << std::to_string(scope_number_) << "\n"; std::cout << "scope #" << std::to_string(scope_number_) << "\n";
for (auto& i : lookup_) { for (auto& i : lookup_) {
std::cout << i.first << ": " << i.second.get() << "\n"; std::cout << i.first << ": " << i.second << "\n";
} }
} }
Scope::Activator::Activator(Scope* scope) : scope_(scope) { Scope::Activator::Activator(Scope* scope) : scope_(scope) {
scope->global_context().PushScope(scope); scope->GetScopeChain().PushScope(scope);
} }
Scope::Activator::Activator(GlobalContext& global_context, const AstNode* node) Scope::Activator::~Activator() { scope_->GetScopeChain().PopScope(); }
: Activator(global_context.GetParserRuleContextScope(node)) {}
Scope::Activator::~Activator() { scope_->global_context().PopScope(); }
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
......
...@@ -16,49 +16,11 @@ namespace v8 { ...@@ -16,49 +16,11 @@ namespace v8 {
namespace internal { namespace internal {
namespace torque { namespace torque {
class Builtin; class ScopeChain;
class Callable;
class Declarable;
class GlobalContext;
class Macro;
class Parameter;
class Runtime;
class Variable;
class Scope { class Scope {
public: public:
explicit Scope(GlobalContext& global_context); explicit Scope(ScopeChain& scope_chain);
Macro* DeclareMacro(SourcePosition pos, const std::string& name, Scope* scope,
const Signature& signature);
Builtin* DeclareBuiltin(SourcePosition pos, const std::string& name,
Builtin::Kind kind, Scope* scope,
const Signature& signature);
Runtime* DeclareRuntime(SourcePosition pos, const std::string& name,
Scope* scope, const Signature& signature);
Variable* DeclareVariable(SourcePosition pos, const std::string& var,
Type type);
Parameter* DeclareParameter(SourcePosition pos, const std::string& name,
const std::string& mangled_name, Type type);
Label* DeclareLabel(SourcePosition pos, const std::string& name);
Label* DeclarePrivateLabel(SourcePosition pos, const std::string& name);
void DeclareConstant(SourcePosition pos, const std::string& name, Type type,
const std::string& value);
Declarable* Lookup(const std::string& name) {
auto i = lookup_.find(name);
if (i == lookup_.end()) {
return nullptr;
}
return i->second.get();
}
void Stream(std::ostream& stream) const { void Stream(std::ostream& stream) const {
stream << "scope " << std::to_string(scope_number_) << " {"; stream << "scope " << std::to_string(scope_number_) << " {";
...@@ -68,7 +30,9 @@ class Scope { ...@@ -68,7 +30,9 @@ class Scope {
stream << "}"; stream << "}";
} }
GlobalContext& global_context() const { return global_context_; } int scope_number() const { return scope_number_; }
ScopeChain& GetScopeChain() const { return scope_chain_; }
void AddLiveVariables(std::set<const Variable*>& set); void AddLiveVariables(std::set<const Variable*>& set);
...@@ -77,18 +41,33 @@ class Scope { ...@@ -77,18 +41,33 @@ class Scope {
class Activator; class Activator;
private: private:
friend class ScopeChain;
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name, void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
const char* new_type); const char* new_type);
GlobalContext& global_context_; void Declare(const std::string& name, Declarable* d) {
DCHECK_EQ(lookup_.end(), lookup_.find(name));
DCHECK(d != nullptr);
lookup_[name] = d;
}
Declarable* Lookup(const std::string& name) {
auto i = lookup_.find(name);
if (i == lookup_.end()) {
return nullptr;
}
return i->second;
}
ScopeChain& scope_chain_;
int scope_number_; int scope_number_;
int private_label_number_; int private_label_number_;
std::map<std::string, std::unique_ptr<Declarable>> lookup_; std::map<std::string, Declarable*> lookup_;
}; };
class Scope::Activator { class Scope::Activator {
public: public:
explicit Activator(GlobalContext& global_context, const AstNode* node);
explicit Activator(Scope* scope); explicit Activator(Scope* scope);
~Activator(); ~Activator();
...@@ -96,6 +75,59 @@ class Scope::Activator { ...@@ -96,6 +75,59 @@ class Scope::Activator {
Scope* scope_; Scope* scope_;
}; };
class ScopeChain {
public:
ScopeChain() : next_scope_number_(0) {}
Scope* NewScope();
Scope* TopScope() const { return current_scopes_.back(); }
void PushScope(Scope* scope) { current_scopes_.push_back(scope); }
void PopScope() { current_scopes_.pop_back(); }
std::set<const Variable*> GetLiveVariables() {
std::set<const Variable*> result;
for (auto scope : current_scopes_) {
scope->AddLiveVariables(result);
}
return result;
}
void Declare(const std::string& name, Declarable* d) {
TopScope()->Declare(name, d);
}
Declarable* Lookup(const std::string& name) {
auto e = current_scopes_.rend();
auto c = current_scopes_.rbegin();
while (c != e) {
Declarable* result = (*c)->Lookup(name);
if (result != nullptr) return result;
++c;
}
return nullptr;
}
Declarable* ShallowLookup(const std::string& name) {
auto& e = current_scopes_.back();
return e->Lookup(name);
}
void Print() {
for (auto s : current_scopes_) {
s->Print();
}
}
private:
friend class Scope;
int GetNextScopeNumber() { return next_scope_number_++; }
int next_scope_number_;
std::vector<std::unique_ptr<Scope>> scopes_;
std::vector<Scope*> current_scopes_;
};
inline std::ostream& operator<<(std::ostream& os, const Scope& scope) { inline std::ostream& operator<<(std::ostream& os, const Scope& scope) {
scope.Stream(os); scope.Stream(os);
return os; return os;
......
...@@ -86,6 +86,7 @@ int WrappedMain(int argc, const char** argv) { ...@@ -86,6 +86,7 @@ int WrappedMain(int argc, const char** argv) {
if (output_directory.length() != 0) { if (output_directory.length() != 0) {
{ {
DeclarationVisitor visitor(global_context); DeclarationVisitor visitor(global_context);
visitor.Visit(global_context.ast()); visitor.Visit(global_context.ast());
std::string output_header_path = output_directory; std::string output_header_path = output_directory;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef V8_TORQUE_TYPE_ORACLE_H_ #ifndef V8_TORQUE_TYPE_ORACLE_H_
#define V8_TORQUE_TYPE_ORACLE_H_ #define V8_TORQUE_TYPE_ORACLE_H_
#include "src/torque/declarable.h"
#include "src/torque/declarations.h"
#include "src/torque/types.h" #include "src/torque/types.h"
#include "src/torque/utils.h" #include "src/torque/utils.h"
...@@ -14,62 +16,28 @@ namespace torque { ...@@ -14,62 +16,28 @@ namespace torque {
class TypeOracle { class TypeOracle {
public: public:
void RegisterTypeImpl(const std::string& name, const std::string& generated, explicit TypeOracle(Declarations* declarations)
const std::string* parent = nullptr) { : declarations_(declarations) {}
TypeImpl* parent_class = nullptr;
if (type_impls_.find(name) != type_impls_.end()) {
ReportError(std::string("cannot redefine type class ") + name);
}
if (parent != nullptr) {
auto i = type_impls_.find(*parent);
if (i == type_impls_.end()) {
std::stringstream s;
s << "cannot find parent type class " << *parent << " for " << name;
ReportError(s.str());
}
parent_class = i->second.get();
}
TypeImpl* new_class = new TypeImpl(parent_class, name, generated);
type_impls_[name] = std::unique_ptr<TypeImpl>(new_class);
}
void RegisterImplicitConversion(Type to, Type from) { void RegisterImplicitConversion(Type to, Type from) {
implicit_conversions_.push_back(std::make_pair(to, from)); implicit_conversions_.push_back(std::make_pair(to, from));
} }
Type GetType(const std::string& type_name) { Type GetArgumentsType() { return GetBuiltinType(ARGUMENTS_TYPE_STRING); }
auto i = type_impls_.find(type_name);
if (i == type_impls_.end()) {
std::stringstream s;
s << "no type class found for type " << type_name;
ReportError(s.str());
}
return Type(i->second.get());
}
Type GetArgumentsType() { return GetType(ARGUMENTS_TYPE_STRING); }
Type GetTaggedType() { return GetType(TAGGED_TYPE_STRING); } Type GetBitType() { return GetBuiltinType(BIT_TYPE_STRING); }
Type GetExceptionType() { return GetType(EXCEPTION_TYPE_STRING); } Type GetVoidType() { return GetBuiltinType(VOID_TYPE_STRING); }
Type GetBranchType() { return GetType(BRANCH_TYPE_STRING); } Type GetObjectType() { return GetBuiltinType(OBJECT_TYPE_STRING); }
Type GetBitType() { return GetType(BIT_TYPE_STRING); } Type GetStringType() { return GetBuiltinType(STRING_TYPE_STRING); }
Type GetVoidType() { return GetType(VOID_TYPE_STRING); } Type GetIntPtrType() { return GetBuiltinType(INTPTR_TYPE_STRING); }
Type GetObjectType() { return GetType(OBJECT_TYPE_STRING); } Type GetNeverType() { return GetBuiltinType(NEVER_TYPE_STRING); }
Type GetStringType() { return GetType(STRING_TYPE_STRING); } Type GetConstInt31Type() { return GetBuiltinType(CONST_INT31_TYPE_STRING); }
Type GetIntPtrType() { return GetType(INTPTR_TYPE_STRING); }
Type GetNeverType() { return GetType(NEVER_TYPE_STRING); }
Type GetConstInt31Type() { return GetType(CONST_INT31_TYPE_STRING); }
bool IsException(Type from) { return GetExceptionType().IsSubclass(from); }
bool IsAssignableFrom(Type to, Type from) { bool IsAssignableFrom(Type to, Type from) {
if (to.IsSubclass(from)) return true; if (to.IsSubclass(from)) return true;
...@@ -99,7 +67,13 @@ class TypeOracle { ...@@ -99,7 +67,13 @@ class TypeOracle {
} }
private: private:
std::map<std::string, std::unique_ptr<TypeImpl>> type_impls_; Type GetBuiltinType(const std::string& name) {
Declarable* declarable = declarations_->Lookup(name);
DCHECK(declarable != nullptr);
return Type(TypeImpl::cast(declarable));
}
Declarations* declarations_;
std::vector<std::pair<Type, Type>> implicit_conversions_; std::vector<std::pair<Type, Type>> implicit_conversions_;
}; };
......
...@@ -5,12 +5,38 @@ ...@@ -5,12 +5,38 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "src/torque/declarable.h"
#include "src/torque/types.h" #include "src/torque/types.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace torque { 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) { std::ostream& operator<<(std::ostream& os, const Signature& sig) {
os << "("; os << "(";
for (size_t i = 0; i < sig.parameter_names.size(); ++i) { for (size_t i = 0; i < sig.parameter_names.size(); ++i) {
......
...@@ -31,21 +31,7 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "const_float64"; ...@@ -31,21 +31,7 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "const_float64";
class Label; class Label;
struct Type; class TypeImpl;
class TypeImpl {
public:
TypeImpl(TypeImpl* parent, const std::string& name,
const std::string& generated_type)
: parent_(parent), name_(name), generated_type_(generated_type) {}
TypeImpl* parent() const { return parent_; }
const std::string& name() const { return name_; }
const std::string& generated_type() const { return generated_type_; }
private:
TypeImpl* parent_;
std::string name_;
std::string generated_type_;
};
typedef struct Type { typedef struct Type {
public: public:
...@@ -54,17 +40,9 @@ typedef struct Type { ...@@ -54,17 +40,9 @@ typedef struct Type {
bool operator==(const Type& other) const { return impl_ == other.impl_; } bool operator==(const Type& other) const { return impl_ == other.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 Type& other) const { return impl_ == other.impl_; }
bool Is(const std::string& name) const { return name == impl_->name(); } bool Is(const std::string& name) const;
bool IsSubclass(Type from) { bool 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;
}
bool IsException() const { return name() == EXCEPTION_TYPE_STRING; } bool IsException() const { return name() == EXCEPTION_TYPE_STRING; }
bool IsVoid() const { return name() == VOID_TYPE_STRING; } bool IsVoid() const { return name() == VOID_TYPE_STRING; }
...@@ -72,17 +50,11 @@ typedef struct Type { ...@@ -72,17 +50,11 @@ typedef struct Type {
bool IsBit() const { return name() == BIT_TYPE_STRING; } bool IsBit() const { return name() == BIT_TYPE_STRING; }
bool IsVoidOrNever() const { return IsVoid() || IsNever(); } bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
const std::string& name() const { return impl_->name(); } const std::string& name() const;
const std::string& GetGeneratedTypeName() const { const std::string& GetGeneratedTypeName() const;
return type_impl()->generated_type();
}
std::string GetGeneratedTNodeTypeName() const { std::string GetGeneratedTNodeTypeName() const;
std::string result = type_impl()->generated_type();
result = result.substr(6, result.length() - 7);
return result;
}
protected: protected:
TypeImpl* type_impl() const { return impl_; } TypeImpl* type_impl() const { return impl_; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment