OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 23 matching lines...) Expand all Loading... |
35 | 35 |
36 namespace v8 { | 36 namespace v8 { |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 class Processor: public AstVisitor { | 39 class Processor: public AstVisitor { |
40 public: | 40 public: |
41 explicit Processor(Variable* result) | 41 explicit Processor(Variable* result) |
42 : result_(result), | 42 : result_(result), |
43 result_assigned_(false), | 43 result_assigned_(false), |
44 is_set_(false), | 44 is_set_(false), |
45 in_try_(false) { | 45 in_try_(false), |
46 } | 46 factory_(isolate()) { } |
| 47 |
| 48 virtual ~Processor() { } |
47 | 49 |
48 void Process(ZoneList<Statement*>* statements); | 50 void Process(ZoneList<Statement*>* statements); |
49 bool result_assigned() const { return result_assigned_; } | 51 bool result_assigned() const { return result_assigned_; } |
50 | 52 |
| 53 AstNodeFactory<AstNullVisitor>* factory() { |
| 54 return &factory_; |
| 55 } |
| 56 |
51 private: | 57 private: |
52 Variable* result_; | 58 Variable* result_; |
53 | 59 |
54 // We are not tracking result usage via the result_'s use | 60 // We are not tracking result usage via the result_'s use |
55 // counts (we leave the accurate computation to the | 61 // counts (we leave the accurate computation to the |
56 // usage analyzer). Instead we simple remember if | 62 // usage analyzer). Instead we simple remember if |
57 // there was ever an assignment to result_. | 63 // there was ever an assignment to result_. |
58 bool result_assigned_; | 64 bool result_assigned_; |
59 | 65 |
60 // To avoid storing to .result all the time, we eliminate some of | 66 // To avoid storing to .result all the time, we eliminate some of |
61 // the stores by keeping track of whether or not we're sure .result | 67 // the stores by keeping track of whether or not we're sure .result |
62 // will be overwritten anyway. This is a bit more tricky than what I | 68 // will be overwritten anyway. This is a bit more tricky than what I |
63 // was hoping for | 69 // was hoping for |
64 bool is_set_; | 70 bool is_set_; |
65 bool in_try_; | 71 bool in_try_; |
66 | 72 |
| 73 AstNodeFactory<AstNullVisitor> factory_; |
| 74 |
67 Expression* SetResult(Expression* value) { | 75 Expression* SetResult(Expression* value) { |
68 result_assigned_ = true; | 76 result_assigned_ = true; |
69 Zone* zone = isolate()->zone(); | 77 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); |
70 VariableProxy* result_proxy = new(zone) VariableProxy(isolate(), result_); | 78 return factory()->NewAssignment( |
71 return new(zone) Assignment(isolate(), | 79 Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); |
72 Token::ASSIGN, | |
73 result_proxy, | |
74 value, | |
75 RelocInfo::kNoPosition); | |
76 } | 80 } |
77 | 81 |
78 // Node visitors. | 82 // Node visitors. |
79 #define DEF_VISIT(type) \ | 83 #define DEF_VISIT(type) \ |
80 virtual void Visit##type(type* node); | 84 virtual void Visit##type(type* node); |
81 AST_NODE_LIST(DEF_VISIT) | 85 AST_NODE_LIST(DEF_VISIT) |
82 #undef DEF_VISIT | 86 #undef DEF_VISIT |
83 | 87 |
84 void VisitIterationStatement(IterationStatement* stmt); | 88 void VisitIterationStatement(IterationStatement* stmt); |
85 }; | 89 }; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 ZoneList<Statement*>* body = function->body(); | 234 ZoneList<Statement*>* body = function->body(); |
231 if (!body->is_empty()) { | 235 if (!body->is_empty()) { |
232 Variable* result = scope->NewTemporary( | 236 Variable* result = scope->NewTemporary( |
233 info->isolate()->factory()->result_symbol()); | 237 info->isolate()->factory()->result_symbol()); |
234 Processor processor(result); | 238 Processor processor(result); |
235 processor.Process(body); | 239 processor.Process(body); |
236 if (processor.HasStackOverflow()) return false; | 240 if (processor.HasStackOverflow()) return false; |
237 | 241 |
238 if (processor.result_assigned()) { | 242 if (processor.result_assigned()) { |
239 ASSERT(function->end_position() != RelocInfo::kNoPosition); | 243 ASSERT(function->end_position() != RelocInfo::kNoPosition); |
240 Isolate* isolate = info->isolate(); | |
241 Zone* zone = isolate->zone(); | |
242 // Set the position of the assignment statement one character past the | 244 // Set the position of the assignment statement one character past the |
243 // source code, such that it definitely is not in the source code range | 245 // source code, such that it definitely is not in the source code range |
244 // of an immediate inner scope. For example in | 246 // of an immediate inner scope. For example in |
245 // eval('with ({x:1}) x = 1'); | 247 // eval('with ({x:1}) x = 1'); |
246 // the end position of the function generated for executing the eval code | 248 // the end position of the function generated for executing the eval code |
247 // coincides with the end of the with scope which is the position of '1'. | 249 // coincides with the end of the with scope which is the position of '1'. |
248 int position = function->end_position(); | 250 int position = function->end_position(); |
249 VariableProxy* result_proxy = new(zone) VariableProxy( | 251 VariableProxy* result_proxy = processor.factory()->NewVariableProxy( |
250 isolate, result->name(), false, position); | 252 result->name(), false, position); |
251 result_proxy->BindTo(result); | 253 result_proxy->BindTo(result); |
252 Statement* result_statement = new(zone) ReturnStatement(result_proxy); | 254 Statement* result_statement = |
| 255 processor.factory()->NewReturnStatement(result_proxy); |
253 result_statement->set_statement_pos(position); | 256 result_statement->set_statement_pos(position); |
254 body->Add(result_statement); | 257 body->Add(result_statement); |
255 } | 258 } |
256 } | 259 } |
257 | 260 |
258 return true; | 261 return true; |
259 } | 262 } |
260 | 263 |
261 | 264 |
262 } } // namespace v8::internal | 265 } } // namespace v8::internal |
OLD | NEW |