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) {
"src/torque/declarable.h",
"src/torque/declaration-visitor.cc",
"src/torque/declaration-visitor.h",
"src/torque/declarations.cc",
"src/torque/declarations.h",
"src/torque/file-visitor.cc",
"src/torque/file-visitor.h",
"src/torque/global-context.h",
......
......@@ -134,8 +134,8 @@ extern operator '>' macro Int32GreaterThan(int32, int32): bit;
extern operator '<=' macro Int32LessThanOrEqual(int32, int32): bit;
extern operator '>=' macro Int32GreaterThanOrEqual(int32, int32): bit;
extern operator '==' macro WordEqual(Smi, Smi): bit;
extern operator '!=' macro WordNotEqual(Smi, Smi): bit;
extern operator '==' macro SmiEqual(Smi, Smi): bit;
extern operator '!=' macro SmiNotEqual(Smi, Smi): bit;
extern operator '<' macro SmiLessThan(Smi, Smi): bit;
extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bit;
extern operator '>' macro SmiGreaterThan(Smi, Smi): bit;
......@@ -189,7 +189,7 @@ extern operator '.length' macro LoadStringLengthAsWord(String): intptr;
extern operator '.length' macro GetArgumentsLength(Arguments): intptr;
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 'isnt<Smi>' macro TaggedIsNotSmi(Object): bit;
......@@ -209,12 +209,9 @@ extern operator 'cast<>' macro ConvertFixedArrayBaseToFixedDoubleArray(
extern implicit operator
'convert<>' macro AllocateHeapNumberWithValue(const_float64): Number;
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_int32): int32;
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_int32): Number;
extern operator 'convert<>' macro ChangeInt32ToTagged(int32): Number;
extern operator 'convert<>' macro TruncateWordToWord32(intptr): int32;
......
......@@ -11579,8 +11579,8 @@ TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
return args->GetOptionalArgumentValue(index);
}
TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
TNode<Smi> index) {
TNode<Object> CodeStubAssembler::GetArgumentValueSmiIndex(
CodeStubArguments* args, TNode<Smi> index) {
return args->GetOptionalArgumentValue(SmiUntag(index));
}
......
......@@ -2239,7 +2239,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args);
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
void Print(const char* s);
......
......@@ -14,6 +14,7 @@ namespace torque {
namespace {
std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
if (!context) return "";
if (!context->type()) return "void";
return context->type()->IDENTIFIER()->getSymbol()->getText();
}
......@@ -21,15 +22,18 @@ std::string GetOptionalType(TorqueParser::OptionalTypeContext* context) {
LabelAndTypesVector GetOptionalLabelAndTypeList(
TorqueParser::OptionalLabelListContext* context) {
LabelAndTypesVector labels;
for (auto label : context->labelParameter()) {
LabelAndTypes new_label;
new_label.name = label->IDENTIFIER()->getSymbol()->getText();
if (label->typeList() != nullptr) {
for (auto& type : label->typeList()->type()) {
new_label.types.push_back(type->IDENTIFIER()->getSymbol()->getText());
if (context) {
for (auto label : context->labelParameter()) {
LabelAndTypes new_label;
new_label.name = label->IDENTIFIER()->getSymbol()->getText();
if (label->typeList() != nullptr) {
for (auto& type : label->typeList()->type()) {
new_label.types.emplace_back(
type->IDENTIFIER()->getSymbol()->getText());
}
}
labels.emplace_back(new_label);
}
labels.push_back(new_label);
}
return labels;
}
......@@ -67,6 +71,21 @@ std::string StringLiteralUnquote(const std::string& s) {
} // 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(
TorqueParser::ParameterListContext* context) {
ParameterList result{{}, {}, context->VARARGS(), {}};
......@@ -117,7 +136,7 @@ antlrcpp::Any AstGenerator::visitMacroDeclaration(
TorqueParser::MacroDeclarationContext* context) {
return base::implicit_cast<Declaration*>(RegisterNode(new MacroDeclaration{
Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
std::move(context->parameterList()->accept(this).as<ParameterList>()),
GetOptionalParameterList(context->parameterList()),
GetOptionalType(context->optionalType()),
GetOptionalLabelAndTypeList(context->optionalLabelList()),
context->helperBody()->accept(this).as<Statement*>()}));
......@@ -588,9 +607,7 @@ antlrcpp::Any AstGenerator::visitConditionalExpression(
return base::implicit_cast<Expression*>(
RegisterNode(new ConditionalExpression{
Pos(context), condition->accept(this).as<Expression*>(),
context->logicalORExpression(0)->accept(this).as<Expression*>(),
context->logicalORExpression(1)->accept(this).as<Expression*>()}));
}
return context->logicalORExpression(0)->accept(this);
......
......@@ -148,6 +148,11 @@ class AstGenerator : public TorqueBaseVisitor {
return node;
}
ParameterList GetOptionalParameterList(
TorqueParser::ParameterListContext* context);
Statement* GetOptionalHelperBody(TorqueParser::HelperBodyContext* context);
void visitSourceFile(SourceFileContext* context);
SourcePosition Pos(antlr4::ParserRuleContext* context);
......
......@@ -158,9 +158,32 @@ struct ExplicitModuleDeclaration : ModuleDeclaration {
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 {
public:
Ast() : default_module_{SourcePosition(), {}} {}
Ast()
: default_module_{SourcePosition(), {}},
source_file_map_(new SourceFileMap()) {}
std::vector<Declaration*>& declarations() {
return default_module_.declarations;
......@@ -172,21 +195,14 @@ class Ast {
nodes_.emplace_back(std::move(node));
}
SourceId AddSource(std::string path) {
sources_.push_back(std::move(path));
return static_cast<SourceId>(sources_.size() - 1);
}
const std::string& GetSource(SourceId id) const {
return sources_[static_cast<int>(id)];
return source_file_map_->AddSource(path);
}
std::string PositionAsString(SourcePosition pos) {
return GetSource(pos.source) + ":" + std::to_string(pos.line) + ":" +
std::to_string(pos.column);
}
DefaultModuleDeclaration* GetDefaultModule() { return &default_module_; }
DefaultModuleDeclaration* default_module() { return &default_module_; }
SourceFileMap* source_file_map() { return &*source_file_map_; }
private:
DefaultModuleDeclaration default_module_;
std::vector<std::string> sources_;
std::unique_ptr<SourceFileMap> source_file_map_;
std::vector<std::unique_ptr<AstNode>> nodes_;
};
......
......@@ -5,6 +5,7 @@
#ifndef V8_TORQUE_DECLARABLE_H_
#define V8_TORQUE_DECLARABLE_H_
#include <cassert>
#include <string>
#include "src/base/logging.h"
......@@ -16,25 +17,28 @@ namespace internal {
namespace torque {
class Scope;
class ScopeChain;
class Declarable {
public:
virtual ~Declarable() {}
enum Kind {
kVariable = 0,
kTypeImpl,
kVariable,
kParameter,
kMacro,
kMacroList,
kBuiltin,
kRuntime,
kRuntimeFunction,
kLabel,
kConstant
};
explicit Declarable(Kind kind) : kind_(kind) {}
Kind kind() const { return kind_; }
bool IsTypeImpl() const { return kind() == kTypeImpl; }
bool IsMacro() const { return kind() == kMacro; }
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 IsLabel() const { return kind() == kLabel; }
bool IsVariable() const { return kind() == kVariable; }
......@@ -60,6 +64,25 @@ class Declarable {
} \
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 {
public:
const std::string& name() const { return name_; }
......@@ -87,7 +110,7 @@ class Parameter : public Value {
std::string GetValueForDeclaration() const override { return var_name_; }
private:
friend class Scope;
friend class Declarations;
Parameter(const std::string& name, Type type, const std::string& var_name)
: Value(Declarable::kParameter, type, name), var_name_(var_name) {}
......@@ -107,7 +130,7 @@ class Variable : public Value {
bool IsDefined() const { return defined_; }
private:
friend class Scope;
friend class Declarations;
Variable(const std::string& name, const std::string& value, Type type)
: Value(Declarable::kVariable, type, name),
value_(value),
......@@ -131,7 +154,7 @@ class Label : public Value {
bool IsUsed() const { return used_; }
private:
friend class Scope;
friend class Declarations;
explicit Label(const std::string& name)
: Value(Declarable::kLabel, Type(),
"label_" + name + "_" + std::to_string(next_id_++)),
......@@ -150,7 +173,7 @@ class Constant : public Value {
std::string GetValueForDeclaration() const override { return value_; }
private:
friend class Scope;
friend class Declarations;
explicit Constant(const std::string& name, Type type,
const std::string& value)
: Value(Declarable::kConstant, type, name), value_(value) {}
......@@ -162,15 +185,14 @@ class Callable : public Declarable {
public:
static Callable* cast(Declarable* declarable) {
assert(declarable->IsMacro() || declarable->IsBuiltin() ||
declarable->IsRuntime());
declarable->IsRuntimeFunction());
return static_cast<Callable*>(declarable);
}
static const Callable* cast(const Declarable* declarable) {
assert(declarable->IsMacro() || declarable->IsBuiltin() ||
declarable->IsRuntime());
declarable->IsRuntimeFunction());
return static_cast<const Callable*>(declarable);
}
Scope* scope() const { return scope_; }
const std::string& name() const { return name_; }
const Signature& signature() const { return signature_; }
const NameVector& parameter_names() const {
......@@ -183,17 +205,12 @@ class Callable : public Declarable {
bool HasReturns() const { return returns_; }
protected:
Callable(Declarable::Kind kind, const std::string& name, Scope* scope,
Callable(Declarable::Kind kind, const std::string& name,
const Signature& signature)
: Declarable(kind),
name_(name),
scope_(scope),
signature_(signature),
returns_(0) {}
: Declarable(kind), name_(name), signature_(signature), returns_(0) {}
private:
std::string name_;
Scope* scope_;
Signature signature_;
size_t returns_;
};
......@@ -203,31 +220,30 @@ class Macro : public Callable {
DECLARE_DECLARABLE_BOILERPLATE(Macro, macro);
protected:
Macro(Declarable::Kind type, const std::string& name, Scope* scope,
Macro(Declarable::Kind type, const std::string& name,
const Signature& signature)
: Callable(type, name, scope, signature) {}
: Callable(type, name, signature) {}
private:
friend class Scope;
Macro(const std::string& name, Scope* scope, const Signature& signature)
: Macro(Declarable::kMacro, name, scope, signature) {}
friend class Declarations;
Macro(const std::string& name, const Signature& signature)
: Macro(Declarable::kMacro, name, signature) {}
};
class MacroList : public Declarable {
public:
DECLARE_DECLARABLE_BOILERPLATE(MacroList, macro_list);
const std::vector<std::unique_ptr<Macro>>& list() { return list_; }
Macro* AddMacro(std::unique_ptr<Macro> macro) {
Macro* result = macro.get();
list_.emplace_back(std::move(macro));
return result;
const std::vector<Macro*>& list() { return list_; }
Macro* AddMacro(Macro* macro) {
list_.emplace_back(macro);
return macro;
}
private:
friend class Scope;
friend class Declarations;
MacroList() : Declarable(Declarable::kMacroList) {}
std::vector<std::unique_ptr<Macro>> list_;
std::vector<Macro*> list_;
};
class Builtin : public Callable {
......@@ -240,22 +256,22 @@ class Builtin : public Callable {
bool IsFixedArgsJavaScript() const { return kind_ == kFixedArgsJavaScript; }
private:
friend class Scope;
Builtin(const std::string& name, Builtin::Kind kind, Scope* scope,
friend class Declarations;
Builtin(const std::string& name, Builtin::Kind kind,
const Signature& signature)
: Callable(Declarable::kBuiltin, name, scope, signature), kind_(kind) {}
: Callable(Declarable::kBuiltin, name, signature), kind_(kind) {}
Kind kind_;
};
class Runtime : public Callable {
class RuntimeFunction : public Callable {
public:
DECLARE_DECLARABLE_BOILERPLATE(Runtime, runtime);
DECLARE_DECLARABLE_BOILERPLATE(RuntimeFunction, runtime);
private:
friend class Scope;
Runtime(const std::string& name, Scope* scope, const Signature& signature)
: Callable(Declarable::kRuntime, name, scope, signature) {}
friend class Declarations;
RuntimeFunction(const std::string& name, const Signature& signature)
: Callable(Declarable::kRuntimeFunction, name, signature) {}
};
inline std::ostream& operator<<(std::ostream& os, const Callable& m) {
......@@ -275,8 +291,8 @@ inline std::ostream& operator<<(std::ostream& os, const Builtin& b) {
return os;
}
inline std::ostream& operator<<(std::ostream& os, const Runtime& b) {
os << "runtime " << b.signature().return_type << " " << b.name()
inline std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
os << "runtime function " << b.signature().return_type << " " << b.name()
<< b.signature().parameter_types;
return os;
}
......
......@@ -48,12 +48,21 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
if (global_context_.verbose()) {
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 ||
!signature.types()[0].Is(CONTEXT_TYPE_STRING)) {
std::stringstream stream;
......@@ -66,8 +75,6 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
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) {
std::stringstream stream;
stream << "builtin " << decl->name
......@@ -87,50 +94,31 @@ void DeclarationVisitor::Visit(BuiltinDeclaration* decl) {
}
if (varargs) {
TopScope()->DeclareConstant(decl->pos, decl->parameters.arguments_variable,
GetTypeOracle().GetArgumentsType(),
"arguments");
declarations()->DeclareConstant(
decl->pos, decl->parameters.arguments_variable,
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);
DeclareParameterList(decl->pos, signature, {});
CurrentCallActivator activator(global_context_, builtin);
Visit(decl->body);
}
void DeclarationVisitor::Visit(MacroDeclaration* decl) {
if (global_context_.verbose()) {
std::cout << "found declaration of macro " << decl->name;
}
Scope* enclosing_scope = TopScope();
Scope* new_scope = new Scope(global_context_);
Scope::Activator s(new_scope);
Signature signature = MakeSignature(decl->pos, decl->parameters,
decl->return_type, decl->labels);
PushControlSplit();
Macro* macro = declarations()->DeclareMacro(decl->pos, decl->name, signature);
CurrentCallableActivator activator(global_context_, macro, decl);
Signature signature =
MakeSignature(decl->parameters, decl->return_type, decl->labels);
DeclareParameterList(decl->pos, signature, decl->labels);
if (!signature.return_type.IsVoidOrNever()) {
TopScope()->DeclareVariable(decl->pos, kReturnValueVariable,
signature.return_type);
declarations()->DeclareVariable(decl->pos, kReturnValueVariable,
signature.return_type);
}
if (global_context_.verbose()) {
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);
PushControlSplit();
Visit(decl->body);
auto changed_vars = PopControlSplit();
global_context_.AddControlSplitChangedVariables(decl, changed_vars);
}
......@@ -138,14 +126,14 @@ void DeclarationVisitor::Visit(MacroDeclaration* decl) {
void DeclarationVisitor::Visit(ReturnStatement* stmt) {
const Callable* callable = global_context_.GetCurrentCallable();
if (callable->IsMacro() && callable->HasReturnValue()) {
MarkVariableModified(
Variable::cast(LookupValue(stmt->pos, kReturnValueVariable)));
MarkVariableModified(Variable::cast(
declarations()->LookupValue(stmt->pos, kReturnValueVariable)));
}
}
void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) {
// Scope for for iteration variable
Scope::Activator s(global_context_, stmt);
Declarations::NodeScopeActivator scope(declarations(), stmt);
Visit(stmt->var_declaration);
Visit(stmt->iterable);
if (stmt->begin) Visit(*stmt->begin);
......@@ -160,13 +148,14 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
// Activate a new scope to declare catch handler labels, they should not be
// visible outside the catch.
{
Scope::Activator s(global_context_, stmt);
Declarations::NodeScopeActivator scope(declarations(), stmt);
// Declare catch labels
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) {
std::stringstream stream;
stream << "cannot use ... for label parameters at "
......@@ -176,9 +165,10 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
size_t i = 0;
for (auto p : block->parameters.names) {
shared_label->AddVariable(TopScope()->DeclareVariable(
shared_label->AddVariable(declarations()->DeclareVariable(
stmt->pos, p,
GetTypeOracle().GetType(block->parameters.types[i])));
declarations()->LookupType(stmt->pos,
block->parameters.types[i])));
++i;
}
}
......
This diff is collapsed.
// 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,18 +10,66 @@ namespace v8 {
namespace internal {
namespace torque {
Signature FileVisitor::MakeSignature(const ParameterList& parameters,
Signature FileVisitor::MakeSignature(SourcePosition pos,
const ParameterList& parameters,
const std::string& return_type,
const LabelAndTypesVector& labels) {
LabelDeclarationVector definition_vector;
for (auto label : labels) {
LabelDeclaration def = {label.name, GetTypeVector(label.types)};
LabelDeclaration def = {label.name, GetTypeVector(pos, label.types)};
definition_vector.push_back(def);
}
Signature result{parameters.names,
{GetTypeVector(parameters.types), parameters.has_varargs},
GetType(return_type),
definition_vector};
Signature result{
parameters.names,
{GetTypeVector(pos, parameters.types), parameters.has_varargs},
declarations()->LookupType(pos, return_type),
definition_vector};
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;
}
......
......@@ -22,22 +22,20 @@ class FileVisitor {
public:
explicit FileVisitor(GlobalContext& global_context)
: global_context_(global_context),
module_(global_context.GetDefaultModule()) {
global_context_.PushScope(module_->scope());
}
declarations_(global_context.declarations()),
module_(global_context.GetDefaultModule()) {}
Type GetType(const std::string& s) { return GetTypeOracle().GetType(s); }
TypeVector GetTypeVector(const std::vector<std::string>& v) {
TypeVector GetTypeVector(SourcePosition pos,
const std::vector<std::string>& v) {
TypeVector result;
for (const std::string& s : v) {
result.push_back(GetType(s));
result.push_back(declarations()->LookupType(pos, s));
}
return result;
}
Scope* TopScope() { return global_context_.TopScope(); }
Ast* ast() { return global_context_.ast(); }
Declarations* declarations() { return global_context_.declarations(); }
protected:
static constexpr const char* kTrueLabelName = "True";
......@@ -51,110 +49,23 @@ class FileVisitor {
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) {
return std::string("p_") + name;
}
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 LabelAndTypesVector& labels);
GlobalContext& global_context_;
Declarations* declarations_;
Callable* current_callable_;
Module* module_;
};
......
......@@ -8,6 +8,7 @@
#include "src/torque/TorqueLexer.h"
#include "src/torque/TorqueParser.h"
#include "src/torque/declarable.h"
#include "src/torque/declarations.h"
#include "src/torque/scope.h"
#include "src/torque/type-oracle.h"
......@@ -21,19 +22,15 @@ class TypeOracle;
class Module {
public:
Module(const std::string& name, GlobalContext& context) : name_(name) {
scope_ = new Scope(context);
}
explicit Module(const std::string& name) : name_(name) {}
const std::string& name() const { return name_; }
std::ostream& source_stream() { return source_stream_; }
std::ostream& header_stream() { return header_stream_; }
std::string source() { return source_stream_.str(); }
std::string header() { return header_stream_.str(); }
Scope* scope() { return scope_; }
private:
std::string name_;
Scope* scope_;
std::stringstream header_stream_;
std::stringstream source_stream_;
};
......@@ -66,8 +63,9 @@ class GlobalContext {
public:
explicit GlobalContext(Ast ast)
: verbose_(false),
next_scope_number_(0),
next_label_number_(0),
declarations_(ast.source_file_map()),
type_oracle_(&declarations_),
default_module_(GetModule("base")),
ast_(std::move(ast)) {}
Module* GetDefaultModule() { return default_module_; }
......@@ -76,55 +74,17 @@ class GlobalContext {
if (i != modules_.end()) {
return i->second.get();
}
Module* module = new Module(name, *this);
Module* module = new Module(name);
modules_[name] = std::unique_ptr<Module>(module);
return module;
}
int GetNextScopeNumber() { return next_scope_number_++; }
int GetNextLabelNumber() { return next_label_number_++; }
const std::map<std::string, std::unique_ptr<Module>>& GetModules() const {
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; }
bool verbose() const { return verbose_; }
......@@ -144,7 +104,7 @@ class GlobalContext {
control_split_changed_variables_[node].insert(var);
}
friend class CurrentCallActivator;
friend class CurrentCallableActivator;
friend class BreakContinueActivator;
TypeOracle& GetTypeOracle() { return type_oracle_; }
......@@ -157,45 +117,39 @@ class GlobalContext {
std::map<std::string, std::vector<OperationHandler>> op_handlers_;
void PrintScopeChain() {
for (auto s : current_scopes_) {
s->Print();
}
}
std::string PositionAsString(SourcePosition pos) {
return ast_.PositionAsString(pos);
return declarations()->PositionAsString(pos);
}
Declarations* declarations() { return &declarations_; }
Ast* ast() { return &ast_; }
private:
bool verbose_;
int next_scope_number_;
int next_label_number_;
Declarations declarations_;
TypeOracle type_oracle_;
std::map<std::string, std::unique_ptr<Module>> modules_;
std::vector<std::unique_ptr<Scope>> scopes_;
Module* default_module_;
std::vector<Scope*> current_scopes_;
std::vector<std::pair<Label*, Label*>> break_continue_stack_;
TypeOracle type_oracle_;
Callable* current_callable_;
std::map<const AstNode*, std::set<const Variable*>>
control_split_changed_variables_;
std::map<const AstNode*, Scope*> context_scopes_;
Ast ast_;
};
class CurrentCallActivator {
class CurrentCallableActivator {
public:
CurrentCallActivator(GlobalContext& context, Callable* callable)
: context_(context) {
CurrentCallableActivator(GlobalContext& context, Callable* callable,
Declaration* decl)
: context_(context), scope_activator_(context.declarations(), decl) {
context_.current_callable_ = callable;
}
~CurrentCallActivator() { context_.current_callable_ = nullptr; }
~CurrentCallableActivator() { context_.current_callable_ = nullptr; }
private:
GlobalContext& context_;
Declarations::NodeScopeActivator scope_activator_;
};
class BreakContinueActivator {
......
This diff is collapsed.
......@@ -30,7 +30,7 @@ class ImplementationVisitor : public FileVisitor {
explicit ImplementationVisitor(GlobalContext& global_context)
: 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);
Type Visit(Statement* stmt);
......@@ -38,7 +38,8 @@ class ImplementationVisitor : public FileVisitor {
LocationReference GetLocationReference(LocationExpression* location);
LocationReference GetLocationReference(IdentifierExpression* expr) {
return LocationReference(LookupValue(expr->pos, expr->name), {}, {});
return LocationReference(declarations()->LookupValue(expr->pos, expr->name),
{}, {});
}
LocationReference GetLocationReference(FieldAccessExpression* expr) {
return LocationReference({}, Visit(expr->object), {});
......
......@@ -14,147 +14,37 @@ namespace v8 {
namespace internal {
namespace torque {
Scope::Scope(GlobalContext& global_context)
: global_context_(global_context),
scope_number_(global_context.GetNextScopeNumber()),
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;
}
Scope::Scope(ScopeChain& scope_chain)
: scope_chain_(scope_chain),
scope_number_(scope_chain_.GetNextScopeNumber()),
private_label_number_(0) {}
Variable* Scope::DeclareVariable(SourcePosition pos, const std::string& var,
Type type) {
std::string name(std::string("v") + "_" + var +
std::to_string(scope_number_));
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));
Scope* ScopeChain::NewScope() {
Scope* new_scope = new Scope(*this);
scopes_.emplace_back(std::unique_ptr<Scope>(new_scope));
return new_scope;
}
void Scope::AddLiveVariables(std::set<const Variable*>& set) {
for (auto& current : lookup_) {
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() {
std::cout << "scope #" << std::to_string(scope_number_) << "\n";
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->global_context().PushScope(scope);
scope->GetScopeChain().PushScope(scope);
}
Scope::Activator::Activator(GlobalContext& global_context, const AstNode* node)
: Activator(global_context.GetParserRuleContextScope(node)) {}
Scope::Activator::~Activator() { scope_->global_context().PopScope(); }
Scope::Activator::~Activator() { scope_->GetScopeChain().PopScope(); }
} // namespace torque
} // namespace internal
......
......@@ -16,49 +16,11 @@ namespace v8 {
namespace internal {
namespace torque {
class Builtin;
class Callable;
class Declarable;
class GlobalContext;
class Macro;
class Parameter;
class Runtime;
class Variable;
class ScopeChain;
class Scope {
public:
explicit Scope(GlobalContext& global_context);
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();
}
explicit Scope(ScopeChain& scope_chain);
void Stream(std::ostream& stream) const {
stream << "scope " << std::to_string(scope_number_) << " {";
......@@ -68,7 +30,9 @@ class Scope {
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);
......@@ -77,18 +41,33 @@ class Scope {
class Activator;
private:
friend class ScopeChain;
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
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 private_label_number_;
std::map<std::string, std::unique_ptr<Declarable>> lookup_;
std::map<std::string, Declarable*> lookup_;
};
class Scope::Activator {
public:
explicit Activator(GlobalContext& global_context, const AstNode* node);
explicit Activator(Scope* scope);
~Activator();
......@@ -96,6 +75,59 @@ class Scope::Activator {
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) {
scope.Stream(os);
return os;
......
......@@ -86,6 +86,7 @@ int WrappedMain(int argc, const char** argv) {
if (output_directory.length() != 0) {
{
DeclarationVisitor visitor(global_context);
visitor.Visit(global_context.ast());
std::string output_header_path = output_directory;
......
......@@ -5,6 +5,8 @@
#ifndef 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/utils.h"
......@@ -14,62 +16,28 @@ namespace torque {
class TypeOracle {
public:
void RegisterTypeImpl(const std::string& name, const std::string& generated,
const std::string* parent = nullptr) {
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);
}
explicit TypeOracle(Declarations* declarations)
: declarations_(declarations) {}
void RegisterImplicitConversion(Type to, Type from) {
implicit_conversions_.push_back(std::make_pair(to, from));
}
Type GetType(const std::string& type_name) {
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 GetArgumentsType() { return GetBuiltinType(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 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); }
Type GetConstInt31Type() { return GetBuiltinType(CONST_INT31_TYPE_STRING); }
bool IsAssignableFrom(Type to, Type from) {
if (to.IsSubclass(from)) return true;
......@@ -99,7 +67,13 @@ class TypeOracle {
}
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_;
};
......
......@@ -5,12 +5,38 @@
#include <fstream>
#include <iostream>
#include "src/torque/declarable.h"
#include "src/torque/types.h"
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) {
......
......@@ -31,21 +31,7 @@ static const char* const CONST_FLOAT64_TYPE_STRING = "const_float64";
class Label;
struct Type;
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_;
};
class TypeImpl;
typedef struct Type {
public:
......@@ -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 Is(const Type& other) const { return impl_ == other.impl_; }
bool Is(const std::string& name) const { return name == impl_->name(); }
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 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; }
......@@ -72,17 +50,11 @@ typedef struct Type {
bool IsBit() const { return name() == BIT_TYPE_STRING; }
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
const std::string& name() const { return impl_->name(); }
const std::string& name() const;
const std::string& GetGeneratedTypeName() const {
return type_impl()->generated_type();
}
const std::string& GetGeneratedTypeName() const;
std::string GetGeneratedTNodeTypeName() const {
std::string result = type_impl()->generated_type();
result = result.substr(6, result.length() - 7);
return result;
}
std::string GetGeneratedTNodeTypeName() const;
protected:
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