blob: 9c02ff48e10211ca4cc8df5c9db6cf6192463584 [file] [log] [blame]
Leon Clarke4515c472010-02-03 11:58:03 +00001// Copyright 2010 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "data-flow.h"
Steve Block6ded16b2010-05-10 14:33:55 +010031#include "scopes.h"
Leon Clarke4515c472010-02-03 11:58:03 +000032
33namespace v8 {
34namespace internal {
35
Steve Block6ded16b2010-05-10 14:33:55 +010036#ifdef DEBUG
37void BitVector::Print() {
38 bool first = true;
39 PrintF("{");
40 for (int i = 0; i < length(); i++) {
41 if (Contains(i)) {
42 if (!first) PrintF(",");
43 first = false;
Ben Murdochf87a2032010-10-22 12:50:53 +010044 PrintF("%d", i);
Steve Block6ded16b2010-05-10 14:33:55 +010045 }
46 }
47 PrintF("}");
48}
49#endif
50
51
Ben Murdochb0fe1622011-05-05 13:52:32 +010052void BitVector::Iterator::Advance() {
53 current_++;
54 uint32_t val = current_value_;
55 while (val == 0) {
56 current_index_++;
57 if (Done()) return;
58 val = target_->data_[current_index_];
59 current_ = current_index_ << 5;
60 }
61 val = SkipZeroBytes(val);
62 val = SkipZeroBits(val);
63 current_value_ = val >> 1;
64}
65
66
Ben Murdochf87a2032010-10-22 12:50:53 +010067bool AssignedVariablesAnalyzer::Analyze(CompilationInfo* info) {
Ben Murdochf87a2032010-10-22 12:50:53 +010068 Scope* scope = info->scope();
Ben Murdochb0fe1622011-05-05 13:52:32 +010069 int size = scope->num_parameters() + scope->num_stack_slots();
70 if (size == 0) return true;
71 AssignedVariablesAnalyzer analyzer(info, size);
72 return analyzer.Analyze();
73}
74
75
76AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(CompilationInfo* info,
77 int size)
78 : info_(info), av_(size) {
79}
80
81
82bool AssignedVariablesAnalyzer::Analyze() {
83 ASSERT(av_.length() > 0);
84 VisitStatements(info_->function()->body());
Kristian Monsen80d68ea2010-09-08 11:05:35 +010085 return !HasStackOverflow();
Andrei Popescu402d9372010-02-26 13:31:12 +000086}
87
88
Steve Block6ded16b2010-05-10 14:33:55 +010089Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) {
90 // The loop must have all necessary parts.
91 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) {
92 return NULL;
93 }
94 // The initialization statement has to be a simple assignment.
95 Assignment* init = stmt->init()->StatementAsSimpleAssignment();
96 if (init == NULL) return NULL;
Andrei Popescu402d9372010-02-26 13:31:12 +000097
Steve Block6ded16b2010-05-10 14:33:55 +010098 // We only deal with local variables.
99 Variable* loop_var = init->target()->AsVariableProxy()->AsVariable();
100 if (loop_var == NULL || !loop_var->IsStackAllocated()) return NULL;
101
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100102 // Don't try to get clever with const or dynamic variables.
103 if (loop_var->mode() != Variable::VAR) return NULL;
104
Steve Block6ded16b2010-05-10 14:33:55 +0100105 // The initial value has to be a smi.
106 Literal* init_lit = init->value()->AsLiteral();
107 if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL;
108 int init_value = Smi::cast(*init_lit->handle())->value();
109
110 // The condition must be a compare of variable with <, <=, >, or >=.
111 CompareOperation* cond = stmt->cond()->AsCompareOperation();
112 if (cond == NULL) return NULL;
113 if (cond->op() != Token::LT
114 && cond->op() != Token::LTE
115 && cond->op() != Token::GT
116 && cond->op() != Token::GTE) return NULL;
117
118 // The lhs must be the same variable as in the init expression.
119 if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL;
120
121 // The rhs must be a smi.
122 Literal* term_lit = cond->right()->AsLiteral();
123 if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL;
124 int term_value = Smi::cast(*term_lit->handle())->value();
125
126 // The count operation updates the same variable as in the init expression.
127 CountOperation* update = stmt->next()->StatementAsCountOperation();
128 if (update == NULL) return NULL;
129 if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) {
130 return NULL;
131 }
132
133 // The direction of the count operation must agree with the start and the end
134 // value. We currently do not allow the initial value to be the same as the
135 // terminal value. This _would_ be ok as long as the loop body never executes
136 // or executes exactly one time.
137 if (init_value == term_value) return NULL;
138 if (init_value < term_value && update->op() != Token::INC) return NULL;
139 if (init_value > term_value && update->op() != Token::DEC) return NULL;
140
141 // Check that the update operation cannot overflow the smi range. This can
142 // occur in the two cases where the loop bound is equal to the largest or
143 // smallest smi.
144 if (update->op() == Token::INC && term_value == Smi::kMaxValue) return NULL;
145 if (update->op() == Token::DEC && term_value == Smi::kMinValue) return NULL;
146
147 // Found a smi loop variable.
148 return loop_var;
149}
150
151int AssignedVariablesAnalyzer::BitIndex(Variable* var) {
152 ASSERT(var != NULL);
153 ASSERT(var->IsStackAllocated());
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100154 Slot* slot = var->AsSlot();
Steve Block6ded16b2010-05-10 14:33:55 +0100155 if (slot->type() == Slot::PARAMETER) {
156 return slot->index();
157 } else {
Ben Murdochf87a2032010-10-22 12:50:53 +0100158 return info_->scope()->num_parameters() + slot->index();
Andrei Popescu402d9372010-02-26 13:31:12 +0000159 }
160}
161
162
Steve Block6ded16b2010-05-10 14:33:55 +0100163void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) {
164 ASSERT(var != NULL);
165 if (var->IsStackAllocated()) {
166 av_.Add(BitIndex(var));
Andrei Popescu402d9372010-02-26 13:31:12 +0000167 }
168}
169
170
Steve Block6ded16b2010-05-10 14:33:55 +0100171void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) {
172 Variable* var = expr->AsVariableProxy()->AsVariable();
173 if (var != NULL &&
174 var->IsStackAllocated() &&
175 !var->is_arguments() &&
176 var->mode() != Variable::CONST &&
177 (var->is_this() || !av_.Contains(BitIndex(var)))) {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100178 expr->AsVariableProxy()->MarkAsTrivial();
Andrei Popescu402d9372010-02-26 13:31:12 +0000179 }
180}
181
182
Steve Block6ded16b2010-05-10 14:33:55 +0100183void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) {
184 BitVector saved_av(av_);
185 av_.Clear();
186 Visit(expr);
187 av_.Union(saved_av);
Andrei Popescu402d9372010-02-26 13:31:12 +0000188}
189
Steve Block6ded16b2010-05-10 14:33:55 +0100190void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000191 VisitStatements(stmt->statements());
192}
193
194
Steve Block6ded16b2010-05-10 14:33:55 +0100195void AssignedVariablesAnalyzer::VisitExpressionStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000196 ExpressionStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100197 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000198}
199
200
Steve Block6ded16b2010-05-10 14:33:55 +0100201void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000202 // Do nothing.
203}
204
205
Steve Block6ded16b2010-05-10 14:33:55 +0100206void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) {
207 ProcessExpression(stmt->condition());
208 Visit(stmt->then_statement());
209 Visit(stmt->else_statement());
Andrei Popescu402d9372010-02-26 13:31:12 +0000210}
211
212
Steve Block6ded16b2010-05-10 14:33:55 +0100213void AssignedVariablesAnalyzer::VisitContinueStatement(
214 ContinueStatement* stmt) {
215 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000216}
217
218
Steve Block6ded16b2010-05-10 14:33:55 +0100219void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) {
220 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000221}
222
223
Steve Block6ded16b2010-05-10 14:33:55 +0100224void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) {
225 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000226}
227
228
Steve Block6ded16b2010-05-10 14:33:55 +0100229void AssignedVariablesAnalyzer::VisitWithEnterStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000230 WithEnterStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100231 ProcessExpression(stmt->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000232}
233
234
Steve Block6ded16b2010-05-10 14:33:55 +0100235void AssignedVariablesAnalyzer::VisitWithExitStatement(
236 WithExitStatement* stmt) {
237 // Nothing to do.
Andrei Popescu402d9372010-02-26 13:31:12 +0000238}
239
240
Steve Block6ded16b2010-05-10 14:33:55 +0100241void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) {
242 BitVector result(av_);
243 av_.Clear();
244 Visit(stmt->tag());
245 result.Union(av_);
246 for (int i = 0; i < stmt->cases()->length(); i++) {
247 CaseClause* clause = stmt->cases()->at(i);
248 if (!clause->is_default()) {
249 av_.Clear();
250 Visit(clause->label());
251 result.Union(av_);
252 }
253 VisitStatements(clause->statements());
254 }
255 av_.Union(result);
Andrei Popescu402d9372010-02-26 13:31:12 +0000256}
257
258
Steve Block6ded16b2010-05-10 14:33:55 +0100259void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) {
260 ProcessExpression(stmt->cond());
261 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000262}
263
264
Steve Block6ded16b2010-05-10 14:33:55 +0100265void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) {
266 ProcessExpression(stmt->cond());
267 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000268}
269
270
Steve Block6ded16b2010-05-10 14:33:55 +0100271void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) {
272 if (stmt->init() != NULL) Visit(stmt->init());
Steve Block6ded16b2010-05-10 14:33:55 +0100273 if (stmt->cond() != NULL) ProcessExpression(stmt->cond());
Steve Block6ded16b2010-05-10 14:33:55 +0100274 if (stmt->next() != NULL) Visit(stmt->next());
275
276 // Process loop body. After visiting the loop body av_ contains
277 // the assigned variables of the loop body.
278 BitVector saved_av(av_);
279 av_.Clear();
280 Visit(stmt->body());
281
282 Variable* var = FindSmiLoopVariable(stmt);
283 if (var != NULL && !av_.Contains(BitIndex(var))) {
284 stmt->set_loop_variable(var);
285 }
Steve Block6ded16b2010-05-10 14:33:55 +0100286 av_.Union(saved_av);
Andrei Popescu402d9372010-02-26 13:31:12 +0000287}
288
289
Steve Block6ded16b2010-05-10 14:33:55 +0100290void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) {
291 ProcessExpression(stmt->each());
292 ProcessExpression(stmt->enumerable());
293 Visit(stmt->body());
Andrei Popescu402d9372010-02-26 13:31:12 +0000294}
295
296
Steve Block6ded16b2010-05-10 14:33:55 +0100297void AssignedVariablesAnalyzer::VisitTryCatchStatement(
298 TryCatchStatement* stmt) {
299 Visit(stmt->try_block());
300 Visit(stmt->catch_block());
Andrei Popescu402d9372010-02-26 13:31:12 +0000301}
302
303
Steve Block6ded16b2010-05-10 14:33:55 +0100304void AssignedVariablesAnalyzer::VisitTryFinallyStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000305 TryFinallyStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100306 Visit(stmt->try_block());
307 Visit(stmt->finally_block());
Andrei Popescu402d9372010-02-26 13:31:12 +0000308}
309
310
Steve Block6ded16b2010-05-10 14:33:55 +0100311void AssignedVariablesAnalyzer::VisitDebuggerStatement(
Andrei Popescu402d9372010-02-26 13:31:12 +0000312 DebuggerStatement* stmt) {
Steve Block6ded16b2010-05-10 14:33:55 +0100313 // Nothing to do.
314}
315
316
317void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) {
318 // Nothing to do.
319 ASSERT(av_.IsEmpty());
320}
321
322
323void AssignedVariablesAnalyzer::VisitSharedFunctionInfoLiteral(
324 SharedFunctionInfoLiteral* expr) {
325 // Nothing to do.
326 ASSERT(av_.IsEmpty());
327}
328
329
330void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) {
331 ASSERT(av_.IsEmpty());
332
333 Visit(expr->condition());
334
335 BitVector result(av_);
336 av_.Clear();
337 Visit(expr->then_expression());
338 result.Union(av_);
339
340 av_.Clear();
341 Visit(expr->else_expression());
342 av_.Union(result);
343}
344
345
Steve Block6ded16b2010-05-10 14:33:55 +0100346void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) {
347 // Nothing to do.
348 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000349}
350
351
Steve Block6ded16b2010-05-10 14:33:55 +0100352void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) {
353 // Nothing to do.
354 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000355}
356
357
Steve Block6ded16b2010-05-10 14:33:55 +0100358void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) {
359 // Nothing to do.
360 ASSERT(av_.IsEmpty());
Andrei Popescu402d9372010-02-26 13:31:12 +0000361}
362
363
Steve Block6ded16b2010-05-10 14:33:55 +0100364void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) {
365 ASSERT(av_.IsEmpty());
366 BitVector result(av_.length());
367 for (int i = 0; i < expr->properties()->length(); i++) {
368 Visit(expr->properties()->at(i)->value());
369 result.Union(av_);
370 av_.Clear();
371 }
372 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000373}
374
375
Steve Block6ded16b2010-05-10 14:33:55 +0100376void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) {
377 ASSERT(av_.IsEmpty());
378 BitVector result(av_.length());
379 for (int i = 0; i < expr->values()->length(); i++) {
380 Visit(expr->values()->at(i));
381 result.Union(av_);
382 av_.Clear();
383 }
384 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000385}
386
387
Steve Block6ded16b2010-05-10 14:33:55 +0100388void AssignedVariablesAnalyzer::VisitCatchExtensionObject(
Andrei Popescu402d9372010-02-26 13:31:12 +0000389 CatchExtensionObject* expr) {
Steve Block6ded16b2010-05-10 14:33:55 +0100390 ASSERT(av_.IsEmpty());
391 Visit(expr->key());
392 ProcessExpression(expr->value());
Andrei Popescu402d9372010-02-26 13:31:12 +0000393}
394
395
Steve Block6ded16b2010-05-10 14:33:55 +0100396void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) {
397 ASSERT(av_.IsEmpty());
398
399 // There are three kinds of assignments: variable assignments, property
400 // assignments, and reference errors (invalid left-hand sides).
401 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
Andrei Popescu402d9372010-02-26 13:31:12 +0000402 Property* prop = expr->target()->AsProperty();
Steve Block6ded16b2010-05-10 14:33:55 +0100403 ASSERT(var == NULL || prop == NULL);
Andrei Popescu402d9372010-02-26 13:31:12 +0000404
Steve Block6ded16b2010-05-10 14:33:55 +0100405 if (var != NULL) {
406 MarkIfTrivial(expr->value());
407 Visit(expr->value());
408 if (expr->is_compound()) {
409 // Left-hand side occurs also as an rvalue.
410 MarkIfTrivial(expr->target());
411 ProcessExpression(expr->target());
412 }
413 RecordAssignedVar(var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000414
Steve Block6ded16b2010-05-10 14:33:55 +0100415 } else if (prop != NULL) {
416 MarkIfTrivial(expr->value());
417 Visit(expr->value());
418 if (!prop->key()->IsPropertyName()) {
419 MarkIfTrivial(prop->key());
420 ProcessExpression(prop->key());
421 }
422 MarkIfTrivial(prop->obj());
423 ProcessExpression(prop->obj());
424
425 } else {
426 Visit(expr->target());
427 }
Andrei Popescu402d9372010-02-26 13:31:12 +0000428}
429
430
Steve Block6ded16b2010-05-10 14:33:55 +0100431void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) {
432 ASSERT(av_.IsEmpty());
433 Visit(expr->exception());
Andrei Popescu402d9372010-02-26 13:31:12 +0000434}
435
436
Steve Block6ded16b2010-05-10 14:33:55 +0100437void AssignedVariablesAnalyzer::VisitProperty(Property* expr) {
438 ASSERT(av_.IsEmpty());
439 if (!expr->key()->IsPropertyName()) {
440 MarkIfTrivial(expr->key());
441 Visit(expr->key());
442 }
443 MarkIfTrivial(expr->obj());
444 ProcessExpression(expr->obj());
Andrei Popescu402d9372010-02-26 13:31:12 +0000445}
446
447
Steve Block6ded16b2010-05-10 14:33:55 +0100448void AssignedVariablesAnalyzer::VisitCall(Call* expr) {
449 ASSERT(av_.IsEmpty());
450 Visit(expr->expression());
451 BitVector result(av_);
452 for (int i = 0; i < expr->arguments()->length(); i++) {
453 av_.Clear();
454 Visit(expr->arguments()->at(i));
455 result.Union(av_);
456 }
457 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000458}
459
460
Steve Block6ded16b2010-05-10 14:33:55 +0100461void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) {
462 ASSERT(av_.IsEmpty());
463 Visit(expr->expression());
464 BitVector result(av_);
465 for (int i = 0; i < expr->arguments()->length(); i++) {
466 av_.Clear();
467 Visit(expr->arguments()->at(i));
468 result.Union(av_);
469 }
470 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000471}
472
473
Steve Block6ded16b2010-05-10 14:33:55 +0100474void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) {
475 ASSERT(av_.IsEmpty());
476 BitVector result(av_);
477 for (int i = 0; i < expr->arguments()->length(); i++) {
478 av_.Clear();
479 Visit(expr->arguments()->at(i));
480 result.Union(av_);
481 }
482 av_ = result;
Andrei Popescu402d9372010-02-26 13:31:12 +0000483}
484
485
Steve Block6ded16b2010-05-10 14:33:55 +0100486void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
487 ASSERT(av_.IsEmpty());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100488 MarkIfTrivial(expr->expression());
Steve Block6ded16b2010-05-10 14:33:55 +0100489 Visit(expr->expression());
Andrei Popescu402d9372010-02-26 13:31:12 +0000490}
491
492
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100493void AssignedVariablesAnalyzer::VisitIncrementOperation(
494 IncrementOperation* expr) {
495 UNREACHABLE();
496}
497
498
Steve Block6ded16b2010-05-10 14:33:55 +0100499void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
500 ASSERT(av_.IsEmpty());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100501 if (expr->is_prefix()) MarkIfTrivial(expr->expression());
Steve Block6ded16b2010-05-10 14:33:55 +0100502 Visit(expr->expression());
503
504 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
505 if (var != NULL) RecordAssignedVar(var);
Andrei Popescu402d9372010-02-26 13:31:12 +0000506}
507
508
Steve Block6ded16b2010-05-10 14:33:55 +0100509void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
510 ASSERT(av_.IsEmpty());
511 MarkIfTrivial(expr->right());
Andrei Popescu402d9372010-02-26 13:31:12 +0000512 Visit(expr->right());
Steve Block6ded16b2010-05-10 14:33:55 +0100513 MarkIfTrivial(expr->left());
514 ProcessExpression(expr->left());
Andrei Popescu402d9372010-02-26 13:31:12 +0000515}
516
517
Steve Block6ded16b2010-05-10 14:33:55 +0100518void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) {
519 ASSERT(av_.IsEmpty());
520 MarkIfTrivial(expr->right());
521 Visit(expr->right());
522 MarkIfTrivial(expr->left());
523 ProcessExpression(expr->left());
Andrei Popescu402d9372010-02-26 13:31:12 +0000524}
525
526
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100527void AssignedVariablesAnalyzer::VisitCompareToNull(CompareToNull* expr) {
528 ASSERT(av_.IsEmpty());
529 MarkIfTrivial(expr->expression());
530 Visit(expr->expression());
531}
532
533
Steve Block6ded16b2010-05-10 14:33:55 +0100534void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) {
535 // Nothing to do.
536 ASSERT(av_.IsEmpty());
537}
538
539
540void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
Andrei Popescu402d9372010-02-26 13:31:12 +0000541 UNREACHABLE();
542}
543
544
Leon Clarke4515c472010-02-03 11:58:03 +0000545} } // namespace v8::internal