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 {
return ArrayForEachTorqueContinuation(
context, receiver, numberLength, callbackfn, thisArg, k);
}
label Unexpected {
label Unexpected deferred {
unreachable;
}
}
......@@ -101,7 +101,7 @@ module array {
}
}
}
label Slow {
label Slow deferred {
goto Bailout(k);
}
}
......@@ -129,7 +129,7 @@ module array {
otherwise Bailout;
}
}
label Slow {
label Slow deferred {
goto Bailout(k);
}
return Undefined;
......@@ -165,17 +165,17 @@ module array {
return FastArrayForEach(context, o, len, callbackfn, thisArg)
otherwise Bailout;
}
label Bailout(kValue: Smi) {
label Bailout(kValue: Smi) deferred {
k = kValue;
}
return ArrayForEachTorqueContinuation(
context, o, len, callbackfn, thisArg, k);
}
label TypeError {
label TypeError deferred {
ThrowTypeError(context, kCalledNonCallable, arguments[0]);
}
label NullOrUndefinedError {
label NullOrUndefinedError deferred {
ThrowTypeError(
context, kCalledOnNullOrUndefined, 'Array.prototype.forEach');
}
......
......@@ -172,20 +172,23 @@ class Label : public Declarable {
DECLARE_DECLARABLE_BOILERPLATE(Label, label);
void MarkUsed() { used_ = true; }
bool IsUsed() const { return used_; }
bool IsDeferred() const { return deferred_; }
private:
friend class Declarations;
explicit Label(const std::string& name)
explicit Label(const std::string& name, bool deferred = false)
: Declarable(Declarable::kLabel),
name_(name),
generated_("label_" + name + "_" + std::to_string(next_id_++)),
used_(false) {}
used_(false),
deferred_(deferred) {}
std::string name_;
std::string generated_;
std::vector<Variable*> parameters_;
static size_t next_id_;
bool used_;
bool deferred_;
};
class ExternConstant : public Value {
......
......@@ -372,7 +372,9 @@ void DeclarationVisitor::Visit(LogicalAndExpression* expr) {
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);
// Conditional expressions can either explicitly return a bit
// type, or they can be backed by macros that don't return but
......@@ -380,8 +382,8 @@ void DeclarationVisitor::DeclareExpressionForBranch(Expression* node) {
// visiting the conditional expression, those label-based
// macro conditionals will be able to find them through normal
// label lookups.
declarations()->DeclareLabel(kTrueLabelName);
declarations()->DeclareLabel(kFalseLabelName);
declarations()->DeclareLabel(kTrueLabelName, true_statement);
declarations()->DeclareLabel(kFalseLabelName, false_statement);
Visit(node);
}
......@@ -400,7 +402,7 @@ void DeclarationVisitor::Visit(IfStatement* stmt) {
if (!stmt->is_constexpr) {
PushControlSplit();
}
DeclareExpressionForBranch(stmt->condition);
DeclareExpressionForBranch(stmt->condition, stmt->if_true, stmt->if_false);
Visit(stmt->if_true);
if (stmt->if_false) Visit(*stmt->if_false);
if (!stmt->is_constexpr) {
......@@ -465,7 +467,8 @@ void DeclarationVisitor::Visit(TryLabelStatement* stmt) {
// Declare labels
for (LabelBlock* block : stmt->label_blocks) {
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);
if (block->parameters.has_varargs) {
......
......@@ -114,7 +114,9 @@ class DeclarationVisitor : public FileVisitor {
void Visit(LogicalOrExpression* 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(IfStatement* stmt);
......
......@@ -233,9 +233,15 @@ void Declarations::DeclareStruct(Module* module, const std::string& name,
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");
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));
return result;
}
......
......@@ -79,7 +79,8 @@ class Declarations {
void DeclareStruct(Module* module, const std::string& name,
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,
base::Optional<std::string> op = {});
......
......@@ -2012,6 +2012,11 @@ void ImplementationVisitor::GenerateLabelDefinition(Label* label,
source_out() << ", ";
GenerateChangedVarsFromControlSplit(node);
}
if (label->IsDeferred()) {
source_out() << ", compiler::CodeAssemblerLabel::kDeferred";
} else {
source_out() << ", compiler::CodeAssemblerLabel::kNonDeferred";
}
source_out() << ");\n";
GenerateIndent();
source_out() << "Label* " + label_string + " = &" << label_string_impl
......
......@@ -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) {
auto callee = child_results->NextAs<std::string>();
auto generic_args = child_results->NextAs<TypeList>();
......@@ -419,6 +429,7 @@ base::Optional<ParseResult> MakeSpecializationDeclaration(
auto return_type = child_results->NextAs<TypeExpression*>();
auto labels = child_results->NextAs<LabelAndTypesVector>();
auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Declaration* result = MakeNode<SpecializationDeclaration>(
std::move(name), std::move(generic_parameters), std::move(parameters),
return_type, std::move(labels), body);
......@@ -605,6 +616,7 @@ base::Optional<ParseResult> MakeTypeswitchCase(
auto name = child_results->NextAs<base::Optional<std::string>>();
auto type = child_results->NextAs<TypeExpression*>();
auto block = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(block);
return ParseResult{TypeswitchCase{child_results->matched_input().pos,
std::move(name), type, block}};
}
......@@ -614,6 +626,7 @@ base::Optional<ParseResult> MakeWhileStatement(
auto condition = child_results->NextAs<Expression*>();
auto body = child_results->NextAs<Statement*>();
Statement* result = MakeNode<WhileStatement>(condition, body);
CheckNotDeferredStatement(result);
return ParseResult{result};
}
......@@ -682,6 +695,7 @@ base::Optional<ParseResult> MakeBlockStatement(
base::Optional<ParseResult> MakeTryLabelStatement(
ParseResultIterator* child_results) {
auto try_block = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(try_block);
auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>();
Statement* result =
MakeNode<TryLabelStatement>(try_block, std::move(label_blocks));
......@@ -691,9 +705,11 @@ base::Optional<ParseResult> MakeTryLabelStatement(
base::Optional<ParseResult> MakeForOfLoopStatement(
ParseResultIterator* child_results) {
auto var_decl = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(var_decl);
auto iterable = child_results->NextAs<Expression*>();
auto range = child_results->NextAs<base::Optional<RangeExpression>>();
auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Statement* result =
MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body);
return ParseResult{result};
......@@ -705,6 +721,7 @@ base::Optional<ParseResult> MakeForLoopStatement(
auto test = child_results->NextAs<base::Optional<Expression*>>();
auto action = child_results->NextAs<base::Optional<Expression*>>();
auto body = child_results->NextAs<Statement*>();
CheckNotDeferredStatement(body);
Statement* result = MakeNode<ForLoopStatement>(var_decl, test, action, body);
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