Commit b07d55f5 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Allow function pointers to generic builtins.

This CL adds grammar support for function pointers to generic builtins.
It also instantiates generic specializations when they are only used
in an assignment to a function pointer.

Example:

builtin GenericBuiltinTest<T: type>(c: Context, param: T): Object {
  return Null;
}

let fnptr: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;

Change-Id: Ib7e5f47ffc05f14eb5d0b789936587263dfb961d
Reviewed-on: https://chromium-review.googlesource.com/1068731
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53284}
parent ccee44e1
...@@ -188,7 +188,7 @@ unaryExpression ...@@ -188,7 +188,7 @@ unaryExpression
| op=(PLUS | MINUS | BIT_NOT | NOT) unaryExpression; | op=(PLUS | MINUS | BIT_NOT | NOT) unaryExpression;
locationExpression locationExpression
: IDENTIFIER : IDENTIFIER genericSpecializationTypeList?
| locationExpression '.' IDENTIFIER | locationExpression '.' IDENTIFIER
| locationExpression '[' expression ']'; | locationExpression '[' expression ']';
...@@ -229,7 +229,7 @@ helperCall: (MIN | MAX | IDENTIFIER) genericSpecializationTypeList? argumentList ...@@ -229,7 +229,7 @@ helperCall: (MIN | MAX | IDENTIFIER) genericSpecializationTypeList? argumentList
labelReference: IDENTIFIER; labelReference: IDENTIFIER;
variableDeclaration: LET IDENTIFIER ':' type; variableDeclaration: LET IDENTIFIER ':' type;
variableDeclarationWithInitialization: variableDeclaration ('=' expression)?; variableDeclarationWithInitialization: variableDeclaration (ASSIGNMENT expression)?;
helperCallStatement: (TAIL)? helperCall; helperCallStatement: (TAIL)? helperCall;
expressionStatement: assignment; expressionStatement: assignment;
ifStatement: IF CONSTEXPR? '(' expression ')' statementBlock ('else' statementBlock)?; ifStatement: IF CONSTEXPR? '(' expression ')' statementBlock ('else' statementBlock)?;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -655,6 +655,7 @@ class TorqueParser : public antlr4::Parser { ...@@ -655,6 +655,7 @@ class TorqueParser : public antlr4::Parser {
size_t invokingState); size_t invokingState);
size_t getRuleIndex() const override; size_t getRuleIndex() const override;
antlr4::tree::TerminalNode* IDENTIFIER(); antlr4::tree::TerminalNode* IDENTIFIER();
GenericSpecializationTypeListContext* genericSpecializationTypeList();
LocationExpressionContext* locationExpression(); LocationExpressionContext* locationExpression();
ExpressionContext* expression(); ExpressionContext* expression();
...@@ -913,6 +914,7 @@ class TorqueParser : public antlr4::Parser { ...@@ -913,6 +914,7 @@ class TorqueParser : public antlr4::Parser {
antlr4::ParserRuleContext* parent, size_t invokingState); antlr4::ParserRuleContext* parent, size_t invokingState);
size_t getRuleIndex() const override; size_t getRuleIndex() const override;
VariableDeclarationContext* variableDeclaration(); VariableDeclarationContext* variableDeclaration();
antlr4::tree::TerminalNode* ASSIGNMENT();
ExpressionContext* expression(); ExpressionContext* expression();
void enterRule(antlr4::tree::ParseTreeListener* listener) override; void enterRule(antlr4::tree::ParseTreeListener* listener) override;
......
...@@ -583,8 +583,14 @@ antlrcpp::Any AstGenerator::visitLocationExpression( ...@@ -583,8 +583,14 @@ antlrcpp::Any AstGenerator::visitLocationExpression(
Pos(context), location, Pos(context), location,
context->IDENTIFIER()->getSymbol()->getText()})); context->IDENTIFIER()->getSymbol()->getText()}));
} }
std::vector<TypeExpression*> templateArguments;
if (context->genericSpecializationTypeList()) {
templateArguments =
GetTypeVector(context->genericSpecializationTypeList()->typeList());
}
return implicit_cast<Expression*>(RegisterNode(new IdentifierExpression{ return implicit_cast<Expression*>(RegisterNode(new IdentifierExpression{
Pos(context), context->IDENTIFIER()->getSymbol()->getText()})); Pos(context), context->IDENTIFIER()->getSymbol()->getText(),
std::move(templateArguments)}));
} }
antlrcpp::Any AstGenerator::visitUnaryExpression( antlrcpp::Any AstGenerator::visitUnaryExpression(
......
...@@ -235,9 +235,13 @@ class Ast { ...@@ -235,9 +235,13 @@ class Ast {
struct IdentifierExpression : LocationExpression { struct IdentifierExpression : LocationExpression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(IdentifierExpression)
IdentifierExpression(SourcePosition p, std::string n) IdentifierExpression(SourcePosition p, std::string n,
: LocationExpression(kKind, p), name(std::move(n)) {} std::vector<TypeExpression*> args)
: LocationExpression(kKind, p),
name(std::move(n)),
generic_arguments(std::move(args)) {}
std::string name; std::string name;
std::vector<TypeExpression*> generic_arguments;
}; };
struct CallExpression : Expression { struct CallExpression : Expression {
...@@ -246,14 +250,12 @@ struct CallExpression : Expression { ...@@ -246,14 +250,12 @@ struct CallExpression : Expression {
std::vector<TypeExpression*> ga, std::vector<Expression*> a, std::vector<TypeExpression*> ga, std::vector<Expression*> a,
std::vector<std::string> l) std::vector<std::string> l)
: Expression(kKind, p), : Expression(kKind, p),
callee(p, std::move(c)), callee(p, std::move(c), std::move(ga)),
is_operator(o), is_operator(o),
generic_arguments(ga),
arguments(std::move(a)), arguments(std::move(a)),
labels(l) {} labels(l) {}
IdentifierExpression callee; IdentifierExpression callee;
bool is_operator; bool is_operator;
std::vector<TypeExpression*> generic_arguments;
std::vector<Expression*> arguments; std::vector<Expression*> arguments;
std::vector<std::string> labels; std::vector<std::string> labels;
}; };
......
...@@ -302,9 +302,9 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) { ...@@ -302,9 +302,9 @@ void DeclarationVisitor::Visit(TryCatchStatement* stmt) {
} }
} }
void DeclarationVisitor::Visit(CallExpression* expr) { void DeclarationVisitor::Visit(IdentifierExpression* expr) {
if (expr->generic_arguments.size() != 0) { if (expr->generic_arguments.size() != 0) {
Generic* generic = declarations()->LookupGeneric(expr->callee.name); Generic* generic = declarations()->LookupGeneric(expr->name);
TypeVector specialization_types; TypeVector specialization_types;
for (auto t : expr->generic_arguments) { for (auto t : expr->generic_arguments) {
specialization_types.push_back(declarations()->GetType(t)); specialization_types.push_back(declarations()->GetType(t));
...@@ -314,7 +314,10 @@ void DeclarationVisitor::Visit(CallExpression* expr) { ...@@ -314,7 +314,10 @@ void DeclarationVisitor::Visit(CallExpression* expr) {
callable->signature.get(), callable->signature.get(),
generic->declaration()->body); generic->declaration()->body);
} }
}
void DeclarationVisitor::Visit(CallExpression* expr) {
Visit(&expr->callee);
for (Expression* arg : expr->arguments) Visit(arg); for (Expression* arg : expr->arguments) Visit(arg);
} }
......
...@@ -50,7 +50,7 @@ class DeclarationVisitor : public FileVisitor { ...@@ -50,7 +50,7 @@ class DeclarationVisitor : public FileVisitor {
Visit(implicit_cast<ModuleDeclaration*>(decl)); Visit(implicit_cast<ModuleDeclaration*>(decl));
} }
void Visit(IdentifierExpression* expr) {} void Visit(IdentifierExpression* expr);
void Visit(NumberLiteralExpression* expr) {} void Visit(NumberLiteralExpression* expr) {}
void Visit(StringLiteralExpression* expr) {} void Visit(StringLiteralExpression* expr) {}
void Visit(CallExpression* expr); void Visit(CallExpression* expr);
......
...@@ -500,6 +500,25 @@ VisitResult ImplementationVisitor::GetBuiltinCode(Builtin* builtin) { ...@@ -500,6 +500,25 @@ VisitResult ImplementationVisitor::GetBuiltinCode(Builtin* builtin) {
return VisitResult(type, code); return VisitResult(type, code);
} }
VisitResult ImplementationVisitor::Visit(IdentifierExpression* expr) {
std::string name = expr->name;
if (expr->generic_arguments.size() != 0) {
Generic* generic = declarations()->LookupGeneric(expr->name);
TypeVector specialization_types = GetTypeVector(expr->generic_arguments);
name = GetGeneratedCallableName(name, specialization_types);
CallableNode* callable = generic->declaration()->callable;
QueueGenericSpecialization({generic, specialization_types}, callable,
callable->signature.get(),
generic->declaration()->body);
}
if (Builtin* builtin = Builtin::DynamicCast(declarations()->Lookup(name))) {
return GetBuiltinCode(builtin);
}
return GenerateFetchFromLocation(expr, GetLocationReference(expr));
}
VisitResult ImplementationVisitor::Visit(CastExpression* expr) { VisitResult ImplementationVisitor::Visit(CastExpression* expr) {
Arguments args; Arguments args;
args.parameters = {Visit(expr->value)}; args.parameters = {Visit(expr->value)};
...@@ -1447,10 +1466,11 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr, ...@@ -1447,10 +1466,11 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
bool is_tailcall) { bool is_tailcall) {
Arguments arguments; Arguments arguments;
std::string name = expr->callee.name; std::string name = expr->callee.name;
bool has_template_arguments = expr->generic_arguments.size() != 0; bool has_template_arguments = expr->callee.generic_arguments.size() != 0;
if (has_template_arguments) { if (has_template_arguments) {
Generic* generic = declarations()->LookupGeneric(expr->callee.name); Generic* generic = declarations()->LookupGeneric(expr->callee.name);
TypeVector specialization_types = GetTypeVector(expr->generic_arguments); TypeVector specialization_types =
GetTypeVector(expr->callee.generic_arguments);
name = GetGeneratedCallableName(name, specialization_types); name = GetGeneratedCallableName(name, specialization_types);
CallableNode* callable = generic->declaration()->callable; CallableNode* callable = generic->declaration()->callable;
QueueGenericSpecialization({generic, specialization_types}, callable, QueueGenericSpecialization({generic, specialization_types}, callable,
......
...@@ -75,13 +75,7 @@ class ImplementationVisitor : public FileVisitor { ...@@ -75,13 +75,7 @@ class ImplementationVisitor : public FileVisitor {
VisitResult GetBuiltinCode(Builtin* builtin); VisitResult GetBuiltinCode(Builtin* builtin);
VisitResult Visit(IdentifierExpression* expr) { VisitResult Visit(IdentifierExpression* expr);
if (Builtin* builtin =
Builtin::DynamicCast(declarations()->Lookup(expr->name))) {
return GetBuiltinCode(builtin);
}
return GenerateFetchFromLocation(expr, GetLocationReference(expr));
}
VisitResult Visit(FieldAccessExpression* expr) { VisitResult Visit(FieldAccessExpression* expr) {
return GenerateFetchFromLocation(expr, GetLocationReference(expr)); return GenerateFetchFromLocation(expr, GetLocationReference(expr));
} }
......
...@@ -41,6 +41,7 @@ TEST(TestConstexpr1) { ...@@ -41,6 +41,7 @@ TEST(TestConstexpr1) {
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
} }
TEST(TestConstexprIf) { TEST(TestConstexprIf) {
...@@ -52,6 +53,7 @@ TEST(TestConstexprIf) { ...@@ -52,6 +53,7 @@ TEST(TestConstexprIf) {
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
} }
TEST(TestConstexprReturn) { TEST(TestConstexprReturn) {
...@@ -63,6 +65,7 @@ TEST(TestConstexprReturn) { ...@@ -63,6 +65,7 @@ TEST(TestConstexprReturn) {
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
} }
TEST(TestGotoLabel) { TEST(TestGotoLabel) {
...@@ -111,6 +114,7 @@ TEST(TestBuiltinSpecialization) { ...@@ -111,6 +114,7 @@ TEST(TestBuiltinSpecialization) {
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
} }
TEST(TestMacroSpecialization) { TEST(TestMacroSpecialization) {
...@@ -122,6 +126,7 @@ TEST(TestMacroSpecialization) { ...@@ -122,6 +126,7 @@ TEST(TestMacroSpecialization) {
m.Return(m.UndefinedConstant()); m.Return(m.UndefinedConstant());
} }
FunctionTester ft(asm_tester.GenerateCode(), 0); FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
} }
TEST(TestFunctionPointers) { TEST(TestFunctionPointers) {
...@@ -138,6 +143,19 @@ TEST(TestFunctionPointers) { ...@@ -138,6 +143,19 @@ TEST(TestFunctionPointers) {
ft.CheckCall(ft.true_value()); ft.CheckCall(ft.true_value());
} }
TEST(TestFunctionPointerToGeneric) {
Isolate* isolate(CcTest::InitIsolateOnce());
CodeAssemblerTester asm_tester(isolate, 0);
TestBuiltinsFromDSLAssembler m(asm_tester.state());
{
Node* temp = m.SmiConstant(0);
m.TestFunctionPointerToGeneric(m.UncheckedCast<Context>(temp));
m.Return(m.UndefinedConstant());
}
FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.Call();
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -179,4 +179,14 @@ module test { ...@@ -179,4 +179,14 @@ module test {
let var2 : Number = 42 == 0 ? 1 : 0; let var2 : Number = 42 == 0 ? 1 : 0;
return True; return True;
} }
macro TestFunctionPointerToGeneric(c: Context) {
let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;
let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest<Object>;
assert(fptr1(c, 0) == Null);
assert(fptr1(c, 1) == Null);
assert(fptr2(c, Undefined) == Undefined);
assert(fptr2(c, Undefined) == Undefined);
}
} }
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