Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(941)

Unified Diff: src/rewriter.cc

Issue 1375203004: Fix completion of try..finally. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/ast.h ('K') | « src/ast.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/rewriter.cc
diff --git a/src/rewriter.cc b/src/rewriter.cc
index 11af2bd26246d6fb44ee3fa5cd734f87071dff29..854621ed63ade4718a7ccf57f21860c9f2a15a11 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -13,12 +13,13 @@ namespace internal {
class Processor: public AstVisitor {
public:
- Processor(Isolate* isolate, Variable* result,
+ Processor(Isolate* isolate, Scope* scope, Variable* result,
AstValueFactory* ast_value_factory)
: result_(result),
result_assigned_(false),
replacement_(nullptr),
is_set_(false),
+ scope_(scope),
factory_(ast_value_factory) {
InitializeAstVisitor(isolate, ast_value_factory->zone());
}
@@ -28,6 +29,7 @@ class Processor: public AstVisitor {
void Process(ZoneList<Statement*>* statements);
bool result_assigned() const { return result_assigned_; }
+ Scope* scope() { return scope_; }
AstNodeFactory* factory() { return &factory_; }
private:
@@ -49,8 +51,10 @@ class Processor: public AstVisitor {
// was hoping for.
bool is_set_;
+ Scope* scope_;
AstNodeFactory factory_;
+ // Returns ".result = value"
Expression* SetResult(Expression* value) {
result_assigned_ = true;
VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
@@ -58,6 +62,9 @@ class Processor: public AstVisitor {
Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition);
}
+ // Changes b to ".backup = .result; b; .result = .backup"
+ void BackupAndRestore(Block* b);
rossberg 2015/10/01 09:59:24 Nit: SaveAndRestore would sound more like the typi
neis 2015/10/01 10:56:48 Did that, but I don't think it improved readabilit
+
// Node visitors.
#define DEF_VISIT(type) virtual void Visit##type(type* node) override;
AST_NODE_LIST(DEF_VISIT)
@@ -69,6 +76,24 @@ class Processor: public AstVisitor {
};
+void Processor::BackupAndRestore(Block* b) {
+ Variable* backup = scope()->NewTemporary(
+ factory()->ast_value_factory()->dot_result_string());
+ Expression* backup_proxy = factory()->NewVariableProxy(backup);
+ Expression* result_proxy = factory()->NewVariableProxy(result_);
+ Expression* assignment1 = factory()->NewAssignment(
+ Token::ASSIGN, backup_proxy, result_proxy, RelocInfo::kNoPosition);
+ Expression* assignment2 = factory()->NewAssignment(
+ Token::ASSIGN, result_proxy, backup_proxy, RelocInfo::kNoPosition);
+ b->InsertStatementAt(
+ 0, factory()->NewExpressionStatement(assignment1, RelocInfo::kNoPosition),
+ zone());
+ b->AddStatement(
+ factory()->NewExpressionStatement(assignment2, RelocInfo::kNoPosition),
+ zone());
+}
+
+
void Processor::Process(ZoneList<Statement*>* statements) {
for (int i = statements->length() - 1; i >= 0; --i) {
Visit(statements->at(i));
@@ -167,9 +192,13 @@ void Processor::VisitTryCatchStatement(TryCatchStatement* node) {
void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
// Rewrite both try and finally block (in reverse order).
+ bool set_after = is_set_;
+ is_set_ = true; // Don't normally need to assign in finally block.
Visit(node->finally_block());
node->set_finally_block(replacement_->AsBlock());
- Visit(node->try_block()); // Exception will not be caught.
+ BackupAndRestore(node->finally_block());
+ is_set_ = set_after;
+ Visit(node->try_block());
node->set_try_block(replacement_->AsBlock());
replacement_ = node;
}
@@ -260,7 +289,8 @@ bool Rewriter::Rewrite(ParseInfo* info) {
scope->NewTemporary(info->ast_value_factory()->dot_result_string());
// The name string must be internalized at this point.
DCHECK(!result->name().is_null());
- Processor processor(info->isolate(), result, info->ast_value_factory());
+ Processor processor(info->isolate(), scope, result,
+ info->ast_value_factory());
processor.Process(body);
if (processor.HasStackOverflow()) return false;
« src/ast.h ('K') | « src/ast.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698