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

[torque] Support deferred keyword on some StatementBlocks

Bug: v8:7793

Change-Id: I3ab2cf1b6190014eff29f6983c27872b4d79a9dc
Reviewed-on: https://chromium-review.googlesource.com/1233760
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56134}
parent 32c06197
...@@ -67,7 +67,7 @@ module array { ...@@ -67,7 +67,7 @@ module array {
return ArrayForEachTorqueContinuation( return ArrayForEachTorqueContinuation(
context, receiver, numberLength, callbackfn, thisArg, k); context, receiver, numberLength, callbackfn, thisArg, k);
} }
label Unexpected { label Unexpected deferred {
unreachable; unreachable;
} }
} }
...@@ -101,7 +101,7 @@ module array { ...@@ -101,7 +101,7 @@ module array {
} }
} }
} }
label Slow { label Slow deferred {
goto Bailout(k); goto Bailout(k);
} }
} }
...@@ -129,7 +129,7 @@ module array { ...@@ -129,7 +129,7 @@ module array {
otherwise Bailout; otherwise Bailout;
} }
} }
label Slow { label Slow deferred {
goto Bailout(k); goto Bailout(k);
} }
return Undefined; return Undefined;
...@@ -165,17 +165,17 @@ module array { ...@@ -165,17 +165,17 @@ module array {
return FastArrayForEach(context, o, len, callbackfn, thisArg) return FastArrayForEach(context, o, len, callbackfn, thisArg)
otherwise Bailout; otherwise Bailout;
} }
label Bailout(kValue: Smi) { label Bailout(kValue: Smi) deferred {
k = kValue; k = kValue;
} }
return ArrayForEachTorqueContinuation( return ArrayForEachTorqueContinuation(
context, o, len, callbackfn, thisArg, k); context, o, len, callbackfn, thisArg, k);
} }
label TypeError { label TypeError deferred {
ThrowTypeError(context, kCalledNonCallable, arguments[0]); ThrowTypeError(context, kCalledNonCallable, arguments[0]);
} }
label NullOrUndefinedError { label NullOrUndefinedError deferred {
ThrowTypeError( ThrowTypeError(
context, kCalledOnNullOrUndefined, 'Array.prototype.forEach'); context, kCalledOnNullOrUndefined, 'Array.prototype.forEach');
} }
......
...@@ -172,20 +172,23 @@ class Label : public Declarable { ...@@ -172,20 +172,23 @@ class Label : public Declarable {
DECLARE_DECLARABLE_BOILERPLATE(Label, label); DECLARE_DECLARABLE_BOILERPLATE(Label, label);
void MarkUsed() { used_ = true; } void MarkUsed() { used_ = true; }
bool IsUsed() const { return used_; } bool IsUsed() const { return used_; }
bool IsDeferred() const { return deferred_; }
private: private:
friend class Declarations; friend class Declarations;
explicit Label(const std::string& name) explicit Label(const std::string& name, bool deferred = false)
: Declarable(Declarable::kLabel), : Declarable(Declarable::kLabel),
name_(name), name_(name),
generated_("label_" + name + "_" + std::to_string(next_id_++)), generated_("label_" + name + "_" + std::to_string(next_id_++)),
used_(false) {} used_(false),
deferred_(deferred) {}
std::string name_; std::string name_;
std::string generated_; std::string generated_;
std::vector<Variable*> parameters_; std::vector<Variable*> parameters_;
static size_t next_id_; static size_t next_id_;
bool used_; bool used_;
bool deferred_;
}; };
class ExternConstant : public Value { class ExternConstant : public Value {
......
...@@ -372,7 +372,9 @@ void DeclarationVisitor::Visit(LogicalAndExpression* expr) { ...@@ -372,7 +372,9 @@ void DeclarationVisitor::Visit(LogicalAndExpression* expr) {
Visit(expr->right); Visit(expr->right);
} }
void DeclarationVisitor::DeclareExpressionForBranch(Expression* node) { void DeclarationVisitor::DeclareExpressionForBranch(
Expression* node, base::Optional<Statement*> true_statement,
base::Optional<Statement*> false_statement) {
Declarations::NodeScopeActivator scope(declarations(), node); Declarations::NodeScopeActivator scope(declarations(), node);
// Conditional expressions can either explicitly return a bit // Conditional expressions can either explicitly return a bit
// type, or they can be backed by macros that don't return but // type, or they can be backed by macros that don't return but
...@@ -380,8 +382,8 @@ void DeclarationVisitor::DeclareExpressionForBranch(Expression* node) { ...@@ -380,8 +382,8 @@ void DeclarationVisitor::DeclareExpressionForBranch(Expression* node) {
// visiting the conditional expression, those label-based // visiting the conditional expression, those label-based
// macro conditionals will be able to find them through normal // macro conditionals will be able to find them through normal
// label lookups. // label lookups.
declarations()->DeclareLabel(kTrueLabelName); declarations()->DeclareLabel(kTrueLabelName, true_statement);
declarations()->DeclareLabel(kFalseLabelName); declarations()->DeclareLabel(kFalseLabelName, false_statement);
Visit(node); Visit(node);
} }
...@@ -400,7 +402,7 @@ void DeclarationVisitor::Visit(IfStatement* stmt) { ...@@ -400,7 +402,7 @@ void DeclarationVisitor::Visit(IfStatement* stmt) {
if (!stmt->is_constexpr) { if (!stmt->is_constexpr) {
PushControlSplit(); PushControlSplit();
} }
DeclareExpressionForBranch(stmt->condition); DeclareExpressionForBranch(stmt->condition, stmt->if_true, stmt->if_false);
Visit(stmt->if_true); Visit(stmt->if_true);
if (stmt->if_false) Visit(*stmt->if_false); if (stmt->if_false) Visit(*stmt->if_false);
if (!stmt->is_constexpr) { if (!stmt->is_constexpr) {
...@@ -465,7 +467,8 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) { ...@@ -465,7 +467,8 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) {
// Declare labels // Declare labels
for (LabelBlock* block : stmt->label_blocks) { for (LabelBlock* block : stmt->label_blocks) {
CurrentSourcePosition::Scope scope(block->pos); CurrentSourcePosition::Scope scope(block->pos);
Label* shared_label = declarations()->DeclareLabel(block->label); Label* shared_label =
declarations()->DeclareLabel(block->label, block->body);
{ {
Declarations::NodeScopeActivator scope(declarations(), block->body); Declarations::NodeScopeActivator scope(declarations(), block->body);
if (block->parameters.has_varargs) { if (block->parameters.has_varargs) {
......
...@@ -114,7 +114,9 @@ class DeclarationVisitor : public FileVisitor { ...@@ -114,7 +114,9 @@ class DeclarationVisitor : public FileVisitor {
void Visit(LogicalOrExpression* expr); void Visit(LogicalOrExpression* expr);
void Visit(LogicalAndExpression* expr); void Visit(LogicalAndExpression* expr);
void DeclareExpressionForBranch(Expression* node); void DeclareExpressionForBranch(
Expression* node, base::Optional<Statement*> true_statement = {},
base::Optional<Statement*> false_statement = {});
void Visit(ConditionalExpression* expr); void Visit(ConditionalExpression* expr);
void Visit(IfStatement* stmt); void Visit(IfStatement* stmt);
......
...@@ -233,9 +233,15 @@ void Declarations::DeclareStruct(Module* module, const std::string& name, ...@@ -233,9 +233,15 @@ void Declarations::DeclareStruct(Module* module, const std::string& name,
DeclareType(name, new_type); DeclareType(name, new_type);
} }
Label* Declarations::DeclareLabel(const std::string& name) { Label* Declarations::DeclareLabel(const std::string& name,
base::Optional<Statement*> statement) {
CheckAlreadyDeclared(name, "label"); CheckAlreadyDeclared(name, "label");
Label* result = new Label(name); bool deferred = false;
if (statement) {
BlockStatement* block = BlockStatement::DynamicCast(*statement);
deferred = block && block->deferred;
}
Label* result = new Label(name, deferred);
Declare(name, std::unique_ptr<Declarable>(result)); Declare(name, std::unique_ptr<Declarable>(result));
return result; return result;
} }
......
...@@ -79,7 +79,8 @@ class Declarations { ...@@ -79,7 +79,8 @@ class Declarations {
void DeclareStruct(Module* module, const std::string& name, void DeclareStruct(Module* module, const std::string& name,
const std::vector<NameAndType>& fields); const std::vector<NameAndType>& fields);
Label* DeclareLabel(const std::string& name); Label* DeclareLabel(const std::string& name,
base::Optional<Statement*> statement = {});
Macro* DeclareMacro(const std::string& name, const Signature& signature, Macro* DeclareMacro(const std::string& name, const Signature& signature,
base::Optional<std::string> op = {}); base::Optional<std::string> op = {});
......
...@@ -2012,6 +2012,11 @@ void ImplementationVisitor::GenerateLabelDefinition(Label* label, ...@@ -2012,6 +2012,11 @@ void ImplementationVisitor::GenerateLabelDefinition(Label* label,
source_out() << ", "; source_out() << ", ";
GenerateChangedVarsFromControlSplit(node); GenerateChangedVarsFromControlSplit(node);
} }
if (label->IsDeferred()) {
source_out() << ", compiler::CodeAssemblerLabel::kDeferred";
} else {
source_out() << ", compiler::CodeAssemblerLabel::kNonDeferred";
}
source_out() << ");\n"; source_out() << ");\n";
GenerateIndent(); GenerateIndent();
source_out() << "Label* " + label_string + " = &" << label_string_impl source_out() << "Label* " + label_string + " = &" << label_string_impl
......
...@@ -191,6 +191,16 @@ void LintGenericParameters(const GenericParameters& parameters) { ...@@ -191,6 +191,16 @@ void LintGenericParameters(const GenericParameters& parameters) {
} }
} }
void CheckNotDeferredStatement(Statement* statement) {
if (BlockStatement* block = BlockStatement::DynamicCast(statement)) {
if (block->deferred) {
LintError(
"cannot use deferred with a statement block here, it will have no "
"effect");
}
}
}
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<std::string>();
auto generic_args = child_results->NextAs<TypeList>(); auto generic_args = child_results->NextAs<TypeList>();
...@@ -419,6 +429,7 @@ base::Optional<ParseResult> MakeSpecializationDeclaration( ...@@ -419,6 +429,7 @@ base::Optional<ParseResult> MakeSpecializationDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>(); auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>(); auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<Statement*>(); auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Declaration* result = MakeNode<SpecializationDeclaration>( Declaration* result = MakeNode<SpecializationDeclaration>(
std::move(name), std::move(generic_parameters), std::move(parameters), std::move(name), std::move(generic_parameters), std::move(parameters),
return_type, std::move(labels), body); return_type, std::move(labels), body);
...@@ -605,6 +616,7 @@ base::Optional<ParseResult> MakeTypeswitchCase( ...@@ -605,6 +616,7 @@ base::Optional<ParseResult> MakeTypeswitchCase(
auto name = child_results->NextAs<base::Optional<std::string>>(); auto name = child_results->NextAs<base::Optional<std::string>>();
auto type = child_results->NextAs<TypeExpression*>(); auto type = child_results->NextAs<TypeExpression*>();
auto block = child_results->NextAs<Statement*>(); auto block = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(block);
return ParseResult{TypeswitchCase{child_results->matched_input().pos, return ParseResult{TypeswitchCase{child_results->matched_input().pos,
std::move(name), type, block}}; std::move(name), type, block}};
} }
...@@ -614,6 +626,7 @@ base::Optional<ParseResult> MakeWhileStatement( ...@@ -614,6 +626,7 @@ base::Optional<ParseResult> MakeWhileStatement(
auto condition = child_results->NextAs<Expression*>(); auto condition = child_results->NextAs<Expression*>();
auto body = child_results->NextAs<Statement*>(); auto body = child_results->NextAs<Statement*>();
Statement* result = MakeNode<WhileStatement>(condition, body); Statement* result = MakeNode<WhileStatement>(condition, body);
CheckNotDeferredStatement(result);
return ParseResult{result}; return ParseResult{result};
} }
...@@ -682,6 +695,7 @@ base::Optional<ParseResult> MakeBlockStatement( ...@@ -682,6 +695,7 @@ base::Optional<ParseResult> MakeBlockStatement(
base::Optional<ParseResult> MakeTryLabelStatement( base::Optional<ParseResult> MakeTryLabelStatement(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto try_block = child_results->NextAs<Statement*>(); auto try_block = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(try_block);
auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>(); auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>();
Statement* result = Statement* result =
MakeNode<TryLabelStatement>(try_block, std::move(label_blocks)); MakeNode<TryLabelStatement>(try_block, std::move(label_blocks));
...@@ -691,9 +705,11 @@ base::Optional<ParseResult> MakeTryLabelStatement( ...@@ -691,9 +705,11 @@ base::Optional<ParseResult> MakeTryLabelStatement(
base::Optional<ParseResult> MakeForOfLoopStatement( base::Optional<ParseResult> MakeForOfLoopStatement(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto var_decl = child_results->NextAs<Statement*>(); auto var_decl = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(var_decl);
auto iterable = child_results->NextAs<Expression*>(); auto iterable = child_results->NextAs<Expression*>();
auto range = child_results->NextAs<base::Optional<RangeExpression>>(); auto range = child_results->NextAs<base::Optional<RangeExpression>>();
auto body = child_results->NextAs<Statement*>(); auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Statement* result = Statement* result =
MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body); MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body);
return ParseResult{result}; return ParseResult{result};
...@@ -705,6 +721,7 @@ base::Optional<ParseResult> MakeForLoopStatement( ...@@ -705,6 +721,7 @@ base::Optional<ParseResult> MakeForLoopStatement(
auto test = child_results->NextAs<base::Optional<Expression*>>(); auto test = child_results->NextAs<base::Optional<Expression*>>();
auto action = child_results->NextAs<base::Optional<Expression*>>(); auto action = child_results->NextAs<base::Optional<Expression*>>();
auto body = child_results->NextAs<Statement*>(); auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Statement* result = MakeNode<ForLoopStatement>(var_decl, test, action, body); Statement* result = MakeNode<ForLoopStatement>(var_decl, test, action, body);
return ParseResult{result}; return ParseResult{result};
} }
......
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