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

Side by Side Diff: src/fast-codegen.cc

Issue 549108: Rename the toplevel code generator from "Fast" to "Full". It was... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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
(...skipping 18 matching lines...) Expand all
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "compiler.h" 31 #include "compiler.h"
32 #include "fast-codegen.h" 32 #include "fast-codegen.h"
33 #include "stub-cache.h" 33 #include "stub-cache.h"
34 #include "debug.h" 34 #include "debug.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 #define BAILOUT(reason) \
40 do { \
41 if (FLAG_trace_bailout) { \
42 PrintF("%s\n", reason); \
43 } \
44 has_supported_syntax_ = false; \
45 return; \
46 } while (false)
47
48
49 #define CHECK_BAILOUT \
50 do { \
51 if (!has_supported_syntax_) return; \
52 } while (false)
53
54
55 void FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
56 Scope* scope = fun->scope();
57
58 if (scope->num_heap_slots() > 0) {
59 // We support functions with a local context if they do not have
60 // parameters that need to be copied into the context.
61 for (int i = 0, len = scope->num_parameters(); i < len; i++) {
62 Slot* slot = scope->parameter(i)->slot();
63 if (slot != NULL && slot->type() == Slot::CONTEXT) {
64 BAILOUT("Function has context-allocated parameters.");
65 }
66 }
67 }
68
69 VisitDeclarations(scope->declarations());
70 CHECK_BAILOUT;
71
72 VisitStatements(fun->body());
73 }
74
75
76 void FullCodeGenSyntaxChecker::VisitDeclarations(
77 ZoneList<Declaration*>* decls) {
78 for (int i = 0; i < decls->length(); i++) {
79 Visit(decls->at(i));
80 CHECK_BAILOUT;
81 }
82 }
83
84
85 void FullCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
86 for (int i = 0, len = stmts->length(); i < len; i++) {
87 Visit(stmts->at(i));
88 CHECK_BAILOUT;
89 }
90 }
91
92
93 void FullCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
94 Property* prop = decl->proxy()->AsProperty();
95 if (prop != NULL) {
96 Visit(prop->obj());
97 Visit(prop->key());
98 }
99
100 if (decl->fun() != NULL) {
101 Visit(decl->fun());
102 }
103 }
104
105
106 void FullCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
107 VisitStatements(stmt->statements());
108 }
109
110
111 void FullCodeGenSyntaxChecker::VisitExpressionStatement(
112 ExpressionStatement* stmt) {
113 Visit(stmt->expression());
114 }
115
116
117 void FullCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
118 // Supported.
119 }
120
121
122 void FullCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
123 Visit(stmt->condition());
124 CHECK_BAILOUT;
125 Visit(stmt->then_statement());
126 CHECK_BAILOUT;
127 Visit(stmt->else_statement());
128 }
129
130
131 void FullCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
132 // Supported.
133 }
134
135
136 void FullCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {}
137
138
139 void FullCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
140 Visit(stmt->expression());
141 }
142
143
144 void FullCodeGenSyntaxChecker::VisitWithEnterStatement(
145 WithEnterStatement* stmt) {
146 Visit(stmt->expression());
147 }
148
149
150 void FullCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
151 // Supported.
152 }
153
154
155 void FullCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
156 BAILOUT("SwitchStatement");
157 }
158
159
160 void FullCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
161 Visit(stmt->cond());
162 CHECK_BAILOUT;
163 Visit(stmt->body());
164 }
165
166
167 void FullCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
168 Visit(stmt->cond());
169 CHECK_BAILOUT;
170 Visit(stmt->body());
171 }
172
173
174 void FullCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
175 BAILOUT("ForStatement");
176 }
177
178
179 void FullCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
180 BAILOUT("ForInStatement");
181 }
182
183
184 void FullCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
185 Visit(stmt->try_block());
186 CHECK_BAILOUT;
187 Visit(stmt->catch_block());
188 }
189
190
191 void FullCodeGenSyntaxChecker::VisitTryFinallyStatement(
192 TryFinallyStatement* stmt) {
193 Visit(stmt->try_block());
194 CHECK_BAILOUT;
195 Visit(stmt->finally_block());
196 }
197
198
199 void FullCodeGenSyntaxChecker::VisitDebuggerStatement(
200 DebuggerStatement* stmt) {
201 // Supported.
202 }
203
204
205 void FullCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
206 // Supported.
207 }
208
209
210 void FullCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral(
211 FunctionBoilerplateLiteral* expr) {
212 BAILOUT("FunctionBoilerplateLiteral");
213 }
214
215
216 void FullCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
217 Visit(expr->condition());
218 CHECK_BAILOUT;
219 Visit(expr->then_expression());
220 CHECK_BAILOUT;
221 Visit(expr->else_expression());
222 }
223
224
225 void FullCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
226 UNREACHABLE();
227 }
228
229
230 void FullCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
231 Variable* var = expr->var();
232 if (!var->is_global()) {
233 Slot* slot = var->slot();
234 if (slot != NULL) {
235 Slot::Type type = slot->type();
236 // When LOOKUP slots are enabled, some currently dead code
237 // implementing unary typeof will become live.
238 if (type == Slot::LOOKUP) {
239 BAILOUT("Lookup slot");
240 }
241 } else {
242 // If not global or a slot, it is a parameter rewritten to an explicit
243 // property reference on the (shadow) arguments object.
244 #ifdef DEBUG
245 Property* property = var->AsProperty();
246 ASSERT_NOT_NULL(property);
247 Variable* object = property->obj()->AsVariableProxy()->AsVariable();
248 ASSERT_NOT_NULL(object);
249 ASSERT_NOT_NULL(object->slot());
250 ASSERT_NOT_NULL(property->key()->AsLiteral());
251 ASSERT(property->key()->AsLiteral()->handle()->IsSmi());
252 #endif
253 }
254 }
255 }
256
257
258 void FullCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
259 // Supported.
260 }
261
262
263 void FullCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
264 // Supported.
265 }
266
267
268 void FullCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
269 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
270
271 for (int i = 0, len = properties->length(); i < len; i++) {
272 ObjectLiteral::Property* property = properties->at(i);
273 if (property->IsCompileTimeValue()) continue;
274 Visit(property->key());
275 CHECK_BAILOUT;
276 Visit(property->value());
277 CHECK_BAILOUT;
278 }
279 }
280
281
282 void FullCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
283 ZoneList<Expression*>* subexprs = expr->values();
284 for (int i = 0, len = subexprs->length(); i < len; i++) {
285 Expression* subexpr = subexprs->at(i);
286 if (subexpr->AsLiteral() != NULL) continue;
287 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
288 Visit(subexpr);
289 CHECK_BAILOUT;
290 }
291 }
292
293
294 void FullCodeGenSyntaxChecker::VisitCatchExtensionObject(
295 CatchExtensionObject* expr) {
296 Visit(expr->key());
297 CHECK_BAILOUT;
298 Visit(expr->value());
299 }
300
301
302 void FullCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
303 // We support plain non-compound assignments to properties, parameters and
304 // non-context (stack-allocated) locals, and global variables.
305 Token::Value op = expr->op();
306 if (op == Token::INIT_CONST) BAILOUT("initialize constant");
307
308 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
309 Property* prop = expr->target()->AsProperty();
310 ASSERT(var == NULL || prop == NULL);
311 if (var != NULL) {
312 if (var->mode() == Variable::CONST) {
313 BAILOUT("Assignment to const");
314 }
315 // All global variables are supported.
316 if (!var->is_global()) {
317 ASSERT(var->slot() != NULL);
318 Slot::Type type = var->slot()->type();
319 if (type == Slot::LOOKUP) {
320 BAILOUT("Lookup slot");
321 }
322 }
323 } else if (prop != NULL) {
324 Visit(prop->obj());
325 CHECK_BAILOUT;
326 Visit(prop->key());
327 CHECK_BAILOUT;
328 } else {
329 // This is a throw reference error.
330 BAILOUT("non-variable/non-property assignment");
331 }
332
333 Visit(expr->value());
334 }
335
336
337 void FullCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
338 Visit(expr->exception());
339 }
340
341
342 void FullCodeGenSyntaxChecker::VisitProperty(Property* expr) {
343 Visit(expr->obj());
344 CHECK_BAILOUT;
345 Visit(expr->key());
346 }
347
348
349 void FullCodeGenSyntaxChecker::VisitCall(Call* expr) {
350 Expression* fun = expr->expression();
351 ZoneList<Expression*>* args = expr->arguments();
352 Variable* var = fun->AsVariableProxy()->AsVariable();
353
354 // Check for supported calls
355 if (var != NULL && var->is_possibly_eval()) {
356 BAILOUT("call to the identifier 'eval'");
357 } else if (var != NULL && !var->is_this() && var->is_global()) {
358 // Calls to global variables are supported.
359 } else if (var != NULL && var->slot() != NULL &&
360 var->slot()->type() == Slot::LOOKUP) {
361 BAILOUT("call to a lookup slot");
362 } else if (fun->AsProperty() != NULL) {
363 Property* prop = fun->AsProperty();
364 Visit(prop->obj());
365 CHECK_BAILOUT;
366 Visit(prop->key());
367 CHECK_BAILOUT;
368 } else {
369 // Otherwise the call is supported if the function expression is.
370 Visit(fun);
371 }
372 // Check all arguments to the call.
373 for (int i = 0; i < args->length(); i++) {
374 Visit(args->at(i));
375 CHECK_BAILOUT;
376 }
377 }
378
379
380 void FullCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
381 Visit(expr->expression());
382 CHECK_BAILOUT;
383 ZoneList<Expression*>* args = expr->arguments();
384 // Check all arguments to the call
385 for (int i = 0; i < args->length(); i++) {
386 Visit(args->at(i));
387 CHECK_BAILOUT;
388 }
389 }
390
391
392 void FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
393 // Check for inline runtime call
394 if (expr->name()->Get(0) == '_' &&
395 CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
396 BAILOUT("inlined runtime call");
397 }
398 // Check all arguments to the call. (Relies on TEMP meaning STACK.)
399 for (int i = 0; i < expr->arguments()->length(); i++) {
400 Visit(expr->arguments()->at(i));
401 CHECK_BAILOUT;
402 }
403 }
404
405
406 void FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
407 switch (expr->op()) {
408 case Token::VOID:
409 case Token::NOT:
410 case Token::TYPEOF:
411 Visit(expr->expression());
412 break;
413 case Token::BIT_NOT:
414 BAILOUT("UnaryOperation: BIT_NOT");
415 case Token::DELETE:
416 BAILOUT("UnaryOperation: DELETE");
417 case Token::ADD:
418 BAILOUT("UnaryOperation: ADD");
419 case Token::SUB:
420 BAILOUT("UnaryOperation: SUB");
421 default:
422 UNREACHABLE();
423 }
424 }
425
426
427 void FullCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
428 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
429 Property* prop = expr->expression()->AsProperty();
430 ASSERT(var == NULL || prop == NULL);
431 if (var != NULL) {
432 // All global variables are supported.
433 if (!var->is_global()) {
434 ASSERT(var->slot() != NULL);
435 Slot::Type type = var->slot()->type();
436 if (type == Slot::LOOKUP) {
437 BAILOUT("CountOperation with lookup slot");
438 }
439 }
440 } else if (prop != NULL) {
441 Visit(prop->obj());
442 CHECK_BAILOUT;
443 Visit(prop->key());
444 CHECK_BAILOUT;
445 } else {
446 // This is a throw reference error.
447 BAILOUT("CountOperation non-variable/non-property expression");
448 }
449 }
450
451
452 void FullCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
453 Visit(expr->left());
454 CHECK_BAILOUT;
455 Visit(expr->right());
456 }
457
458
459 void FullCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
460 Visit(expr->left());
461 CHECK_BAILOUT;
462 Visit(expr->right());
463 }
464
465
466 void FullCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
467 // Supported.
468 }
469
470 #undef BAILOUT
471 #undef CHECK_BAILOUT
472
473
39 #define __ ACCESS_MASM(masm()) 474 #define __ ACCESS_MASM(masm())
40 475
41 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, 476 Handle<Code> FullCodeGenerator::MakeCode(FunctionLiteral* fun,
42 Handle<Script> script, 477 Handle<Script> script,
43 bool is_eval) { 478 bool is_eval) {
44 CodeGenerator::MakeCodePrologue(fun); 479 CodeGenerator::MakeCodePrologue(fun);
45 const int kInitialBufferSize = 4 * KB; 480 const int kInitialBufferSize = 4 * KB;
46 MacroAssembler masm(NULL, kInitialBufferSize); 481 MacroAssembler masm(NULL, kInitialBufferSize);
47 FastCodeGenerator cgen(&masm, script, is_eval); 482 FullCodeGenerator cgen(&masm, script, is_eval);
48 cgen.Generate(fun); 483 cgen.Generate(fun);
49 if (cgen.HasStackOverflow()) { 484 if (cgen.HasStackOverflow()) {
50 ASSERT(!Top::has_pending_exception()); 485 ASSERT(!Top::has_pending_exception());
51 return Handle<Code>::null(); 486 return Handle<Code>::null();
52 } 487 }
53 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 488 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
54 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); 489 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script);
55 } 490 }
56 491
57 492
58 int FastCodeGenerator::SlotOffset(Slot* slot) { 493 int FullCodeGenerator::SlotOffset(Slot* slot) {
59 ASSERT(slot != NULL); 494 ASSERT(slot != NULL);
60 // Offset is negative because higher indexes are at lower addresses. 495 // Offset is negative because higher indexes are at lower addresses.
61 int offset = -slot->index() * kPointerSize; 496 int offset = -slot->index() * kPointerSize;
62 // Adjust by a (parameter or local) base offset. 497 // Adjust by a (parameter or local) base offset.
63 switch (slot->type()) { 498 switch (slot->type()) {
64 case Slot::PARAMETER: 499 case Slot::PARAMETER:
65 offset += (function_->scope()->num_parameters() + 1) * kPointerSize; 500 offset += (function_->scope()->num_parameters() + 1) * kPointerSize;
66 break; 501 break;
67 case Slot::LOCAL: 502 case Slot::LOCAL:
68 offset += JavaScriptFrameConstants::kLocal0Offset; 503 offset += JavaScriptFrameConstants::kLocal0Offset;
69 break; 504 break;
70 case Slot::CONTEXT: 505 case Slot::CONTEXT:
71 case Slot::LOOKUP: 506 case Slot::LOOKUP:
72 UNREACHABLE(); 507 UNREACHABLE();
73 } 508 }
74 return offset; 509 return offset;
75 } 510 }
76 511
77 512
78 void FastCodeGenerator::VisitDeclarations( 513 void FullCodeGenerator::VisitDeclarations(
79 ZoneList<Declaration*>* declarations) { 514 ZoneList<Declaration*>* declarations) {
80 int length = declarations->length(); 515 int length = declarations->length();
81 int globals = 0; 516 int globals = 0;
82 for (int i = 0; i < length; i++) { 517 for (int i = 0; i < length; i++) {
83 Declaration* decl = declarations->at(i); 518 Declaration* decl = declarations->at(i);
84 Variable* var = decl->proxy()->var(); 519 Variable* var = decl->proxy()->var();
85 Slot* slot = var->slot(); 520 Slot* slot = var->slot();
86 521
87 // If it was not possible to allocate the variable at compile 522 // If it was not possible to allocate the variable at compile
88 // time, we need to "declare" it at runtime to make sure it 523 // time, we need to "declare" it at runtime to make sure it
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 557 }
123 } 558 }
124 } 559 }
125 // Invoke the platform-dependent code generator to do the actual 560 // Invoke the platform-dependent code generator to do the actual
126 // declaration the global variables and functions. 561 // declaration the global variables and functions.
127 DeclareGlobals(array); 562 DeclareGlobals(array);
128 } 563 }
129 } 564 }
130 565
131 566
132 void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { 567 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
133 if (FLAG_debug_info) { 568 if (FLAG_debug_info) {
134 CodeGenerator::RecordPositions(masm_, fun->start_position()); 569 CodeGenerator::RecordPositions(masm_, fun->start_position());
135 } 570 }
136 } 571 }
137 572
138 573
139 void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { 574 void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
140 if (FLAG_debug_info) { 575 if (FLAG_debug_info) {
141 CodeGenerator::RecordPositions(masm_, fun->end_position()); 576 CodeGenerator::RecordPositions(masm_, fun->end_position());
142 } 577 }
143 } 578 }
144 579
145 580
146 void FastCodeGenerator::SetStatementPosition(Statement* stmt) { 581 void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
147 if (FLAG_debug_info) { 582 if (FLAG_debug_info) {
148 CodeGenerator::RecordPositions(masm_, stmt->statement_pos()); 583 CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
149 } 584 }
150 } 585 }
151 586
152 587
153 void FastCodeGenerator::SetStatementPosition(int pos) { 588 void FullCodeGenerator::SetStatementPosition(int pos) {
154 if (FLAG_debug_info) { 589 if (FLAG_debug_info) {
155 CodeGenerator::RecordPositions(masm_, pos); 590 CodeGenerator::RecordPositions(masm_, pos);
156 } 591 }
157 } 592 }
158 593
159 594
160 void FastCodeGenerator::SetSourcePosition(int pos) { 595 void FullCodeGenerator::SetSourcePosition(int pos) {
161 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 596 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
162 masm_->RecordPosition(pos); 597 masm_->RecordPosition(pos);
163 } 598 }
164 } 599 }
165 600
166 601
167 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 602 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
168 Label eval_right, done; 603 Label eval_right, done;
169 604
170 // Set up the appropriate context for the left subexpression based 605 // Set up the appropriate context for the left subexpression based
171 // on the operation and our own context. Initially assume we can 606 // on the operation and our own context. Initially assume we can
172 // inherit both true and false labels from our context. 607 // inherit both true and false labels from our context.
173 if (expr->op() == Token::OR) { 608 if (expr->op() == Token::OR) {
174 switch (context_) { 609 switch (context_) {
175 case Expression::kUninitialized: 610 case Expression::kUninitialized:
176 UNREACHABLE(); 611 UNREACHABLE();
177 case Expression::kEffect: 612 case Expression::kEffect:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 } 660 }
226 } 661 }
227 662
228 __ bind(&eval_right); 663 __ bind(&eval_right);
229 Visit(expr->right()); 664 Visit(expr->right());
230 665
231 __ bind(&done); 666 __ bind(&done);
232 } 667 }
233 668
234 669
235 void FastCodeGenerator::VisitBlock(Block* stmt) { 670 void FullCodeGenerator::VisitBlock(Block* stmt) {
236 Comment cmnt(masm_, "[ Block"); 671 Comment cmnt(masm_, "[ Block");
237 Breakable nested_statement(this, stmt); 672 Breakable nested_statement(this, stmt);
238 SetStatementPosition(stmt); 673 SetStatementPosition(stmt);
239 VisitStatements(stmt->statements()); 674 VisitStatements(stmt->statements());
240 __ bind(nested_statement.break_target()); 675 __ bind(nested_statement.break_target());
241 } 676 }
242 677
243 678
244 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 679 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
245 Comment cmnt(masm_, "[ ExpressionStatement"); 680 Comment cmnt(masm_, "[ ExpressionStatement");
246 SetStatementPosition(stmt); 681 SetStatementPosition(stmt);
247 VisitForEffect(stmt->expression()); 682 VisitForEffect(stmt->expression());
248 } 683 }
249 684
250 685
251 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 686 void FullCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
252 Comment cmnt(masm_, "[ EmptyStatement"); 687 Comment cmnt(masm_, "[ EmptyStatement");
253 SetStatementPosition(stmt); 688 SetStatementPosition(stmt);
254 } 689 }
255 690
256 691
257 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { 692 void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) {
258 Comment cmnt(masm_, "[ IfStatement"); 693 Comment cmnt(masm_, "[ IfStatement");
259 SetStatementPosition(stmt); 694 SetStatementPosition(stmt);
260 Label then_part, else_part, done; 695 Label then_part, else_part, done;
261 696
262 // Do not worry about optimizing for empty then or else bodies. 697 // Do not worry about optimizing for empty then or else bodies.
263 VisitForControl(stmt->condition(), &then_part, &else_part); 698 VisitForControl(stmt->condition(), &then_part, &else_part);
264 699
265 __ bind(&then_part); 700 __ bind(&then_part);
266 Visit(stmt->then_statement()); 701 Visit(stmt->then_statement());
267 __ jmp(&done); 702 __ jmp(&done);
268 703
269 __ bind(&else_part); 704 __ bind(&else_part);
270 Visit(stmt->else_statement()); 705 Visit(stmt->else_statement());
271 706
272 __ bind(&done); 707 __ bind(&done);
273 } 708 }
274 709
275 710
276 void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 711 void FullCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
277 Comment cmnt(masm_, "[ ContinueStatement"); 712 Comment cmnt(masm_, "[ ContinueStatement");
278 SetStatementPosition(stmt); 713 SetStatementPosition(stmt);
279 NestedStatement* current = nesting_stack_; 714 NestedStatement* current = nesting_stack_;
280 int stack_depth = 0; 715 int stack_depth = 0;
281 while (!current->IsContinueTarget(stmt->target())) { 716 while (!current->IsContinueTarget(stmt->target())) {
282 stack_depth = current->Exit(stack_depth); 717 stack_depth = current->Exit(stack_depth);
283 current = current->outer(); 718 current = current->outer();
284 } 719 }
285 __ Drop(stack_depth); 720 __ Drop(stack_depth);
286 721
287 Iteration* loop = current->AsIteration(); 722 Iteration* loop = current->AsIteration();
288 __ jmp(loop->continue_target()); 723 __ jmp(loop->continue_target());
289 } 724 }
290 725
291 726
292 void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { 727 void FullCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
293 Comment cmnt(masm_, "[ BreakStatement"); 728 Comment cmnt(masm_, "[ BreakStatement");
294 SetStatementPosition(stmt); 729 SetStatementPosition(stmt);
295 NestedStatement* current = nesting_stack_; 730 NestedStatement* current = nesting_stack_;
296 int stack_depth = 0; 731 int stack_depth = 0;
297 while (!current->IsBreakTarget(stmt->target())) { 732 while (!current->IsBreakTarget(stmt->target())) {
298 stack_depth = current->Exit(stack_depth); 733 stack_depth = current->Exit(stack_depth);
299 current = current->outer(); 734 current = current->outer();
300 } 735 }
301 __ Drop(stack_depth); 736 __ Drop(stack_depth);
302 737
303 Breakable* target = current->AsBreakable(); 738 Breakable* target = current->AsBreakable();
304 __ jmp(target->break_target()); 739 __ jmp(target->break_target());
305 } 740 }
306 741
307 742
308 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { 743 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
309 Comment cmnt(masm_, "[ ReturnStatement"); 744 Comment cmnt(masm_, "[ ReturnStatement");
310 SetStatementPosition(stmt); 745 SetStatementPosition(stmt);
311 Expression* expr = stmt->expression(); 746 Expression* expr = stmt->expression();
312 VisitForValue(expr, kAccumulator); 747 VisitForValue(expr, kAccumulator);
313 748
314 // Exit all nested statements. 749 // Exit all nested statements.
315 NestedStatement* current = nesting_stack_; 750 NestedStatement* current = nesting_stack_;
316 int stack_depth = 0; 751 int stack_depth = 0;
317 while (current != NULL) { 752 while (current != NULL) {
318 stack_depth = current->Exit(stack_depth); 753 stack_depth = current->Exit(stack_depth);
319 current = current->outer(); 754 current = current->outer();
320 } 755 }
321 __ Drop(stack_depth); 756 __ Drop(stack_depth);
322 757
323 EmitReturnSequence(stmt->statement_pos()); 758 EmitReturnSequence(stmt->statement_pos());
324 } 759 }
325 760
326 761
327 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { 762 void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
328 Comment cmnt(masm_, "[ WithEnterStatement"); 763 Comment cmnt(masm_, "[ WithEnterStatement");
329 SetStatementPosition(stmt); 764 SetStatementPosition(stmt);
330 765
331 VisitForValue(stmt->expression(), kStack); 766 VisitForValue(stmt->expression(), kStack);
332 if (stmt->is_catch_block()) { 767 if (stmt->is_catch_block()) {
333 __ CallRuntime(Runtime::kPushCatchContext, 1); 768 __ CallRuntime(Runtime::kPushCatchContext, 1);
334 } else { 769 } else {
335 __ CallRuntime(Runtime::kPushContext, 1); 770 __ CallRuntime(Runtime::kPushContext, 1);
336 } 771 }
337 // Both runtime calls return the new context in both the context and the 772 // Both runtime calls return the new context in both the context and the
338 // result registers. 773 // result registers.
339 774
340 // Update local stack frame context field. 775 // Update local stack frame context field.
341 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 776 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
342 } 777 }
343 778
344 779
345 void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) { 780 void FullCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
346 Comment cmnt(masm_, "[ WithExitStatement"); 781 Comment cmnt(masm_, "[ WithExitStatement");
347 SetStatementPosition(stmt); 782 SetStatementPosition(stmt);
348 783
349 // Pop context. 784 // Pop context.
350 LoadContextField(context_register(), Context::PREVIOUS_INDEX); 785 LoadContextField(context_register(), Context::PREVIOUS_INDEX);
351 // Update local stack frame context field. 786 // Update local stack frame context field.
352 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); 787 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register());
353 } 788 }
354 789
355 790
356 void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 791 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
357 UNREACHABLE(); 792 UNREACHABLE();
358 } 793 }
359 794
360 795
361 void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 796 void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
362 Comment cmnt(masm_, "[ DoWhileStatement"); 797 Comment cmnt(masm_, "[ DoWhileStatement");
363 SetStatementPosition(stmt); 798 SetStatementPosition(stmt);
364 Label body, stack_limit_hit, stack_check_success; 799 Label body, stack_limit_hit, stack_check_success;
365 800
366 Iteration loop_statement(this, stmt); 801 Iteration loop_statement(this, stmt);
367 increment_loop_depth(); 802 increment_loop_depth();
368 803
369 __ bind(&body); 804 __ bind(&body);
370 Visit(stmt->body()); 805 Visit(stmt->body());
371 806
372 // Check stack before looping. 807 // Check stack before looping.
373 __ StackLimitCheck(&stack_limit_hit); 808 __ StackLimitCheck(&stack_limit_hit);
374 __ bind(&stack_check_success); 809 __ bind(&stack_check_success);
375 810
376 __ bind(loop_statement.continue_target()); 811 __ bind(loop_statement.continue_target());
377 SetStatementPosition(stmt->condition_position()); 812 SetStatementPosition(stmt->condition_position());
378 VisitForControl(stmt->cond(), &body, loop_statement.break_target()); 813 VisitForControl(stmt->cond(), &body, loop_statement.break_target());
379 814
380 __ bind(&stack_limit_hit); 815 __ bind(&stack_limit_hit);
381 StackCheckStub stack_stub; 816 StackCheckStub stack_stub;
382 __ CallStub(&stack_stub); 817 __ CallStub(&stack_stub);
383 __ jmp(&stack_check_success); 818 __ jmp(&stack_check_success);
384 819
385 __ bind(loop_statement.break_target()); 820 __ bind(loop_statement.break_target());
386 821
387 decrement_loop_depth(); 822 decrement_loop_depth();
388 } 823 }
389 824
390 825
391 void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 826 void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
392 Comment cmnt(masm_, "[ WhileStatement"); 827 Comment cmnt(masm_, "[ WhileStatement");
393 SetStatementPosition(stmt); 828 SetStatementPosition(stmt);
394 Label body, stack_limit_hit, stack_check_success; 829 Label body, stack_limit_hit, stack_check_success;
395 830
396 Iteration loop_statement(this, stmt); 831 Iteration loop_statement(this, stmt);
397 increment_loop_depth(); 832 increment_loop_depth();
398 833
399 // Emit the test at the bottom of the loop. 834 // Emit the test at the bottom of the loop.
400 __ jmp(loop_statement.continue_target()); 835 __ jmp(loop_statement.continue_target());
401 836
(...skipping 10 matching lines...) Expand all
412 __ bind(&stack_limit_hit); 847 __ bind(&stack_limit_hit);
413 StackCheckStub stack_stub; 848 StackCheckStub stack_stub;
414 __ CallStub(&stack_stub); 849 __ CallStub(&stack_stub);
415 __ jmp(&stack_check_success); 850 __ jmp(&stack_check_success);
416 851
417 __ bind(loop_statement.break_target()); 852 __ bind(loop_statement.break_target());
418 decrement_loop_depth(); 853 decrement_loop_depth();
419 } 854 }
420 855
421 856
422 void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { 857 void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
423 UNREACHABLE(); 858 UNREACHABLE();
424 } 859 }
425 860
426 861
427 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 862 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
428 UNREACHABLE(); 863 UNREACHABLE();
429 } 864 }
430 865
431 866
432 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { 867 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
433 Comment cmnt(masm_, "[ TryCatchStatement"); 868 Comment cmnt(masm_, "[ TryCatchStatement");
434 SetStatementPosition(stmt); 869 SetStatementPosition(stmt);
435 // The try block adds a handler to the exception handler chain 870 // The try block adds a handler to the exception handler chain
436 // before entering, and removes it again when exiting normally. 871 // before entering, and removes it again when exiting normally.
437 // If an exception is thrown during execution of the try block, 872 // If an exception is thrown during execution of the try block,
438 // control is passed to the handler, which also consumes the handler. 873 // control is passed to the handler, which also consumes the handler.
439 // At this point, the exception is in a register, and store it in 874 // At this point, the exception is in a register, and store it in
440 // the temporary local variable (prints as ".catch-var") before 875 // the temporary local variable (prints as ".catch-var") before
441 // executing the catch block. The catch block has been rewritten 876 // executing the catch block. The catch block has been rewritten
442 // to introduce a new scope to bind the catch variable and to remove 877 // to introduce a new scope to bind the catch variable and to remove
(...skipping 22 matching lines...) Expand all
465 { 900 {
466 TryCatch try_block(this, &catch_entry); 901 TryCatch try_block(this, &catch_entry);
467 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); 902 __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER);
468 Visit(stmt->try_block()); 903 Visit(stmt->try_block());
469 __ PopTryHandler(); 904 __ PopTryHandler();
470 } 905 }
471 __ bind(&done); 906 __ bind(&done);
472 } 907 }
473 908
474 909
475 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 910 void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
476 Comment cmnt(masm_, "[ TryFinallyStatement"); 911 Comment cmnt(masm_, "[ TryFinallyStatement");
477 SetStatementPosition(stmt); 912 SetStatementPosition(stmt);
478 // Try finally is compiled by setting up a try-handler on the stack while 913 // Try finally is compiled by setting up a try-handler on the stack while
479 // executing the try body, and removing it again afterwards. 914 // executing the try body, and removing it again afterwards.
480 // 915 //
481 // The try-finally construct can enter the finally block in three ways: 916 // The try-finally construct can enter the finally block in three ways:
482 // 1. By exiting the try-block normally. This removes the try-handler and 917 // 1. By exiting the try-block normally. This removes the try-handler and
483 // calls the finally block code before continuing. 918 // calls the finally block code before continuing.
484 // 2. By exiting the try-block with a function-local control flow transfer 919 // 2. By exiting the try-block with a function-local control flow transfer
485 // (break/continue/return). The site of the, e.g., break removes the 920 // (break/continue/return). The site of the, e.g., break removes the
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 TryFinally try_block(this, &finally_entry); 964 TryFinally try_block(this, &finally_entry);
530 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); 965 __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER);
531 Visit(stmt->try_block()); 966 Visit(stmt->try_block());
532 __ PopTryHandler(); 967 __ PopTryHandler();
533 } 968 }
534 // Execute the finally block on the way out. 969 // Execute the finally block on the way out.
535 __ Call(&finally_entry); 970 __ Call(&finally_entry);
536 } 971 }
537 972
538 973
539 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { 974 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
540 #ifdef ENABLE_DEBUGGER_SUPPORT 975 #ifdef ENABLE_DEBUGGER_SUPPORT
541 Comment cmnt(masm_, "[ DebuggerStatement"); 976 Comment cmnt(masm_, "[ DebuggerStatement");
542 SetStatementPosition(stmt); 977 SetStatementPosition(stmt);
543 __ CallRuntime(Runtime::kDebugBreak, 0); 978 __ CallRuntime(Runtime::kDebugBreak, 0);
544 // Ignore the return value. 979 // Ignore the return value.
545 #endif 980 #endif
546 } 981 }
547 982
548 983
549 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( 984 void FullCodeGenerator::VisitFunctionBoilerplateLiteral(
550 FunctionBoilerplateLiteral* expr) { 985 FunctionBoilerplateLiteral* expr) {
551 UNREACHABLE(); 986 UNREACHABLE();
552 } 987 }
553 988
554 989
555 void FastCodeGenerator::VisitConditional(Conditional* expr) { 990 void FullCodeGenerator::VisitConditional(Conditional* expr) {
556 Comment cmnt(masm_, "[ Conditional"); 991 Comment cmnt(masm_, "[ Conditional");
557 Label true_case, false_case, done; 992 Label true_case, false_case, done;
558 VisitForControl(expr->condition(), &true_case, &false_case); 993 VisitForControl(expr->condition(), &true_case, &false_case);
559 994
560 __ bind(&true_case); 995 __ bind(&true_case);
561 Visit(expr->then_expression()); 996 Visit(expr->then_expression());
562 // If control flow falls through Visit, jump to done. 997 // If control flow falls through Visit, jump to done.
563 if (context_ == Expression::kEffect || context_ == Expression::kValue) { 998 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
564 __ jmp(&done); 999 __ jmp(&done);
565 } 1000 }
566 1001
567 __ bind(&false_case); 1002 __ bind(&false_case);
568 Visit(expr->else_expression()); 1003 Visit(expr->else_expression());
569 // If control flow falls through Visit, merge it with true case here. 1004 // If control flow falls through Visit, merge it with true case here.
570 if (context_ == Expression::kEffect || context_ == Expression::kValue) { 1005 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
571 __ bind(&done); 1006 __ bind(&done);
572 } 1007 }
573 } 1008 }
574 1009
575 1010
576 void FastCodeGenerator::VisitSlot(Slot* expr) { 1011 void FullCodeGenerator::VisitSlot(Slot* expr) {
577 // Slots do not appear directly in the AST. 1012 // Slots do not appear directly in the AST.
578 UNREACHABLE(); 1013 UNREACHABLE();
579 } 1014 }
580 1015
581 1016
582 void FastCodeGenerator::VisitLiteral(Literal* expr) { 1017 void FullCodeGenerator::VisitLiteral(Literal* expr) {
583 Comment cmnt(masm_, "[ Literal"); 1018 Comment cmnt(masm_, "[ Literal");
584 Apply(context_, expr); 1019 Apply(context_, expr);
585 } 1020 }
586 1021
587 1022
588 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 1023 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
589 Comment cmnt(masm_, "[ Assignment"); 1024 Comment cmnt(masm_, "[ Assignment");
590 // Left-hand side can only be a property, a global or a (parameter or local) 1025 // Left-hand side can only be a property, a global or a (parameter or local)
591 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1026 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
592 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1027 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
593 LhsKind assign_type = VARIABLE; 1028 LhsKind assign_type = VARIABLE;
594 Property* prop = expr->target()->AsProperty(); 1029 Property* prop = expr->target()->AsProperty();
595 if (prop != NULL) { 1030 if (prop != NULL) {
596 assign_type = 1031 assign_type =
597 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 1032 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
598 } 1033 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 case NAMED_PROPERTY: 1092 case NAMED_PROPERTY:
658 EmitNamedPropertyAssignment(expr); 1093 EmitNamedPropertyAssignment(expr);
659 break; 1094 break;
660 case KEYED_PROPERTY: 1095 case KEYED_PROPERTY:
661 EmitKeyedPropertyAssignment(expr); 1096 EmitKeyedPropertyAssignment(expr);
662 break; 1097 break;
663 } 1098 }
664 } 1099 }
665 1100
666 1101
667 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 1102 void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
668 // Call runtime routine to allocate the catch extension object and 1103 // Call runtime routine to allocate the catch extension object and
669 // assign the exception value to the catch variable. 1104 // assign the exception value to the catch variable.
670 Comment cmnt(masm_, "[ CatchExtensionObject"); 1105 Comment cmnt(masm_, "[ CatchExtensionObject");
671 VisitForValue(expr->key(), kStack); 1106 VisitForValue(expr->key(), kStack);
672 VisitForValue(expr->value(), kStack); 1107 VisitForValue(expr->value(), kStack);
673 // Create catch extension object. 1108 // Create catch extension object.
674 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 1109 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
675 Apply(context_, result_register()); 1110 Apply(context_, result_register());
676 } 1111 }
677 1112
678 1113
679 void FastCodeGenerator::VisitThrow(Throw* expr) { 1114 void FullCodeGenerator::VisitThrow(Throw* expr) {
680 Comment cmnt(masm_, "[ Throw"); 1115 Comment cmnt(masm_, "[ Throw");
681 VisitForValue(expr->exception(), kStack); 1116 VisitForValue(expr->exception(), kStack);
682 __ CallRuntime(Runtime::kThrow, 1); 1117 __ CallRuntime(Runtime::kThrow, 1);
683 // Never returns here. 1118 // Never returns here.
684 } 1119 }
685 1120
686 1121
687 int FastCodeGenerator::TryFinally::Exit(int stack_depth) { 1122 int FullCodeGenerator::TryFinally::Exit(int stack_depth) {
688 // The macros used here must preserve the result register. 1123 // The macros used here must preserve the result register.
689 __ Drop(stack_depth); 1124 __ Drop(stack_depth);
690 __ PopTryHandler(); 1125 __ PopTryHandler();
691 __ Call(finally_entry_); 1126 __ Call(finally_entry_);
692 return 0; 1127 return 0;
693 } 1128 }
694 1129
695 1130
696 int FastCodeGenerator::TryCatch::Exit(int stack_depth) { 1131 int FullCodeGenerator::TryCatch::Exit(int stack_depth) {
697 // The macros used here must preserve the result register. 1132 // The macros used here must preserve the result register.
698 __ Drop(stack_depth); 1133 __ Drop(stack_depth);
699 __ PopTryHandler(); 1134 __ PopTryHandler();
700 return 0; 1135 return 0;
701 } 1136 }
702 1137
703 1138
704 #undef __ 1139 #undef __
705 1140
706 1141
707 } } // namespace v8::internal 1142 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698