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

Side by Side Diff: src/rewriter.cc

Issue 1399893002: [es7] implement |do| expressions proposal (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Some cleanup Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/rewriter.h" 5 #include "src/rewriter.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/parser.h" 8 #include "src/parser.h"
9 #include "src/scopes.h" 9 #include "src/scopes.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 class Processor: public AstVisitor { 14 class Processor: public AstVisitor {
15 public: 15 public:
16 Processor(Isolate* isolate, Scope* scope, Variable* result, 16 Processor(Isolate* isolate, Scope* scope, Variable* result,
17 AstValueFactory* ast_value_factory) 17 AstValueFactory* ast_value_factory)
18 : result_(result), 18 : result_(result),
19 result_assigned_(false), 19 result_assigned_(false),
20 replacement_(nullptr), 20 replacement_(nullptr),
21 is_set_(false), 21 is_set_(false),
22 scope_(scope), 22 scope_(scope),
23 factory_(ast_value_factory) { 23 factory_(ast_value_factory) {
24 InitializeAstVisitor(isolate, ast_value_factory->zone()); 24 InitializeAstVisitor(isolate, ast_value_factory->zone());
25 } 25 }
26 26
27 Processor(Parser* parser, Scope* scope, Variable* result,
28 AstValueFactory* ast_value_factory)
29 : result_(result),
30 result_assigned_(false),
31 replacement_(nullptr),
32 is_set_(false),
33 scope_(scope),
34 factory_(ast_value_factory) {
35 InitializeAstVisitor(nullptr, ast_value_factory->zone());
36 parser_ = parser;
37 }
38
27 virtual ~Processor() { } 39 virtual ~Processor() { }
28 40
29 void Process(ZoneList<Statement*>* statements); 41 void Process(ZoneList<Statement*>* statements);
30 bool result_assigned() const { return result_assigned_; } 42 bool result_assigned() const { return result_assigned_; }
31 43
32 Scope* scope() { return scope_; } 44 Scope* scope() { return scope_; }
33 AstNodeFactory* factory() { return &factory_; } 45 AstNodeFactory* factory() { return &factory_; }
34 46
47 // Returns ".result = value"
rossberg 2015/10/13 10:44:33 Why are these public now?
caitp (gmail) 2015/10/13 15:05:59 SetResult is used by the do expression rewriter, i
48 Expression* SetResult(Expression* value) {
49 result_assigned_ = true;
50 VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
51 return factory()->NewAssignment(Token::ASSIGN, result_proxy, value,
52 RelocInfo::kNoPosition);
53 }
54
55 // Inserts '.result = undefined' in front of the given statement.
56 Statement* AssignUndefinedBefore(Statement* s);
57
35 private: 58 private:
36 Variable* result_; 59 Variable* result_;
37 60
38 // We are not tracking result usage via the result_'s use 61 // We are not tracking result usage via the result_'s use
39 // counts (we leave the accurate computation to the 62 // counts (we leave the accurate computation to the
40 // usage analyzer). Instead we simple remember if 63 // usage analyzer). Instead we simple remember if
41 // there was ever an assignment to result_. 64 // there was ever an assignment to result_.
42 bool result_assigned_; 65 bool result_assigned_;
43 66
44 // When visiting a node, we "return" a replacement for that node in 67 // When visiting a node, we "return" a replacement for that node in
45 // [replacement_]. In many cases this will just be the original node. 68 // [replacement_]. In many cases this will just be the original node.
46 Statement* replacement_; 69 Statement* replacement_;
47 70
48 // To avoid storing to .result all the time, we eliminate some of 71 // To avoid storing to .result all the time, we eliminate some of
49 // the stores by keeping track of whether or not we're sure .result 72 // the stores by keeping track of whether or not we're sure .result
50 // will be overwritten anyway. This is a bit more tricky than what I 73 // will be overwritten anyway. This is a bit more tricky than what I
51 // was hoping for. 74 // was hoping for.
52 bool is_set_; 75 bool is_set_;
53 76
54 Scope* scope_; 77 Scope* scope_;
55 AstNodeFactory factory_; 78 AstNodeFactory factory_;
56 79
57 // Returns ".result = value"
58 Expression* SetResult(Expression* value) {
59 result_assigned_ = true;
60 VariableProxy* result_proxy = factory()->NewVariableProxy(result_);
61 return factory()->NewAssignment(
62 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition);
63 }
64
65 // Inserts '.result = undefined' in front of the given statement.
66 Statement* AssignUndefinedBefore(Statement* s);
67
68 // Node visitors. 80 // Node visitors.
69 #define DEF_VISIT(type) virtual void Visit##type(type* node) override; 81 #define DEF_VISIT(type) virtual void Visit##type(type* node) override;
70 AST_NODE_LIST(DEF_VISIT) 82 AST_NODE_LIST(DEF_VISIT)
71 #undef DEF_VISIT 83 #undef DEF_VISIT
72 84
73 void VisitIterationStatement(IterationStatement* stmt); 85 void VisitIterationStatement(IterationStatement* stmt);
74 86
75 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 87 public:
88 void Visit(AstNode* node) final {
89 if (!CheckStackOverflow()) node->Accept(this);
90 }
91
92 void SetStackOverflow() { stack_overflow_ = true; }
93 void ClearStackOverflow() { stack_overflow_ = false; }
94 bool HasStackOverflow() const { return stack_overflow_; }
95
96 bool CheckStackOverflow() {
97 if (stack_overflow_) return true;
98 if (isolate_) {
99 StackLimitCheck check(isolate_);
100 if (!check.HasOverflowed()) return false;
101 stack_overflow_ = true;
102 } else {
103 if (!parser_->CheckStackOverflow()) return false;
104 stack_overflow_ = true;
105 }
106 return true;
107 }
108
109 private:
110 void InitializeAstVisitor(Isolate* isolate, Zone* zone) {
111 isolate_ = isolate;
112 zone_ = zone;
113 stack_overflow_ = false;
114 }
115 Zone* zone() { return zone_; }
116 Isolate* isolate() { return isolate_; }
117
118 Isolate* isolate_;
119 Parser* parser_;
120 Zone* zone_;
121 bool stack_overflow_;
76 }; 122 };
77 123
78 124
79 Statement* Processor::AssignUndefinedBefore(Statement* s) { 125 Statement* Processor::AssignUndefinedBefore(Statement* s) {
80 Expression* result_proxy = factory()->NewVariableProxy(result_); 126 Expression* result_proxy = factory()->NewVariableProxy(result_);
81 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 127 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
82 Expression* assignment = factory()->NewAssignment( 128 Expression* assignment = factory()->NewAssignment(
83 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition); 129 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition);
84 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 130 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
85 b->statements()->Add( 131 b->statements()->Add(
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 Statement* result_statement = 398 Statement* result_statement =
353 processor.factory()->NewReturnStatement(result_proxy, pos); 399 processor.factory()->NewReturnStatement(result_proxy, pos);
354 body->Add(result_statement, info->zone()); 400 body->Add(result_statement, info->zone());
355 } 401 }
356 } 402 }
357 403
358 return true; 404 return true;
359 } 405 }
360 406
361 407
408 bool Rewriter::Rewrite(Parser* parser, DoExpression* expr,
409 AstValueFactory* factory) {
410 Block* block = expr->block();
411 Scope* scope = block->scope();
412 ZoneList<Statement*>* body = block->statements();
413 VariableProxy* result = expr->result();
414 Variable* result_var = result->var();
415
416 if (!body->is_empty()) {
417 Processor processor(parser, scope, result_var, factory);
418 processor.Process(body);
419 if (processor.HasStackOverflow()) return false;
420
421 if (!processor.result_assigned()) {
422 AstNodeFactory* node_factory = processor.factory();
423 Expression* undef =
424 node_factory->NewUndefinedLiteral(RelocInfo::kNoPosition);
425 Statement* completion = node_factory->NewExpressionStatement(
426 processor.SetResult(undef), expr->position());
427 body->Add(completion, factory->zone());
428 }
429 }
430 return true;
431 }
432
433
362 } // namespace internal 434 } // namespace internal
363 } // namespace v8 435 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698