Commit 06c8ce59 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] cleanup generics and scopes

- Name lookup in module scopes has namespace semantics now: All
  overloads from all parent modules are combined before overload
  resolution.
- Allow overloads of different callables: runtime-functions,
  macros, builtins, and generics.
- The duplication between the DeclarationVisitor and the
  ImplementationVisitor is removed: The DeclarationVisitor creates
  declarables for everything except for implicit generic specializations.
  The ImplementationVisitor iterates over declarables.
  The DeclarationVisitor only looks at the header of declarations, not
  at the body.
- Modules become Declarable's, which will enable them to be nested.
- Modules replace the existing Scope chain mechanism, which will make it
  easier to inline macros.
- The DeclarationVisitor and Declarations become stateless. All state is
  moved to contextual variables and the GlobalContext.
- Implicit specializations are created directly from the
  ImplementationVisitor. This will enable template parameter inference.
- As a consequence, the list of all builtins is only available after the
  ImplementationVisitor has run. Thus GenerateBuiltinDefinitions has to
  move to the ImplementationVisitor. Also, this makes it necessary to
  resolve the link from function pointer types to example builtins only
  at this point.


Bug: v8:7793
Change-Id: I61cef2fd3e954ab148c252974344a6e38ee2d01d
Reviewed-on: https://chromium-review.googlesource.com/c/1304294
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57231}
parent 2593d073
......@@ -3063,8 +3063,6 @@ v8_source_set("torque_base") {
"src/torque/implementation-visitor.h",
"src/torque/instructions.cc",
"src/torque/instructions.h",
"src/torque/scope.cc",
"src/torque/scope.h",
"src/torque/source-positions.cc",
"src/torque/source-positions.h",
"src/torque/torque-parser.cc",
......
......@@ -748,6 +748,9 @@ macro UnsafeCast<A: type>(n: Number): A;
UnsafeCast<HeapNumber>(n: Number): HeapNumber {
return UnsafeCastNumberToHeapNumber(n);
}
UnsafeCast<Smi>(o: Number): Smi {
return UnsafeCastObjectToSmi(o);
}
macro UnsafeCast<A: type>(o: Object): A;
UnsafeCast<Object>(o: Object): Object {
return o;
......@@ -821,7 +824,6 @@ macro BranchIfJSArgumentsObjectWithLength(implicit context: Context)(o: Object):
goto True;
}
macro UnsafeCast<A: type>(implicit context: Context)(o: Object): A;
UnsafeCast<JSArgumentsObjectWithLength>(implicit context: Context)(o: Object):
JSArgumentsObjectWithLength {
assert(BranchIfJSArgumentsObjectWithLength(o));
......
......@@ -372,5 +372,18 @@ bool Builtins::AllowDynamicFunction(Isolate* isolate, Handle<JSFunction> target,
return isolate->MayAccess(responsible_context, target_global_proxy);
}
Builtins::Name ExampleBuiltinForTorqueFunctionPointerType(
size_t function_pointer_type_id) {
switch (function_pointer_type_id) {
#define FUNCTION_POINTER_ID_CASE(id, name) \
case id: \
return Builtins::k##name;
TORQUE_FUNCTION_POINTER_TYPE_TO_BUILTIN_MAP(FUNCTION_POINTER_ID_CASE)
#undef FUNCTION_POINTER_ID_CASE
default:
UNREACHABLE();
}
}
} // namespace internal
} // namespace v8
......@@ -208,6 +208,9 @@ class Builtins {
DISALLOW_COPY_AND_ASSIGN(Builtins);
};
Builtins::Name ExampleBuiltinForTorqueFunctionPointerType(
size_t function_pointer_type_id);
} // namespace internal
} // namespace v8
......
......@@ -63,8 +63,7 @@ namespace torque {
V(SpecializationDeclaration) \
V(ExternConstDeclaration) \
V(StructDeclaration) \
V(DefaultModuleDeclaration) \
V(ExplicitModuleDeclaration) \
V(ModuleDeclaration) \
V(ConstDeclaration)
#define AST_CALLABLE_NODE_KIND_LIST(V) \
......@@ -155,46 +154,23 @@ struct Statement : AstNode {
class Module;
struct ModuleDeclaration : Declaration {
ModuleDeclaration(AstNode::Kind kind, SourcePosition pos,
DEFINE_AST_NODE_LEAF_BOILERPLATE(ModuleDeclaration)
ModuleDeclaration(SourcePosition pos, std::string name,
std::vector<Declaration*> declarations)
: Declaration(kind, pos),
module(nullptr),
declarations(std::move(declarations)) {}
virtual bool IsDefault() const = 0;
// virtual std::string GetName() const = 0;
void SetModule(Module* m) { module = m; }
Module* GetModule() const { return module; }
Module* module;
: Declaration(kKind, pos),
declarations(std::move(declarations)),
name(name) {}
std::vector<Declaration*> declarations;
};
struct DefaultModuleDeclaration : ModuleDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(DefaultModuleDeclaration)
DefaultModuleDeclaration(SourcePosition pos,
std::vector<Declaration*> declarations)
: ModuleDeclaration(kKind, pos, std::move(declarations)) {}
bool IsDefault() const override { return true; }
};
struct ExplicitModuleDeclaration : ModuleDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(ExplicitModuleDeclaration)
ExplicitModuleDeclaration(SourcePosition pos, std::string name,
std::vector<Declaration*> declarations)
: ModuleDeclaration(kKind, pos, std::move(declarations)),
name(std::move(name)) {}
bool IsDefault() const override { return false; }
std::string name;
};
class Ast {
public:
Ast() : default_module_{SourcePosition{CurrentSourceFile::Get(), 0, 0}, {}} {}
Ast() {}
std::vector<Declaration*>& declarations() {
return default_module_.declarations;
}
std::vector<Declaration*>& declarations() { return declarations_; }
const std::vector<Declaration*>& declarations() const {
return default_module_.declarations;
return declarations_;
}
template <class T>
T* AddNode(std::unique_ptr<T> node) {
......@@ -202,10 +178,9 @@ class Ast {
nodes_.push_back(std::move(node));
return result;
}
DefaultModuleDeclaration* default_module() { return &default_module_; }
private:
DefaultModuleDeclaration default_module_;
std::vector<Declaration*> declarations_;
std::vector<std::unique_ptr<AstNode>> nodes_;
};
......@@ -690,6 +665,7 @@ struct TorqueMacroDeclaration : MacroDeclaration {
};
struct BuiltinDeclaration : CallableNode {
DEFINE_AST_NODE_INNER_BOILERPLATE(BuiltinDeclaration)
BuiltinDeclaration(AstNode::Kind kind, SourcePosition pos,
bool javascript_linkage, bool transitioning,
std::string name, ParameterList parameters,
......@@ -747,10 +723,10 @@ struct ConstDeclaration : Declaration {
struct StandardDeclaration : Declaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StandardDeclaration)
StandardDeclaration(SourcePosition pos, CallableNode* callable,
Statement* body)
base::Optional<Statement*> body)
: Declaration(kKind, pos), callable(callable), body(body) {}
CallableNode* callable;
Statement* body;
base::Optional<Statement*> body;
};
struct GenericDeclaration : Declaration {
......
......@@ -348,13 +348,14 @@ void CSAGenerator::EmitInstruction(
std::vector<std::string> function_and_arguments =
stack->PopMany(1 + instruction.argc);
std::vector<const Type*> result_types =
LowerType(instruction.example_builtin->signature().return_type);
LowerType(instruction.type->return_type());
if (result_types.size() != 1) {
ReportError("builtins must have exactly one result");
}
if (instruction.is_tailcall) {
out_ << " Tail (Builtins::CallableFor(isolate(), Builtins::k"
<< instruction.example_builtin->name() << ").descriptor(), ";
out_ << " Tail (Builtins::CallableFor(isolate(), "
"ExampleBuiltinForTorqueFunctionPointerType("
<< instruction.type->function_pointer_type_id() << ")).descriptor(), ";
PrintCommaSeparatedList(out_, function_and_arguments);
out_ << ");\n";
} else {
......@@ -362,8 +363,9 @@ void CSAGenerator::EmitInstruction(
std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
out_ << " TNode<" << generated_type << "> " << stack->Top() << " = ";
if (generated_type != "Object") out_ << "CAST(";
out_ << "CallStub(Builtins::CallableFor(isolate(), Builtins::k"
<< instruction.example_builtin->name() << ").descriptor(), ";
out_ << "CallStub(Builtins::CallableFor(isolate(),"
"ExampleBuiltinForTorqueFunctionPointerType("
<< instruction.type->function_pointer_type_id() << ")).descriptor(), ";
PrintCommaSeparatedList(out_, function_and_arguments);
out_ << ")";
if (generated_type != "Object") out_ << ")";
......
......@@ -11,12 +11,10 @@ namespace v8 {
namespace internal {
namespace torque {
DEFINE_CONTEXTUAL_VARIABLE(CurrentScope);
std::ostream& operator<<(std::ostream& os, const Callable& m) {
if (m.generic()) {
os << "callable " << (*m.generic())->name() << "(";
} else {
os << "callable " << m.name() << "(";
}
os << "callable " << m.name() << "(";
if (m.signature().implicit_count != 0) {
os << "implicit ";
TypeVector implicit_parameter_types(
......
This diff is collapsed.
This diff is collapsed.
......@@ -12,7 +12,6 @@
#include "src/torque/declarations.h"
#include "src/torque/file-visitor.h"
#include "src/torque/global-context.h"
#include "src/torque/scope.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
......@@ -22,132 +21,73 @@ namespace torque {
class DeclarationVisitor : public FileVisitor {
public:
explicit DeclarationVisitor(GlobalContext& global_context)
: FileVisitor(global_context),
scope_(declarations(), global_context.GetDefaultModule()) {}
void Visit(Ast* ast) {
Visit(ast->default_module());
DrainSpecializationQueue();
CurrentScope::Scope current_namespace(GlobalContext::GetDefaultModule());
for (Declaration* child : ast->declarations()) Visit(child);
}
void Visit(Expression* expr);
void Visit(Statement* stmt);
void Visit(Declaration* decl);
Module* GetOrCreateModule(const std::string& name) {
std::vector<Module*> existing_modules =
FilterDeclarables<Module>(Declarations::TryLookupShallow(name));
if (existing_modules.empty()) {
return Declarations::DeclareModule(name);
}
DCHECK_EQ(1, existing_modules.size());
return existing_modules.front();
}
void Visit(ModuleDeclaration* decl) {
ScopedModuleActivator activator(this, decl->GetModule());
Declarations::ModuleScopeActivator scope(declarations(), decl->GetModule());
CurrentScope::Scope current_scope(GetOrCreateModule(decl->name));
for (Declaration* child : decl->declarations) Visit(child);
}
void Visit(DefaultModuleDeclaration* decl) {
decl->SetModule(global_context_.GetDefaultModule());
Visit(implicit_cast<ModuleDeclaration*>(decl));
}
void Visit(ExplicitModuleDeclaration* decl) {
decl->SetModule(global_context_.GetModule(decl->name));
Visit(implicit_cast<ModuleDeclaration*>(decl));
}
void Visit(IdentifierExpression* expr);
void Visit(NumberLiteralExpression* expr) {}
void Visit(StringLiteralExpression* expr) {}
void Visit(CallExpression* expr);
void Visit(ElementAccessExpression* expr) {
Visit(expr->array);
Visit(expr->index);
}
void Visit(FieldAccessExpression* expr) { Visit(expr->object); }
void Visit(BlockStatement* expr) {
Declarations::NodeScopeActivator scope(declarations(), expr);
for (Statement* stmt : expr->statements) Visit(stmt);
}
void Visit(ExpressionStatement* stmt) { Visit(stmt->expression); }
void Visit(TailCallStatement* stmt) { Visit(stmt->call); }
void Visit(TypeDeclaration* decl);
void Visit(TypeAliasDeclaration* decl) {
const Type* type = declarations()->GetType(decl->type);
const Type* type = Declarations::GetType(decl->type);
type->AddAlias(decl->name);
declarations()->DeclareType(decl->name, type);
Declarations::DeclareType(decl->name, type, true);
}
Builtin* BuiltinDeclarationCommon(BuiltinDeclaration* decl, bool external,
const Signature& signature);
Builtin* CreateBuiltin(BuiltinDeclaration* decl,
const std::string& external_name,
const Signature& signature,
base::Optional<Statement*> body);
void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature,
Statement* body) {
BuiltinDeclarationCommon(decl, true, signature);
base::Optional<Statement*> body) {
Declarations::Declare(
decl->name, CreateBuiltin(decl, decl->name, signature, base::nullopt));
}
void Visit(ExternalRuntimeDeclaration* decl, const Signature& sig,
Statement* body);
base::Optional<Statement*> body);
void Visit(ExternalMacroDeclaration* decl, const Signature& sig,
Statement* body);
base::Optional<Statement*> body);
void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
Statement* body);
base::Optional<Statement*> body);
void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
Statement* body);
base::Optional<Statement*> body);
void Visit(CallableNode* decl, const Signature& signature, Statement* body);
void Visit(CallableNode* decl, const Signature& signature,
base::Optional<Statement*> body);
void Visit(ConstDeclaration* decl);
void Visit(StandardDeclaration* decl);
void Visit(GenericDeclaration* decl);
void Visit(SpecializationDeclaration* decl);
void Visit(ReturnStatement* stmt);
void Visit(DebugStatement* stmt) {}
void Visit(AssertStatement* stmt) {
bool do_check = !stmt->debug_only;
#if defined(DEBUG)
do_check = true;
#endif
if (do_check) Visit(stmt->expression);
}
void Visit(VarDeclarationStatement* stmt);
void Visit(ExternConstDeclaration* decl);
void Visit(StructDeclaration* decl);
void Visit(StructExpression* decl) {}
void Visit(LogicalOrExpression* expr);
void Visit(LogicalAndExpression* expr);
void Visit(ConditionalExpression* expr);
void Visit(IfStatement* stmt);
void Visit(WhileStatement* stmt);
void Visit(ForOfLoopStatement* stmt);
void Visit(AssignmentExpression* expr) {
Visit(expr->location);
Visit(expr->value);
}
void Visit(BreakStatement* stmt) {}
void Visit(ContinueStatement* stmt) {}
void Visit(GotoStatement* expr) {}
void Visit(ForLoopStatement* stmt);
void Visit(IncrementDecrementExpression* expr) {
Visit(expr->location);
}
void Visit(AssumeTypeImpossibleExpression* expr) { Visit(expr->expression); }
void Visit(TryLabelExpression* stmt);
void Visit(StatementExpression* stmt);
void GenerateHeader(std::string& file_name);
Signature MakeSpecializedSignature(const SpecializationKey& key);
Callable* SpecializeImplicit(const SpecializationKey& key);
Callable* Specialize(const SpecializationKey& key, CallableNode* declaration,
base::Optional<const CallableNodeSignature*> signature,
Statement* body);
private:
void DeclareSpecializedTypes(const SpecializationKey& key);
void Specialize(const SpecializationKey& key, CallableNode* callable,
const CallableNodeSignature* signature,
Statement* body) override;
Declarations::ModuleScopeActivator scope_;
std::vector<Builtin*> torque_builtins_;
};
} // namespace torque
......
This diff is collapsed.
This diff is collapsed.
......@@ -5,7 +5,6 @@
#include "src/torque/file-visitor.h"
#include "src/torque/declarable.h"
#include "src/torque/parameter-difference.h"
namespace v8 {
namespace internal {
......@@ -17,68 +16,19 @@ Signature FileVisitor::MakeSignature(const CallableNodeSignature* signature) {
LabelDeclaration def = {label.name, GetTypeVector(label.types)};
definition_vector.push_back(def);
}
base::Optional<std::string> arguments_variable;
if (signature->parameters.has_varargs)
arguments_variable = signature->parameters.arguments_variable;
Signature result{signature->parameters.names,
arguments_variable,
{GetTypeVector(signature->parameters.types),
signature->parameters.has_varargs},
signature->parameters.implicit_count,
declarations()->GetType(signature->return_type),
Declarations::GetType(signature->return_type),
definition_vector};
return result;
}
Signature FileVisitor::MakeSignatureFromReturnType(
TypeExpression* return_type) {
Signature result{
{}, {{}, false}, 0, declarations()->GetType(return_type), {}};
return result;
}
void FileVisitor::QueueGenericSpecialization(
const SpecializationKey& key, CallableNode* callable,
const CallableNodeSignature* signature, base::Optional<Statement*> body) {
pending_specializations_.push_back(
{key, callable, signature, body, CurrentSourcePosition::Get()});
}
void FileVisitor::SpecializeGeneric(
const PendingSpecialization& specialization) {
CurrentSourcePosition::Scope scope(specialization.request_position);
if (completed_specializations_.find(specialization.key) !=
completed_specializations_.end()) {
std::stringstream stream;
stream << "cannot redeclare specialization of "
<< specialization.key.first->name() << " with types <"
<< specialization.key.second << ">";
ReportError(stream.str());
}
if (!specialization.body) {
std::stringstream stream;
stream << "missing specialization of " << specialization.key.first->name()
<< " with types <" << specialization.key.second << ">";
ReportError(stream.str());
}
Declarations::ScopedGenericSpecializationKey instantiation(
declarations(), specialization.key);
FileVisitor::ScopedModuleActivator activator(
this, specialization.key.first->module());
Specialize(specialization.key, specialization.callable,
specialization.signature, *specialization.body);
completed_specializations_.insert(specialization.key);
}
void FileVisitor::DrainSpecializationQueue() {
while (pending_specializations_.size() != 0) {
PendingSpecialization specialization(pending_specializations_.front());
pending_specializations_.pop_front();
if (completed_specializations_.find(specialization.key) ==
completed_specializations_.end()) {
Declarations::ScopedGenericScopeChainSnapshot scope(declarations(),
specialization.key);
SpecializeGeneric(specialization);
}
}
}
} // namespace torque
} // namespace internal
} // namespace v8
......@@ -19,74 +19,20 @@ namespace torque {
class FileVisitor {
public:
explicit FileVisitor(GlobalContext& global_context)
: global_context_(global_context),
declarations_(global_context.declarations()),
module_(global_context.GetDefaultModule()) {}
TypeVector GetTypeVector(const std::vector<TypeExpression*>& v) {
TypeVector result;
for (TypeExpression* t : v) {
result.push_back(declarations()->GetType(t));
result.push_back(Declarations::GetType(t));
}
return result;
}
Ast* ast() { return global_context_.ast(); }
Declarations* declarations() { return global_context_.declarations(); }
void DrainSpecializationQueue();
class ScopedModuleActivator {
public:
ScopedModuleActivator(FileVisitor* visitor, Module* module)
: visitor_(visitor), saved_module_(visitor->CurrentModule()) {
visitor->module_ = module;
}
~ScopedModuleActivator() { visitor_->module_ = saved_module_; }
private:
FileVisitor* visitor_;
Module* saved_module_;
};
protected:
Module* CurrentModule() const { return module_; }
friend class ScopedModuleActivator;
std::string GetParameterVariableFromName(const std::string& name) {
return std::string("p_") + name;
}
Signature MakeSignature(const CallableNodeSignature* signature);
Signature MakeSignatureFromReturnType(TypeExpression* return_type);
struct PendingSpecialization {
SpecializationKey key;
CallableNode* callable;
const CallableNodeSignature* signature;
base::Optional<Statement*> body;
SourcePosition request_position;
};
void QueueGenericSpecialization(const SpecializationKey& key,
CallableNode* callable,
const CallableNodeSignature* signature,
base::Optional<Statement*> body);
void SpecializeGeneric(const PendingSpecialization& specialization);
virtual void Specialize(const SpecializationKey&, CallableNode* callable,
const CallableNodeSignature* signature,
Statement* body) = 0;
GlobalContext& global_context_;
Declarations* declarations_;
std::deque<PendingSpecialization> pending_specializations_;
std::set<SpecializationKey> completed_specializations_;
Callable* current_callable_;
Module* module_;
};
} // namespace torque
......
......@@ -7,98 +7,57 @@
#include "src/torque/declarable.h"
#include "src/torque/declarations.h"
#include "src/torque/scope.h"
#include "src/torque/type-oracle.h"
namespace v8 {
namespace internal {
namespace torque {
class GlobalContext;
class Scope;
class TypeOracle;
class Builtin;
class Module {
public:
explicit Module(const std::string& name, bool is_default)
: name_(name), is_default_(is_default) {}
const std::string& name() const { return name_; }
bool IsDefault() const { return is_default_; }
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(); }
private:
std::string name_;
bool is_default_;
std::stringstream header_stream_;
std::stringstream source_stream_;
};
class GlobalContext {
class GlobalContext : public ContextualClass<GlobalContext> {
public:
explicit GlobalContext(Ast ast)
: verbose_(false),
next_label_number_(0),
default_module_(GetModule("base", true)),
ast_(std::move(ast)) {}
Module* GetDefaultModule() { return default_module_; }
Module* GetModule(const std::string& name, bool is_default = false) {
auto i = modules_.find(name);
if (i != modules_.end()) {
return i->second.get();
}
Module* module = new Module(name, is_default);
modules_[name] = std::unique_ptr<Module>(module);
return module;
explicit GlobalContext(Ast ast) : verbose_(false), ast_(std::move(ast)) {
CurrentScope::Scope current_scope(nullptr);
CurrentSourcePosition::Scope current_source_position(
SourcePosition{CurrentSourceFile::Get(), -1, -1});
default_module_ = RegisterDeclarable(base::make_unique<Module>("base"));
}
int GetNextLabelNumber() { return next_label_number_++; }
const std::map<std::string, std::unique_ptr<Module>>& GetModules() const {
return modules_;
static Module* GetDefaultModule() { return Get().default_module_; }
template <class T>
T* RegisterDeclarable(std::unique_ptr<T> d) {
T* ptr = d.get();
declarables_.push_back(std::move(d));
return ptr;
}
void SetVerbose() { verbose_ = true; }
bool verbose() const { return verbose_; }
friend class CurrentCallableActivator;
friend class BreakContinueActivator;
static const std::vector<std::unique_ptr<Declarable>>& AllDeclarables() {
return Get().declarables_;
}
Callable* GetCurrentCallable() const { return current_callable_; }
static const std::vector<Module*> GetModules() {
std::vector<Module*> result;
for (auto& declarable : AllDeclarables()) {
if (Module* m = Module::DynamicCast(declarable.get())) {
result.push_back(m);
}
}
return result;
}
Declarations* declarations() { return &declarations_; }
Ast* ast() { return &ast_; }
static void SetVerbose() { Get().verbose_ = true; }
static bool verbose() { return Get().verbose_; }
static Ast* ast() { return &Get().ast_; }
private:
bool verbose_;
int next_label_number_;
Declarations declarations_;
Callable* current_callable_;
std::map<std::string, std::unique_ptr<Module>> modules_;
Module* default_module_;
Ast ast_;
std::vector<std::unique_ptr<Declarable>> declarables_;
};
class CurrentCallableActivator {
public:
CurrentCallableActivator(GlobalContext& context, Callable* callable,
CallableNode* decl)
: context_(context), scope_activator_(context.declarations(), decl) {
remembered_callable_ = context_.current_callable_;
context_.current_callable_ = callable;
}
~CurrentCallableActivator() {
context_.current_callable_ = remembered_callable_;
}
private:
GlobalContext& context_;
Callable* remembered_callable_;
Declarations::NodeScopeActivator scope_activator_;
};
template <class T>
T* RegisterDeclarable(std::unique_ptr<T> d) {
return GlobalContext::Get().RegisterDeclarable(std::move(d));
}
} // namespace torque
} // namespace internal
......
This diff is collapsed.
......@@ -199,14 +199,10 @@ bool IsCompatibleSignature(const Signature& sig, const TypeVector& types,
class ImplementationVisitor : public FileVisitor {
public:
explicit ImplementationVisitor(GlobalContext& global_context)
: FileVisitor(global_context) {}
void Visit(Ast* ast) { Visit(ast->default_module()); }
void GenerateBuiltinDefinitions(std::string& file_name);
VisitResult Visit(Expression* expr);
const Type* Visit(Statement* stmt);
void Visit(Declaration* decl);
VisitResult Visit(StructExpression* decl);
......@@ -229,33 +225,12 @@ class ImplementationVisitor : public FileVisitor {
return scope.Yield(GenerateFetchFromLocation(GetLocationReference(expr)));
}
void Visit(ModuleDeclaration* decl);
void Visit(DefaultModuleDeclaration* decl) {
Visit(implicit_cast<ModuleDeclaration*>(decl));
}
void Visit(ExplicitModuleDeclaration* decl) {
Visit(implicit_cast<ModuleDeclaration*>(decl));
}
void Visit(TypeDeclaration* decl) {}
void Visit(TypeAliasDeclaration* decl) {}
void Visit(ExternConstDeclaration* decl) {}
void Visit(StructDeclaration* decl);
void Visit(StandardDeclaration* decl);
void Visit(GenericDeclaration* decl) {}
void Visit(SpecializationDeclaration* decl);
void Visit(TorqueMacroDeclaration* decl, const Signature& signature,
Statement* body);
void Visit(TorqueBuiltinDeclaration* decl, const Signature& signature,
Statement* body);
void Visit(ExternalMacroDeclaration* decl, const Signature& signature,
Statement* body) {}
void Visit(ExternalBuiltinDeclaration* decl, const Signature& signature,
Statement* body) {}
void Visit(ExternalRuntimeDeclaration* decl, const Signature& signature,
Statement* body) {}
void Visit(CallableNode* decl, const Signature& signature, Statement* body);
void Visit(ConstDeclaration* decl);
void VisitAllDeclarables();
void Visit(Declarable* delarable);
void Visit(TypeAlias* decl);
void Visit(Macro* macro);
void Visit(Builtin* builtin);
void Visit(ModuleConstant* decl);
VisitResult Visit(CallExpression* expr, bool is_tail = false);
const Type* Visit(TailCallStatement* stmt);
......@@ -298,6 +273,7 @@ class ImplementationVisitor : public FileVisitor {
BindingsManager<LocalValue>);
DECLARE_CONTEXTUAL_VARIABLE(LabelBindingsManager,
BindingsManager<LocalLabel>);
DECLARE_CONTEXTUAL_VARIABLE(CurrentCallable, Callable*);
// A BindingsManagersScope has to be active for local bindings to be created.
// Shadowing an existing BindingsManagersScope by creating a new one hides all
......@@ -431,13 +407,6 @@ class ImplementationVisitor : public FileVisitor {
VisitResult GenerateImplicitConvert(const Type* destination_type,
VisitResult source);
void Specialize(const SpecializationKey& key, CallableNode* callable,
const CallableNodeSignature* signature,
Statement* body) override {
Declarations::GenericScopeActivator scope(declarations(), key);
Visit(callable, MakeSignature(signature), body);
}
StackRange GenerateLabelGoto(LocalLabel* label,
base::Optional<StackRange> arguments = {});
......@@ -452,9 +421,9 @@ class ImplementationVisitor : public FileVisitor {
size_t i);
std::string ExternalParameterName(const std::string& name);
std::ostream& source_out() { return module_->source_stream(); }
std::ostream& source_out() { return CurrentModule()->source_stream(); }
std::ostream& header_out() { return module_->header_stream(); }
std::ostream& header_out() { return CurrentModule()->header_stream(); }
CfgAssembler& assembler() { return *assembler_; }
......
......@@ -190,9 +190,9 @@ void CallBuiltinPointerInstruction::TypeInstruction(
if (argument_types != LowerParameterTypes(f->parameter_types())) {
ReportError("wrong argument types");
}
if (example_builtin->IsTransitioning()) {
InvalidateTransientTypes(stack);
}
// TODO(tebbi): Only invalidate transient types if the function pointer type
// is transitioning.
InvalidateTransientTypes(stack);
stack->PushMany(LowerType(f->return_type()));
}
......
......@@ -252,14 +252,12 @@ struct CallBuiltinInstruction : InstructionBase {
struct CallBuiltinPointerInstruction : InstructionBase {
TORQUE_INSTRUCTION_BOILERPLATE()
bool IsBlockTerminator() const override { return is_tailcall; }
CallBuiltinPointerInstruction(bool is_tailcall, Builtin* example_builtin,
size_t argc)
: is_tailcall(is_tailcall),
example_builtin(example_builtin),
argc(argc) {}
CallBuiltinPointerInstruction(bool is_tailcall,
const FunctionPointerType* type, size_t argc)
: is_tailcall(is_tailcall), type(type), argc(argc) {}
bool is_tailcall;
Builtin* example_builtin;
const FunctionPointerType* type;
size_t argc;
};
......
// 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 <fstream>
#include <iostream>
#include <string>
#include "src/torque/global-context.h"
#include "src/torque/scope.h"
namespace v8 {
namespace internal {
namespace torque {
Scope::Scope(ScopeChain& scope_chain)
: scope_chain_(scope_chain),
scope_number_(scope_chain_.GetNextScopeNumber()),
private_label_number_(0) {}
Scope* ScopeChain::NewScope() {
Scope* new_scope = new Scope(*this);
scopes_.emplace_back(std::unique_ptr<Scope>(new_scope));
return new_scope;
}
void Scope::Print() {
std::cout << "scope #" << std::to_string(scope_number_) << "\n";
for (auto& i : lookup_) {
std::cout << i.first << ": " << i.second << "\n";
}
}
Scope::Activator::Activator(Scope* scope) : scope_(scope) {
scope->GetScopeChain().PushScope(scope);
}
Scope::Activator::~Activator() { scope_->GetScopeChain().PopScope(); }
} // 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_SCOPE_H_
#define V8_TORQUE_SCOPE_H_
#include <map>
#include <string>
#include "src/torque/ast.h"
#include "src/torque/types.h"
#include "src/torque/utils.h"
namespace v8 {
namespace internal {
namespace torque {
class ScopeChain;
class Declarable;
class Scope {
public:
explicit Scope(ScopeChain& scope_chain);
void Stream(std::ostream& stream) const {
stream << "scope " << std::to_string(scope_number_) << " {";
for (auto& c : lookup_) {
stream << c.first << ",";
}
stream << "}";
}
int scope_number() const { return scope_number_; }
ScopeChain& GetScopeChain() const { return scope_chain_; }
void Print();
class Activator;
private:
friend class ScopeChain;
void CheckAlreadyDeclared(SourcePosition pos, const std::string& name,
const char* new_type);
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, Declarable*> lookup_;
};
class Scope::Activator {
public:
explicit Activator(Scope* scope);
~Activator();
private:
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(); }
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);
}
Declarable* LookupGlobalScope(const std::string& name) {
auto& e = current_scopes_.front();
return e->Lookup(name);
}
void Print() {
for (auto s : current_scopes_) {
s->Print();
}
}
struct Snapshot {
ScopeChain* chain;
std::vector<Scope*> current_scopes;
};
Snapshot TaskSnapshot() { return {this, current_scopes_}; }
class ScopedSnapshotRestorer {
public:
explicit ScopedSnapshotRestorer(const Snapshot& snapshot)
: chain_(snapshot.chain) {
saved_ = chain_->current_scopes_;
chain_->current_scopes_ = snapshot.current_scopes;
}
~ScopedSnapshotRestorer() { chain_->current_scopes_ = saved_; }
private:
ScopeChain* chain_;
std::vector<Scope*> saved_;
};
private:
friend class Scope;
friend class ScopedSnapshotRestorer;
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;
}
} // namespace torque
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_SCOPE_H_
......@@ -364,7 +364,7 @@ base::Optional<ParseResult> MakeExternalMacro(
transitioning, name, operator_name, args, return_type, labels);
Declaration* result;
if (generic_parameters.empty()) {
result = MakeNode<StandardDeclaration>(macro, nullptr);
result = MakeNode<StandardDeclaration>(macro, base::nullopt);
} else {
result = MakeNode<GenericDeclaration>(macro, generic_parameters);
}
......@@ -475,15 +475,15 @@ base::Optional<ParseResult> MakeTypeDeclaration(
return ParseResult{result};
}
base::Optional<ParseResult> MakeExplicitModuleDeclaration(
base::Optional<ParseResult> MakeModuleDeclaration(
ParseResultIterator* child_results) {
auto name = child_results->NextAs<std::string>();
if (!IsSnakeCase(name)) {
NamingConventionError("Module", name, "snake_case");
}
auto declarations = child_results->NextAs<std::vector<Declaration*>>();
Declaration* result = MakeNode<ExplicitModuleDeclaration>(
std::move(name), std::move(declarations));
Declaration* result =
MakeNode<ModuleDeclaration>(std::move(name), std::move(declarations));
return ParseResult{result};
}
......@@ -526,7 +526,7 @@ base::Optional<ParseResult> MakeExternalBuiltin(
transitioning, js_linkage, name, args, return_type);
Declaration* result;
if (generic_parameters.empty()) {
result = MakeNode<StandardDeclaration>(builtin, nullptr);
result = MakeNode<StandardDeclaration>(builtin, base::nullopt);
} else {
result = MakeNode<GenericDeclaration>(builtin, generic_parameters);
}
......@@ -541,7 +541,7 @@ base::Optional<ParseResult> MakeExternalRuntime(
auto return_type = child_results->NextAs<TypeExpression*>();
ExternalRuntimeDeclaration* runtime = MakeNode<ExternalRuntimeDeclaration>(
transitioning, name, args, return_type);
Declaration* result = MakeNode<StandardDeclaration>(runtime, nullptr);
Declaration* result = MakeNode<StandardDeclaration>(runtime, base::nullopt);
return ParseResult{result};
}
......@@ -1448,7 +1448,7 @@ struct TorqueGrammar : Grammar {
Symbol moduleDeclaration = {
Rule({Token("module"), &identifier, Token("{"),
List<Declaration*>(&declaration), Token("}")},
MakeExplicitModuleDeclaration)};
MakeModuleDeclaration)};
Symbol file = {Rule({&file, &moduleDeclaration}, AddGlobalDeclaration),
Rule({&file, &declaration}, AddGlobalDeclaration), Rule({})};
......
......@@ -9,7 +9,6 @@
#include "src/torque/declaration-visitor.h"
#include "src/torque/global-context.h"
#include "src/torque/implementation-visitor.h"
#include "src/torque/scope.h"
#include "src/torque/torque-parser.h"
#include "src/torque/type-oracle.h"
#include "src/torque/types.h"
......@@ -51,31 +50,27 @@ int WrappedMain(int argc, const char** argv) {
ParseTorque(file_content);
}
GlobalContext global_context(std::move(CurrentAst::Get()));
if (verbose) global_context.SetVerbose();
TypeOracle::Scope type_oracle(global_context.declarations());
GlobalContext::Scope global_context(std::move(CurrentAst::Get()));
if (verbose) GlobalContext::SetVerbose();
TypeOracle::Scope type_oracle;
if (output_directory.length() != 0) {
{
DeclarationVisitor visitor(global_context);
DeclarationVisitor().Visit(GlobalContext::Get().ast());
visitor.Visit(global_context.ast());
std::string output_header_path = output_directory;
output_header_path += "/builtin-definitions-from-dsl.h";
visitor.GenerateHeader(output_header_path);
ImplementationVisitor visitor;
for (Module* module : GlobalContext::Get().GetModules()) {
visitor.BeginModuleFile(module);
}
ImplementationVisitor visitor(global_context);
for (auto& module : global_context.GetModules()) {
visitor.BeginModuleFile(module.second.get());
}
visitor.VisitAllDeclarables();
visitor.Visit(global_context.ast());
std::string output_header_path = output_directory;
output_header_path += "/builtin-definitions-from-dsl.h";
visitor.GenerateBuiltinDefinitions(output_header_path);
for (auto& module : global_context.GetModules()) {
visitor.EndModuleFile(module.second.get());
visitor.GenerateImplementation(output_directory, module.second.get());
for (Module* module : GlobalContext::Get().GetModules()) {
visitor.EndModuleFile(module);
visitor.GenerateImplementation(output_directory, module);
}
}
......
......@@ -17,9 +17,6 @@ namespace torque {
class TypeOracle : public ContextualClass<TypeOracle> {
public:
explicit TypeOracle(Declarations* declarations)
: declarations_(declarations) {}
static const AbstractType* GetAbstractType(
const Type* parent, std::string name, bool transient,
std::string generated,
......@@ -32,18 +29,29 @@ class TypeOracle : public ContextualClass<TypeOracle> {
}
static const StructType* GetStructType(
Module* module, const std::string& name,
const std::vector<NameAndType>& fields) {
StructType* result = new StructType(module, name, fields);
const std::string& name, const std::vector<NameAndType>& fields) {
StructType* result = new StructType(CurrentModule(), name, fields);
Get().struct_types_.push_back(std::unique_ptr<StructType>(result));
return result;
}
static const FunctionPointerType* GetFunctionPointerType(
TypeVector argument_types, const Type* return_type) {
const Type* code_type = Get().GetBuiltinType(CODE_TYPE_STRING);
return Get().function_pointer_types_.Add(
FunctionPointerType(code_type, argument_types, return_type));
TypeOracle& self = Get();
const Type* code_type = self.GetBuiltinType(CODE_TYPE_STRING);
const FunctionPointerType* result = self.function_pointer_types_.Add(
FunctionPointerType(code_type, argument_types, return_type,
self.all_function_pointer_types_.size()));
if (result->function_pointer_type_id() ==
self.all_function_pointer_types_.size()) {
self.all_function_pointer_types_.push_back(result);
}
return result;
}
static const std::vector<const FunctionPointerType*>&
AllFunctionPointerTypes() {
return Get().all_function_pointer_types_;
}
static const Type* GetUnionType(UnionType type) {
......@@ -105,17 +113,26 @@ class TypeOracle : public ContextualClass<TypeOracle> {
}
static bool IsImplicitlyConvertableFrom(const Type* to, const Type* from) {
std::string name = GetGeneratedCallableName(kFromConstexprMacroName, {to});
return Get().declarations_->TryLookupMacro(name, {from}) != nullptr;
for (Generic* from_constexpr :
Declarations::LookupGeneric(kFromConstexprMacroName)) {
if (base::Optional<Callable*> specialization =
from_constexpr->GetSpecialization({to})) {
if ((*specialization)->signature().GetExplicitTypes() ==
TypeVector{from}) {
return true;
}
}
}
return false;
}
private:
const Type* GetBuiltinType(const std::string& name) {
return declarations_->LookupGlobalType(name);
return Declarations::LookupGlobalType(name);
}
Declarations* declarations_;
Deduplicator<FunctionPointerType> function_pointer_types_;
std::vector<const FunctionPointerType*> all_function_pointer_types_;
Deduplicator<UnionType> union_types_;
std::vector<std::unique_ptr<Type>> nominal_types_;
std::vector<std::unique_ptr<Type>> struct_types_;
......
......@@ -121,6 +121,14 @@ class Type : public TypeBase {
using TypeVector = std::vector<const Type*>;
inline size_t hash_value(const TypeVector& types) {
size_t hash = 0;
for (const Type* t : types) {
hash = base::hash_combine(hash, t);
}
return hash;
}
struct NameAndType {
std::string name;
const Type* type;
......@@ -229,17 +237,20 @@ class FunctionPointerType final : public Type {
return parameter_types_ == other.parameter_types_ &&
return_type_ == other.return_type_;
}
size_t function_pointer_type_id() const { return function_pointer_type_id_; }
private:
friend class TypeOracle;
FunctionPointerType(const Type* parent, TypeVector parameter_types,
const Type* return_type)
const Type* return_type, size_t function_pointer_type_id)
: Type(Kind::kFunctionPointerType, parent),
parameter_types_(parameter_types),
return_type_(return_type) {}
return_type_(return_type),
function_pointer_type_id_(function_pointer_type_id) {}
const TypeVector parameter_types_;
const Type* const return_type_;
const size_t function_pointer_type_id_;
};
bool operator<(const Type& a, const Type& b);
......@@ -460,9 +471,10 @@ std::ostream& operator<<(std::ostream& os, const ParameterTypes& parameters);
enum class ParameterMode { kProcessImplicit, kIgnoreImplicit };
struct Signature {
Signature(NameVector n, ParameterTypes p, size_t i, const Type* r,
LabelDeclarationVector l)
Signature(NameVector n, base::Optional<std::string> arguments_variable,
ParameterTypes p, size_t i, const Type* r, LabelDeclarationVector l)
: parameter_names(std::move(n)),
arguments_variable(arguments_variable),
parameter_types(std::move(p)),
implicit_count(i),
return_type(r),
......@@ -470,6 +482,7 @@ struct Signature {
Signature() : implicit_count(0), return_type(nullptr) {}
const TypeVector& types() const { return parameter_types.types; }
NameVector parameter_names;
base::Optional<std::string> arguments_variable;
ParameterTypes parameter_types;
size_t implicit_count;
const Type* return_type;
......
......@@ -203,8 +203,8 @@ module test {
check(fptr2(c, Undefined) == Undefined);
}
type SmiToSmi = builtin(Smi) => Smi;
macro TestTypeAlias(x: SmiToSmi): Code {
type ObjectToObject = builtin(Context, Object) => Object;
macro TestTypeAlias(x: ObjectToObject): Code {
return x;
}
......
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