Commit ece9156c authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] allow qualified access to different modules/namespaces

This introduces a new syntax for identifiers and calls: modulename::foo.
Such a name is resolved by trying to find a module modulename in one of
the parent scopes and looking for foo there. So this roughly corresponds
to C++ qualified namespace lookup.

Bug: v8:7793
Change-Id: Iedc43e6ebe125cd74575cbbcbf990bbcc0155a1f
Reviewed-on: https://chromium-review.googlesource.com/c/1309818
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57238}
parent 75da45ff
...@@ -186,28 +186,31 @@ class Ast { ...@@ -186,28 +186,31 @@ class Ast {
struct IdentifierExpression : LocationExpression { struct IdentifierExpression : LocationExpression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression)
IdentifierExpression(SourcePosition pos, std::string name, IdentifierExpression(SourcePosition pos,
std::vector<TypeExpression*> args = {}) std::vector<std::string> namespace_qualification,
std::string name, std::vector<TypeExpression*> args = {})
: LocationExpression(kKind, pos), : LocationExpression(kKind, pos),
namespace_qualification(std::move(namespace_qualification)),
name(std::move(name)), name(std::move(name)),
generic_arguments(std::move(args)) {} generic_arguments(std::move(args)) {}
IdentifierExpression(SourcePosition pos, std::string name,
std::vector<TypeExpression*> args = {})
: IdentifierExpression(pos, {}, std::move(name), std::move(args)) {}
std::vector<std::string> namespace_qualification;
std::string name; std::string name;
std::vector<TypeExpression*> generic_arguments; std::vector<TypeExpression*> generic_arguments;
}; };
struct CallExpression : Expression { struct CallExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(CallExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(CallExpression)
CallExpression(SourcePosition pos, std::string callee, bool is_operator, CallExpression(SourcePosition pos, IdentifierExpression* callee,
std::vector<TypeExpression*> generic_arguments,
std::vector<Expression*> arguments, std::vector<Expression*> arguments,
std::vector<std::string> labels) std::vector<std::string> labels)
: Expression(kKind, pos), : Expression(kKind, pos),
callee(pos, std::move(callee), std::move(generic_arguments)), callee(callee),
is_operator(is_operator),
arguments(std::move(arguments)), arguments(std::move(arguments)),
labels(std::move(labels)) {} labels(std::move(labels)) {}
IdentifierExpression callee; IdentifierExpression* callee;
bool is_operator;
std::vector<Expression*> arguments; std::vector<Expression*> arguments;
std::vector<std::string> labels; std::vector<std::string> labels;
}; };
......
...@@ -13,6 +13,18 @@ namespace torque { ...@@ -13,6 +13,18 @@ namespace torque {
DEFINE_CONTEXTUAL_VARIABLE(CurrentScope); DEFINE_CONTEXTUAL_VARIABLE(CurrentScope);
std::ostream& operator<<(std::ostream& os, const QualifiedName& name) {
bool first = true;
for (const std::string& qualifier : name.namespace_qualification) {
if (!first) {
os << "::";
}
os << qualifier;
first = false;
}
return os << name.name;
}
std::ostream& operator<<(std::ostream& os, const Callable& m) { std::ostream& operator<<(std::ostream& os, const Callable& m) {
os << "callable " << m.ReadableName() << "("; os << "callable " << m.ReadableName() << "(";
if (m.signature().implicit_count != 0) { if (m.signature().implicit_count != 0) {
......
...@@ -23,6 +23,20 @@ class Scope; ...@@ -23,6 +23,20 @@ class Scope;
DECLARE_CONTEXTUAL_VARIABLE(CurrentScope, Scope*); DECLARE_CONTEXTUAL_VARIABLE(CurrentScope, Scope*);
struct QualifiedName {
std::vector<std::string> namespace_qualification;
std::string name;
QualifiedName(std::vector<std::string> namespace_qualification,
std::string name)
: namespace_qualification(std::move(namespace_qualification)),
name(std::move(name)) {}
explicit QualifiedName(std::string name)
: QualifiedName({}, std::move(name)) {}
friend std::ostream& operator<<(std::ostream& os, const QualifiedName& name);
};
class Declarable { class Declarable {
public: public:
virtual ~Declarable() = default; virtual ~Declarable() = default;
...@@ -46,6 +60,7 @@ class Declarable { ...@@ -46,6 +60,7 @@ class Declarable {
bool IsExternConstant() const { return kind() == kExternConstant; } bool IsExternConstant() const { return kind() == kExternConstant; }
bool IsModuleConstant() const { return kind() == kModuleConstant; } bool IsModuleConstant() const { return kind() == kModuleConstant; }
bool IsValue() const { return IsExternConstant() || IsModuleConstant(); } bool IsValue() const { return IsExternConstant() || IsModuleConstant(); }
bool IsScope() const { return IsModule() || IsCallable(); }
bool IsCallable() const { bool IsCallable() const {
return IsMacro() || IsBuiltin() || IsRuntimeFunction(); return IsMacro() || IsBuiltin() || IsRuntimeFunction();
} }
...@@ -85,18 +100,35 @@ class Declarable { ...@@ -85,18 +100,35 @@ class Declarable {
class Scope : public Declarable { class Scope : public Declarable {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Scope, scope);
explicit Scope(Declarable::Kind kind) : Declarable(kind) {} explicit Scope(Declarable::Kind kind) : Declarable(kind) {}
const std::vector<Declarable*>& LookupShallow(const std::string& name) { std::vector<Declarable*> LookupShallow(const QualifiedName& name) {
return declarations_[name]; if (name.namespace_qualification.empty()) return declarations_[name.name];
Scope* child = nullptr;
for (Declarable* declarable :
declarations_[name.namespace_qualification.front()]) {
if (Scope* scope = Scope::DynamicCast(declarable)) {
if (child != nullptr) {
ReportError("ambiguous reference to scope ",
name.namespace_qualification.front());
}
child = scope;
}
}
if (child == nullptr) return {};
return child->LookupShallow(
QualifiedName({name.namespace_qualification.begin() + 1,
name.namespace_qualification.end()},
name.name));
} }
std::vector<Declarable*> Lookup(const std::string& name) { std::vector<Declarable*> Lookup(const QualifiedName& name) {
std::vector<Declarable*> result; std::vector<Declarable*> result;
if (ParentScope()) { if (ParentScope()) {
result = ParentScope()->Lookup(name); result = ParentScope()->Lookup(name);
} }
for (Declarable* declarable : declarations_[name]) { for (Declarable* declarable : LookupShallow(name)) {
result.push_back(declarable); result.push_back(declarable);
} }
return result; return result;
......
...@@ -29,8 +29,8 @@ class DeclarationVisitor : public FileVisitor { ...@@ -29,8 +29,8 @@ class DeclarationVisitor : public FileVisitor {
void Visit(Declaration* decl); void Visit(Declaration* decl);
Module* GetOrCreateModule(const std::string& name) { Module* GetOrCreateModule(const std::string& name) {
std::vector<Module*> existing_modules = std::vector<Module*> existing_modules = FilterDeclarables<Module>(
FilterDeclarables<Module>(Declarations::TryLookupShallow(name)); Declarations::TryLookupShallow(QualifiedName(name)));
if (existing_modules.empty()) { if (existing_modules.empty()) {
return Declarations::DeclareModule(name); return Declarations::DeclareModule(name);
} }
......
...@@ -24,9 +24,8 @@ std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name, ...@@ -24,9 +24,8 @@ std::vector<T> EnsureNonempty(std::vector<T> list, const std::string& name,
return std::move(list); return std::move(list);
} }
template <class T> template <class T, class Name>
T EnsureUnique(const std::vector<T>& list, const std::string& name, T EnsureUnique(const std::vector<T>& list, const Name& name, const char* kind) {
const char* kind) {
if (list.empty()) { if (list.empty()) {
ReportError("there is no ", kind, "named ", name); ReportError("there is no ", kind, "named ", name);
} }
...@@ -39,7 +38,7 @@ T EnsureUnique(const std::vector<T>& list, const std::string& name, ...@@ -39,7 +38,7 @@ T EnsureUnique(const std::vector<T>& list, const std::string& name,
template <class T> template <class T>
void CheckAlreadyDeclared(const std::string& name, const char* new_type) { void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
std::vector<T*> declarations = std::vector<T*> declarations =
FilterDeclarables<T>(Declarations::TryLookupShallow(name)); FilterDeclarables<T>(Declarations::TryLookupShallow(QualifiedName(name)));
if (!declarations.empty()) { if (!declarations.empty()) {
Scope* scope = CurrentScope::Get(); Scope* scope = CurrentScope::Get();
ReportError("cannot redeclare ", name, " (type ", new_type, scope, ")"); ReportError("cannot redeclare ", name, " (type ", new_type, scope, ")");
...@@ -50,7 +49,8 @@ void CheckAlreadyDeclared(const std::string& name, const char* new_type) { ...@@ -50,7 +49,8 @@ void CheckAlreadyDeclared(const std::string& name, const char* new_type) {
std::vector<Declarable*> Declarations::LookupGlobalScope( std::vector<Declarable*> Declarations::LookupGlobalScope(
const std::string& name) { const std::string& name) {
std::vector<Declarable*> d = GlobalContext::GetDefaultModule()->Lookup(name); std::vector<Declarable*> d =
GlobalContext::GetDefaultModule()->Lookup(QualifiedName(name));
if (d.empty()) { if (d.empty()) {
std::stringstream s; std::stringstream s;
s << "cannot find \"" << name << "\" in global scope"; s << "cannot find \"" << name << "\" in global scope";
...@@ -60,8 +60,8 @@ std::vector<Declarable*> Declarations::LookupGlobalScope( ...@@ -60,8 +60,8 @@ std::vector<Declarable*> Declarations::LookupGlobalScope(
} }
const Type* Declarations::LookupType(const std::string& name) { const Type* Declarations::LookupType(const std::string& name) {
TypeAlias* declaration = TypeAlias* declaration = EnsureUnique(
EnsureUnique(FilterDeclarables<TypeAlias>(Lookup(name)), name, "type"); FilterDeclarables<TypeAlias>(Lookup(QualifiedName(name))), name, "type");
return declaration->type(); return declaration->type();
} }
...@@ -105,13 +105,13 @@ Builtin* Declarations::FindSomeInternalBuiltinWithType( ...@@ -105,13 +105,13 @@ Builtin* Declarations::FindSomeInternalBuiltinWithType(
return nullptr; return nullptr;
} }
Value* Declarations::LookupValue(const std::string& name) { Value* Declarations::LookupValue(const QualifiedName& name) {
return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value"); return EnsureUnique(FilterDeclarables<Value>(Lookup(name)), name, "value");
} }
Macro* Declarations::TryLookupMacro(const std::string& name, Macro* Declarations::TryLookupMacro(const std::string& name,
const TypeVector& types) { const TypeVector& types) {
std::vector<Macro*> macros = TryLookup<Macro>(name); std::vector<Macro*> macros = TryLookup<Macro>(QualifiedName(name));
for (auto& m : macros) { for (auto& m : macros) {
auto signature_types = m->signature().GetExplicitTypes(); auto signature_types = m->signature().GetExplicitTypes();
if (signature_types == types && !m->signature().parameter_types.var_args) { if (signature_types == types && !m->signature().parameter_types.var_args) {
...@@ -122,18 +122,18 @@ Macro* Declarations::TryLookupMacro(const std::string& name, ...@@ -122,18 +122,18 @@ Macro* Declarations::TryLookupMacro(const std::string& name,
} }
base::Optional<Builtin*> Declarations::TryLookupBuiltin( base::Optional<Builtin*> Declarations::TryLookupBuiltin(
const std::string& name) { const QualifiedName& name) {
std::vector<Builtin*> builtins = TryLookup<Builtin>(name); std::vector<Builtin*> builtins = TryLookup<Builtin>(name);
if (builtins.empty()) return base::nullopt; if (builtins.empty()) return base::nullopt;
return EnsureUnique(builtins, name, "builtin"); return EnsureUnique(builtins, name.name, "builtin");
} }
std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) { std::vector<Generic*> Declarations::LookupGeneric(const std::string& name) {
return EnsureNonempty(FilterDeclarables<Generic>(Lookup(name)), name, return EnsureNonempty(FilterDeclarables<Generic>(Lookup(QualifiedName(name))),
"generic"); name, "generic");
} }
Generic* Declarations::LookupUniqueGeneric(const std::string& name) { Generic* Declarations::LookupUniqueGeneric(const QualifiedName& name) {
return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name, return EnsureUnique(FilterDeclarables<Generic>(Lookup(name)), name,
"generic"); "generic");
} }
......
...@@ -31,20 +31,20 @@ std::vector<T*> FilterDeclarables(const std::vector<Declarable*> list) { ...@@ -31,20 +31,20 @@ std::vector<T*> FilterDeclarables(const std::vector<Declarable*> list) {
class Declarations { class Declarations {
public: public:
static std::vector<Declarable*> TryLookup(const std::string& name) { static std::vector<Declarable*> TryLookup(const QualifiedName& name) {
return CurrentScope::Get()->Lookup(name); return CurrentScope::Get()->Lookup(name);
} }
static std::vector<Declarable*> TryLookupShallow(const std::string& name) { static std::vector<Declarable*> TryLookupShallow(const QualifiedName& name) {
return CurrentScope::Get()->LookupShallow(name); return CurrentScope::Get()->LookupShallow(name);
} }
template <class T> template <class T>
static std::vector<T*> TryLookup(const std::string& name) { static std::vector<T*> TryLookup(const QualifiedName& name) {
return FilterDeclarables<T>(TryLookup(name)); return FilterDeclarables<T>(TryLookup(name));
} }
static std::vector<Declarable*> Lookup(const std::string& name) { static std::vector<Declarable*> Lookup(const QualifiedName& name) {
std::vector<Declarable*> d = TryLookup(name); std::vector<Declarable*> d = TryLookup(name);
if (d.empty()) { if (d.empty()) {
std::stringstream s; std::stringstream s;
...@@ -63,14 +63,14 @@ class Declarations { ...@@ -63,14 +63,14 @@ class Declarations {
static Builtin* FindSomeInternalBuiltinWithType( static Builtin* FindSomeInternalBuiltinWithType(
const FunctionPointerType* type); const FunctionPointerType* type);
static Value* LookupValue(const std::string& name); static Value* LookupValue(const QualifiedName& name);
static Macro* TryLookupMacro(const std::string& name, static Macro* TryLookupMacro(const std::string& name,
const TypeVector& types); const TypeVector& types);
static base::Optional<Builtin*> TryLookupBuiltin(const std::string& name); static base::Optional<Builtin*> TryLookupBuiltin(const QualifiedName& name);
static std::vector<Generic*> LookupGeneric(const std::string& name); static std::vector<Generic*> LookupGeneric(const std::string& name);
static Generic* LookupUniqueGeneric(const std::string& name); static Generic* LookupUniqueGeneric(const QualifiedName& name);
static Module* DeclareModule(const std::string& name); static Module* DeclareModule(const std::string& name);
......
...@@ -1242,7 +1242,7 @@ void ImplementationVisitor::GenerateFunctionDeclaration( ...@@ -1242,7 +1242,7 @@ void ImplementationVisitor::GenerateFunctionDeclaration(
namespace { namespace {
void FailCallableLookup(const std::string& reason, const std::string& name, void FailCallableLookup(const std::string& reason, const QualifiedName& name,
const Arguments& arguments, const Arguments& arguments,
const std::vector<Signature>& candidates) { const std::vector<Signature>& candidates) {
std::stringstream stream; std::stringstream stream;
...@@ -1302,7 +1302,7 @@ Block* ImplementationVisitor::LookupSimpleLabel(const std::string& name) { ...@@ -1302,7 +1302,7 @@ Block* ImplementationVisitor::LookupSimpleLabel(const std::string& name) {
} }
Callable* ImplementationVisitor::LookupCall( Callable* ImplementationVisitor::LookupCall(
const std::string& name, const Arguments& arguments, const QualifiedName& name, const Arguments& arguments,
const TypeVector& specialization_types) { const TypeVector& specialization_types) {
Callable* result = nullptr; Callable* result = nullptr;
TypeVector parameter_types(arguments.parameters.GetTypeVector()); TypeVector parameter_types(arguments.parameters.GetTypeVector());
...@@ -1486,19 +1486,22 @@ LocationReference ImplementationVisitor::GetLocationReference( ...@@ -1486,19 +1486,22 @@ LocationReference ImplementationVisitor::GetLocationReference(
LocationReference ImplementationVisitor::GetLocationReference( LocationReference ImplementationVisitor::GetLocationReference(
IdentifierExpression* expr) { IdentifierExpression* expr) {
if (base::Optional<Binding<LocalValue>*> value = if (expr->namespace_qualification.empty()) {
TryLookupLocalValue(expr->name)) { if (base::Optional<Binding<LocalValue>*> value =
if (expr->generic_arguments.size() != 0) { TryLookupLocalValue(expr->name)) {
ReportError("cannot have generic parameters on local name ", expr->name); if (expr->generic_arguments.size() != 0) {
} ReportError("cannot have generic parameters on local name ",
if ((*value)->is_const) { expr->name);
return LocationReference::Temporary((*value)->value, }
"constant value " + expr->name); if ((*value)->is_const) {
return LocationReference::Temporary((*value)->value,
"constant value " + expr->name);
}
return LocationReference::VariableAccess((*value)->value);
} }
return LocationReference::VariableAccess((*value)->value);
} }
std::string name = expr->name; QualifiedName name = QualifiedName(expr->namespace_qualification, expr->name);
if (base::Optional<Builtin*> builtin = Declarations::TryLookupBuiltin(name)) { if (base::Optional<Builtin*> builtin = Declarations::TryLookupBuiltin(name)) {
return LocationReference::Temporary(GetBuiltinCode(*builtin), return LocationReference::Temporary(GetBuiltinCode(*builtin),
"builtin " + expr->name); "builtin " + expr->name);
...@@ -1516,7 +1519,7 @@ LocationReference ImplementationVisitor::GetLocationReference( ...@@ -1516,7 +1519,7 @@ LocationReference ImplementationVisitor::GetLocationReference(
generic->name()); generic->name());
} }
} }
Value* value = Declarations::LookupValue(expr->name); Value* value = Declarations::LookupValue(name);
if (auto* constant = ModuleConstant::DynamicCast(value)) { if (auto* constant = ModuleConstant::DynamicCast(value)) {
if (constant->type()->IsConstexpr()) { if (constant->type()->IsConstexpr()) {
return LocationReference::Temporary( return LocationReference::Temporary(
...@@ -1620,7 +1623,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall( ...@@ -1620,7 +1623,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
} }
VisitResult ImplementationVisitor::GenerateCall( VisitResult ImplementationVisitor::GenerateCall(
const std::string& callable_name, Arguments arguments, const QualifiedName& callable_name, Arguments arguments,
const TypeVector& specialization_types, bool is_tailcall) { const TypeVector& specialization_types, bool is_tailcall) {
Callable* callable = Callable* callable =
LookupCall(callable_name, arguments, specialization_types); LookupCall(callable_name, arguments, specialization_types);
...@@ -1647,8 +1650,8 @@ VisitResult ImplementationVisitor::GenerateCall( ...@@ -1647,8 +1650,8 @@ VisitResult ImplementationVisitor::GenerateCall(
base::Optional<Binding<LocalValue>*> val = base::Optional<Binding<LocalValue>*> val =
TryLookupLocalValue(implicit_name); TryLookupLocalValue(implicit_name);
if (!val) { if (!val) {
ReportError("implicit parameter '" + implicit_name + ReportError("implicit parameter '", implicit_name,
"' required for call to '" + callable_name + "' required for call to '", callable_name,
"' is not defined"); "' is not defined");
} }
VisitResult converted = GenerateImplicitConvert( VisitResult converted = GenerateImplicitConvert(
...@@ -1821,17 +1824,19 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr, ...@@ -1821,17 +1824,19 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
bool is_tailcall) { bool is_tailcall) {
StackScope scope(this); StackScope scope(this);
Arguments arguments; Arguments arguments;
std::string name = expr->callee.name; QualifiedName name =
QualifiedName(expr->callee->namespace_qualification, expr->callee->name);
TypeVector specialization_types = TypeVector specialization_types =
GetTypeVector(expr->callee.generic_arguments); GetTypeVector(expr->callee->generic_arguments);
bool has_template_arguments = !specialization_types.empty(); bool has_template_arguments = !specialization_types.empty();
for (Expression* arg : expr->arguments) for (Expression* arg : expr->arguments)
arguments.parameters.push_back(Visit(arg)); arguments.parameters.push_back(Visit(arg));
arguments.labels = LabelsFromIdentifiers(expr->labels); arguments.labels = LabelsFromIdentifiers(expr->labels);
VisitResult result; VisitResult result;
if (!has_template_arguments && TryLookupLocalValue(expr->callee.name)) { if (!has_template_arguments && name.namespace_qualification.empty() &&
TryLookupLocalValue(name.name)) {
return scope.Yield( return scope.Yield(
GeneratePointerCall(&expr->callee, arguments, is_tailcall)); GeneratePointerCall(expr->callee, arguments, is_tailcall));
} else { } else {
return scope.Yield( return scope.Yield(
GenerateCall(name, arguments, specialization_types, is_tailcall)); GenerateCall(name, arguments, specialization_types, is_tailcall));
......
...@@ -368,7 +368,7 @@ class ImplementationVisitor : public FileVisitor { ...@@ -368,7 +368,7 @@ class ImplementationVisitor : public FileVisitor {
base::Optional<Binding<LocalLabel>*> TryLookupLabel(const std::string& name); base::Optional<Binding<LocalLabel>*> TryLookupLabel(const std::string& name);
Binding<LocalLabel>* LookupLabel(const std::string& name); Binding<LocalLabel>* LookupLabel(const std::string& name);
Block* LookupSimpleLabel(const std::string& name); Block* LookupSimpleLabel(const std::string& name);
Callable* LookupCall(const std::string& name, const Arguments& arguments, Callable* LookupCall(const QualifiedName& name, const Arguments& arguments,
const TypeVector& specialization_types); const TypeVector& specialization_types);
const Type* GetCommonType(const Type* left, const Type* right); const Type* GetCommonType(const Type* left, const Type* right);
...@@ -378,10 +378,16 @@ class ImplementationVisitor : public FileVisitor { ...@@ -378,10 +378,16 @@ class ImplementationVisitor : public FileVisitor {
void GenerateAssignToLocation(const LocationReference& reference, void GenerateAssignToLocation(const LocationReference& reference,
const VisitResult& assignment_value); const VisitResult& assignment_value);
VisitResult GenerateCall(const std::string& callable_name, VisitResult GenerateCall(const QualifiedName& callable_name,
Arguments parameters, Arguments parameters,
const TypeVector& specialization_types = {}, const TypeVector& specialization_types = {},
bool tail_call = false); bool tail_call = false);
VisitResult GenerateCall(std::string callable_name, Arguments parameters,
const TypeVector& specialization_types = {},
bool tail_call = false) {
return GenerateCall(QualifiedName(std::move(callable_name)),
std::move(parameters), specialization_types, tail_call);
}
VisitResult GeneratePointerCall(Expression* callee, VisitResult GeneratePointerCall(Expression* callee,
const Arguments& parameters, bool tail_call); const Arguments& parameters, bool tail_call);
......
...@@ -207,8 +207,7 @@ void CheckNotDeferredStatement(Statement* statement) { ...@@ -207,8 +207,7 @@ void CheckNotDeferredStatement(Statement* statement) {
} }
} }
Expression* MakeCall(const std::string& callee, bool is_operator, Expression* MakeCall(IdentifierExpression* callee,
const std::vector<TypeExpression*>& generic_arguments,
const std::vector<Expression*>& arguments, const std::vector<Expression*>& arguments,
const std::vector<Statement*>& otherwise) { const std::vector<Statement*>& otherwise) {
std::vector<std::string> labels; std::vector<std::string> labels;
...@@ -237,20 +236,27 @@ Expression* MakeCall(const std::string& callee, bool is_operator, ...@@ -237,20 +236,27 @@ Expression* MakeCall(const std::string& callee, bool is_operator,
// Create nested try-label expression for all of the temporary Labels that // Create nested try-label expression for all of the temporary Labels that
// were created. // were created.
Expression* result = MakeNode<CallExpression>( Expression* result = MakeNode<CallExpression>(callee, arguments, labels);
callee, false, generic_arguments, arguments, labels);
for (auto* label : temp_labels) { for (auto* label : temp_labels) {
result = MakeNode<TryLabelExpression>(false, result, label); result = MakeNode<TryLabelExpression>(false, result, label);
} }
return result; return result;
} }
Expression* MakeCall(const std::string& callee,
const std::vector<TypeExpression*>& generic_arguments,
const std::vector<Expression*>& arguments,
const std::vector<Statement*>& otherwise) {
return MakeCall(MakeNode<IdentifierExpression>(callee, generic_arguments),
arguments, otherwise);
}
base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) { base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) {
auto callee = child_results->NextAs<std::string>(); auto callee = child_results->NextAs<LocationExpression*>();
auto generic_args = child_results->NextAs<TypeList>();
auto args = child_results->NextAs<std::vector<Expression*>>(); auto args = child_results->NextAs<std::vector<Expression*>>();
auto otherwise = child_results->NextAs<std::vector<Statement*>>(); auto otherwise = child_results->NextAs<std::vector<Statement*>>();
return ParseResult{MakeCall(callee, false, generic_args, args, otherwise)}; return ParseResult{
MakeCall(IdentifierExpression::cast(callee), args, otherwise)};
} }
base::Optional<ParseResult> MakeBinaryOperator( base::Optional<ParseResult> MakeBinaryOperator(
...@@ -258,7 +264,7 @@ base::Optional<ParseResult> MakeBinaryOperator( ...@@ -258,7 +264,7 @@ base::Optional<ParseResult> MakeBinaryOperator(
auto left = child_results->NextAs<Expression*>(); auto left = child_results->NextAs<Expression*>();
auto op = child_results->NextAs<std::string>(); auto op = child_results->NextAs<std::string>();
auto right = child_results->NextAs<Expression*>(); auto right = child_results->NextAs<Expression*>();
return ParseResult{MakeCall(op, true, TypeList{}, return ParseResult{MakeCall(op, TypeList{},
std::vector<Expression*>{left, right}, std::vector<Expression*>{left, right},
std::vector<Statement*>{})}; std::vector<Statement*>{})};
} }
...@@ -267,7 +273,7 @@ base::Optional<ParseResult> MakeUnaryOperator( ...@@ -267,7 +273,7 @@ base::Optional<ParseResult> MakeUnaryOperator(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto op = child_results->NextAs<std::string>(); auto op = child_results->NextAs<std::string>();
auto e = child_results->NextAs<Expression*>(); auto e = child_results->NextAs<Expression*>();
return ParseResult{MakeCall(op, true, TypeList{}, std::vector<Expression*>{e}, return ParseResult{MakeCall(op, TypeList{}, std::vector<Expression*>{e},
std::vector<Statement*>{})}; std::vector<Statement*>{})};
} }
...@@ -662,11 +668,10 @@ base::Optional<ParseResult> MakeTypeswitchStatement( ...@@ -662,11 +668,10 @@ base::Optional<ParseResult> MakeTypeswitchStatement(
} }
BlockStatement* case_block; BlockStatement* case_block;
if (i < cases.size() - 1) { if (i < cases.size() - 1) {
value = value = MakeCall("Cast", std::vector<TypeExpression*>{cases[i].type},
MakeCall("Cast", false, std::vector<TypeExpression*>{cases[i].type}, std::vector<Expression*>{value},
std::vector<Expression*>{value}, std::vector<Statement*>{MakeNode<ExpressionStatement>(
std::vector<Statement*>{MakeNode<ExpressionStatement>( MakeNode<IdentifierExpression>("_NextCase"))});
MakeNode<IdentifierExpression>("_NextCase"))});
case_block = MakeNode<BlockStatement>(); case_block = MakeNode<BlockStatement>();
} else { } else {
case_block = current_block; case_block = current_block;
...@@ -864,11 +869,14 @@ base::Optional<ParseResult> MakeExpressionWithSource( ...@@ -864,11 +869,14 @@ base::Optional<ParseResult> MakeExpressionWithSource(
base::Optional<ParseResult> MakeIdentifierExpression( base::Optional<ParseResult> MakeIdentifierExpression(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto namespace_qualification =
child_results->NextAs<std::vector<std::string>>();
auto name = child_results->NextAs<std::string>(); auto name = child_results->NextAs<std::string>();
auto generic_arguments = auto generic_arguments =
child_results->NextAs<std::vector<TypeExpression*>>(); child_results->NextAs<std::vector<TypeExpression*>>();
LocationExpression* result = MakeNode<IdentifierExpression>( LocationExpression* result = MakeNode<IdentifierExpression>(
std::move(name), std::move(generic_arguments)); std::move(namespace_qualification), std::move(name),
std::move(generic_arguments));
return ParseResult{result}; return ParseResult{result};
} }
...@@ -1197,10 +1205,16 @@ struct TorqueGrammar : Grammar { ...@@ -1197,10 +1205,16 @@ struct TorqueGrammar : Grammar {
IncrementDecrementOperator::kDecrement>)}; IncrementDecrementOperator::kDecrement>)};
// Result: LocationExpression* // Result: LocationExpression*
Symbol locationExpression = { Symbol identifierExpression = {
Rule( Rule(
{&identifier, TryOrDefault<TypeList>(&genericSpecializationTypeList)}, {List<std::string>(Sequence({&identifier, Token("::")})), &identifier,
TryOrDefault<TypeList>(&genericSpecializationTypeList)},
MakeIdentifierExpression), MakeIdentifierExpression),
};
// Result: LocationExpression*
Symbol locationExpression = {
Rule({&identifierExpression}),
Rule({&primaryExpression, Token("."), &identifier}, Rule({&primaryExpression, Token("."), &identifier},
MakeFieldAccessExpression), MakeFieldAccessExpression),
Rule({&primaryExpression, Token("["), expression, Token("]")}, Rule({&primaryExpression, Token("["), expression, Token("]")},
...@@ -1211,10 +1225,8 @@ struct TorqueGrammar : Grammar { ...@@ -1211,10 +1225,8 @@ struct TorqueGrammar : Grammar {
{Token("("), List<Expression*>(expression, Token(",")), Token(")")})}; {Token("("), List<Expression*>(expression, Token(",")), Token(")")})};
// Result: Expression* // Result: Expression*
Symbol callExpression = { Symbol callExpression = {Rule(
Rule({&identifier, TryOrDefault<TypeList>(&genericSpecializationTypeList), {&identifierExpression, &argumentList, optionalOtherwise}, MakeCall)};
&argumentList, optionalOtherwise},
MakeCall)};
// Result: Expression* // Result: Expression*
Symbol primaryExpression = { Symbol primaryExpression = {
......
...@@ -343,6 +343,18 @@ TEST(TestCatch3) { ...@@ -343,6 +343,18 @@ TEST(TestCatch3) {
ft.Call(); ft.Call();
} }
TEST(TestLookup) {
Isolate* isolate(CcTest::InitIsolateOnce());
CodeAssemblerTester asm_tester(isolate, 0);
TestBuiltinsFromDSLAssembler m(asm_tester.state());
{
m.TestQualifiedAccess();
m.Return(m.UndefinedConstant());
}
FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -599,6 +599,11 @@ module test { ...@@ -599,6 +599,11 @@ module test {
} }
} }
macro TestQualifiedAccess() {
let s: Smi = 0;
check(!array::IsJSArray(s));
}
macro TestCatch1(context: Context): Smi { macro TestCatch1(context: Context): Smi {
let r: Smi = 0; let r: Smi = 0;
try { try {
...@@ -641,29 +646,25 @@ module test { ...@@ -641,29 +646,25 @@ module test {
return r; return r;
} }
} }
}
// Until we fully support namespaces, put the test for iterators in the
// iterator module so that the macros and builtins are found.
module iterator {
// This test doesn't actually test the functionality of iterators, // This test doesn't actually test the functionality of iterators,
// it's only purpose is to make sure tha the CSA macros in the // it's only purpose is to make sure tha the CSA macros in the
// IteratorBuiltinsAssembler match the signatures provided in // IteratorBuiltinsAssembler match the signatures provided in
// iterator.tq. // iterator.tq.
macro TestIterator(implicit context: Context)(o: Object, map: Map) { macro TestIterator(implicit context: Context)(o: Object, map: Map) {
try { try {
const t1: Object = GetIteratorMethod(o); const t1: Object = iterator::GetIteratorMethod(o);
const t2: IteratorRecord = GetIterator(o); const t2: IteratorRecord = iterator::GetIterator(o);
const t3: Object = IteratorStep(t2) otherwise Fail; const t3: Object = iterator::IteratorStep(t2) otherwise Fail;
const t4: Object = IteratorStep(t2, map) otherwise Fail; const t4: Object = iterator::IteratorStep(t2, map) otherwise Fail;
const t5: Object = IteratorValue(t4); const t5: Object = iterator::IteratorValue(t4);
const t6: Object = IteratorValue(t4, map); const t6: Object = iterator::IteratorValue(t4, map);
IteratorCloseOnException(t2); iterator::IteratorCloseOnException(t2);
const t7: JSArray = IterableToList(t1, t1); const t7: JSArray = iterator::IterableToList(t1, t1);
} }
label Fail {} label Fail {}
} }
......
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