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

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

Issue 646019: Temporarily move the ia32 fast code generator into the platform-specific dire... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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/ia32/fast-codegen-ia32.h ('k') | tools/gyp/v8.gyp » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "fast-codegen.h" 31 #include "fast-codegen.h"
32 #include "data-flow.h"
33 #include "scopes.h"
32 34
33 namespace v8 { 35 namespace v8 {
34 namespace internal { 36 namespace internal {
35 37
38 #define BAILOUT(reason) \
39 do { \
40 if (FLAG_trace_bailout) { \
41 PrintF("%s\n", reason); \
42 } \
43 has_supported_syntax_ = false; \
44 return; \
45 } while (false)
46
47
48 #define CHECK_BAILOUT \
49 do { \
50 if (!has_supported_syntax_) return; \
51 } while (false)
52
53
54 void FastCodeGenSyntaxChecker::Check(CompilationInfo* info) {
55 info_ = info;
56
57 // We do not specialize if we do not have a receiver or if it is not a
58 // JS object with fast mode properties.
59 if (!info->has_receiver()) BAILOUT("No receiver");
60 if (!info->receiver()->IsJSObject()) BAILOUT("Receiver is not an object");
61 Handle<JSObject> object = Handle<JSObject>::cast(info->receiver());
62 if (!object->HasFastProperties()) BAILOUT("Receiver is in dictionary mode");
63
64 // We do not support stack or heap slots (both of which require
65 // allocation).
66 Scope* scope = info->scope();
67 if (scope->num_stack_slots() > 0) {
68 BAILOUT("Function has stack-allocated locals");
69 }
70 if (scope->num_heap_slots() > 0) {
71 BAILOUT("Function has context-allocated locals");
72 }
73
74 VisitDeclarations(scope->declarations());
75 CHECK_BAILOUT;
76
77 // We do not support empty function bodies.
78 if (info->function()->body()->is_empty()) {
79 BAILOUT("Function has an empty body");
80 }
81 VisitStatements(info->function()->body());
82 }
83
84
85 void FastCodeGenSyntaxChecker::VisitDeclarations(
86 ZoneList<Declaration*>* decls) {
87 if (!decls->is_empty()) BAILOUT("Function has declarations");
88 }
89
90
91 void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
92 if (stmts->length() != 1) {
93 BAILOUT("Function body is not a singleton statement.");
94 }
95 Visit(stmts->at(0));
96 }
97
98
99 void FastCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
100 UNREACHABLE();
101 }
102
103
104 void FastCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
105 VisitStatements(stmt->statements());
106 }
107
108
109 void FastCodeGenSyntaxChecker::VisitExpressionStatement(
110 ExpressionStatement* stmt) {
111 Visit(stmt->expression());
112 }
113
114
115 void FastCodeGenSyntaxChecker::VisitEmptyStatement(EmptyStatement* stmt) {
116 // Supported.
117 }
118
119
120 void FastCodeGenSyntaxChecker::VisitIfStatement(IfStatement* stmt) {
121 BAILOUT("IfStatement");
122 }
123
124
125 void FastCodeGenSyntaxChecker::VisitContinueStatement(ContinueStatement* stmt) {
126 BAILOUT("Continuestatement");
127 }
128
129
130 void FastCodeGenSyntaxChecker::VisitBreakStatement(BreakStatement* stmt) {
131 BAILOUT("BreakStatement");
132 }
133
134
135 void FastCodeGenSyntaxChecker::VisitReturnStatement(ReturnStatement* stmt) {
136 BAILOUT("ReturnStatement");
137 }
138
139
140 void FastCodeGenSyntaxChecker::VisitWithEnterStatement(
141 WithEnterStatement* stmt) {
142 BAILOUT("WithEnterStatement");
143 }
144
145
146 void FastCodeGenSyntaxChecker::VisitWithExitStatement(WithExitStatement* stmt) {
147 BAILOUT("WithExitStatement");
148 }
149
150
151 void FastCodeGenSyntaxChecker::VisitSwitchStatement(SwitchStatement* stmt) {
152 BAILOUT("SwitchStatement");
153 }
154
155
156 void FastCodeGenSyntaxChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
157 BAILOUT("DoWhileStatement");
158 }
159
160
161 void FastCodeGenSyntaxChecker::VisitWhileStatement(WhileStatement* stmt) {
162 BAILOUT("WhileStatement");
163 }
164
165
166 void FastCodeGenSyntaxChecker::VisitForStatement(ForStatement* stmt) {
167 BAILOUT("ForStatement");
168 }
169
170
171 void FastCodeGenSyntaxChecker::VisitForInStatement(ForInStatement* stmt) {
172 BAILOUT("ForInStatement");
173 }
174
175
176 void FastCodeGenSyntaxChecker::VisitTryCatchStatement(TryCatchStatement* stmt) {
177 BAILOUT("TryCatchStatement");
178 }
179
180
181 void FastCodeGenSyntaxChecker::VisitTryFinallyStatement(
182 TryFinallyStatement* stmt) {
183 BAILOUT("TryFinallyStatement");
184 }
185
186
187 void FastCodeGenSyntaxChecker::VisitDebuggerStatement(
188 DebuggerStatement* stmt) {
189 BAILOUT("DebuggerStatement");
190 }
191
192
193 void FastCodeGenSyntaxChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
194 BAILOUT("FunctionLiteral");
195 }
196
197
198 void FastCodeGenSyntaxChecker::VisitFunctionBoilerplateLiteral(
199 FunctionBoilerplateLiteral* expr) {
200 BAILOUT("FunctionBoilerplateLiteral");
201 }
202
203
204 void FastCodeGenSyntaxChecker::VisitConditional(Conditional* expr) {
205 BAILOUT("Conditional");
206 }
207
208
209 void FastCodeGenSyntaxChecker::VisitSlot(Slot* expr) {
210 UNREACHABLE();
211 }
212
213
214 void FastCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
215 // Only global variable references are supported.
216 Variable* var = expr->var();
217 if (!var->is_global() || var->is_this()) BAILOUT("Non-global variable");
218
219 // Check if the global variable is existing and non-deletable.
220 if (info()->has_global_object()) {
221 LookupResult lookup;
222 info()->global_object()->Lookup(*expr->name(), &lookup);
223 if (!lookup.IsProperty()) {
224 BAILOUT("Non-existing global variable");
225 }
226 // We do not handle global variables with accessors or interceptors.
227 if (lookup.type() != NORMAL) {
228 BAILOUT("Global variable with accessors or interceptors.");
229 }
230 // We do not handle deletable global variables.
231 if (!lookup.IsDontDelete()) {
232 BAILOUT("Deletable global variable");
233 }
234 }
235 }
236
237
238 void FastCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
239 BAILOUT("Literal");
240 }
241
242
243 void FastCodeGenSyntaxChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
244 BAILOUT("RegExpLiteral");
245 }
246
247
248 void FastCodeGenSyntaxChecker::VisitObjectLiteral(ObjectLiteral* expr) {
249 BAILOUT("ObjectLiteral");
250 }
251
252
253 void FastCodeGenSyntaxChecker::VisitArrayLiteral(ArrayLiteral* expr) {
254 BAILOUT("ArrayLiteral");
255 }
256
257
258 void FastCodeGenSyntaxChecker::VisitCatchExtensionObject(
259 CatchExtensionObject* expr) {
260 BAILOUT("CatchExtensionObject");
261 }
262
263
264 void FastCodeGenSyntaxChecker::VisitAssignment(Assignment* expr) {
265 // Simple assignments to (named) this properties are supported.
266 if (expr->op() != Token::ASSIGN) BAILOUT("Non-simple assignment");
267
268 Property* prop = expr->target()->AsProperty();
269 if (prop == NULL) BAILOUT("Non-property assignment");
270 VariableProxy* proxy = prop->obj()->AsVariableProxy();
271 if (proxy == NULL || !proxy->var()->is_this()) {
272 BAILOUT("Non-this-property assignment");
273 }
274 if (!prop->key()->IsPropertyName()) {
275 BAILOUT("Non-named-property assignment");
276 }
277
278 // We will only specialize for fields on the object itself.
279 // Expression::IsPropertyName implies that the name is a literal
280 // symbol but we do not assume that.
281 Literal* key = prop->key()->AsLiteral();
282 if (key != NULL && key->handle()->IsString()) {
283 Handle<Object> receiver = info()->receiver();
284 Handle<String> name = Handle<String>::cast(key->handle());
285 LookupResult lookup;
286 receiver->Lookup(*name, &lookup);
287 if (!lookup.IsProperty()) {
288 BAILOUT("Assigned property not found at compile time");
289 }
290 if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
291 if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment");
292 } else {
293 UNREACHABLE();
294 BAILOUT("Unexpected non-string-literal property key");
295 }
296
297 Visit(expr->value());
298 }
299
300
301 void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
302 BAILOUT("Throw");
303 }
304
305
306 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
307 // We support named this property references.
308 VariableProxy* proxy = expr->obj()->AsVariableProxy();
309 if (proxy == NULL || !proxy->var()->is_this()) {
310 BAILOUT("Non-this-property reference");
311 }
312 if (!expr->key()->IsPropertyName()) {
313 BAILOUT("Non-named-property reference");
314 }
315
316 // We will only specialize for fields on the object itself.
317 // Expression::IsPropertyName implies that the name is a literal
318 // symbol but we do not assume that.
319 Literal* key = expr->key()->AsLiteral();
320 if (key != NULL && key->handle()->IsString()) {
321 Handle<Object> receiver = info()->receiver();
322 Handle<String> name = Handle<String>::cast(key->handle());
323 LookupResult lookup;
324 receiver->Lookup(*name, &lookup);
325 if (!lookup.IsProperty()) {
326 BAILOUT("Referenced property not found at compile time");
327 }
328 if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
329 if (!lookup.type() == FIELD) BAILOUT("Non-field property reference");
330 } else {
331 UNREACHABLE();
332 BAILOUT("Unexpected non-string-literal property key");
333 }
334 }
335
336
337 void FastCodeGenSyntaxChecker::VisitCall(Call* expr) {
338 BAILOUT("Call");
339 }
340
341
342 void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
343 BAILOUT("CallNew");
344 }
345
346
347 void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
348 BAILOUT("CallRuntime");
349 }
350
351
352 void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
353 BAILOUT("UnaryOperation");
354 }
355
356
357 void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
358 BAILOUT("CountOperation");
359 }
360
361
362 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
363 // We support bitwise OR.
364 switch (expr->op()) {
365 case Token::COMMA:
366 BAILOUT("BinaryOperation COMMA");
367 case Token::OR:
368 BAILOUT("BinaryOperation OR");
369 case Token::AND:
370 BAILOUT("BinaryOperation AND");
371
372 case Token::BIT_OR:
373 // We support expressions nested on the left because they only require
374 // a pair of registers to keep all intermediate values in registers
375 // (i.e., the expression stack has height no more than two).
376 if (!expr->right()->IsLeaf()) BAILOUT("expression nested on right");
377
378 // We do not allow subexpressions with side effects because we
379 // (currently) bail out to the beginning of the full function. The
380 // only expressions with side effects that we would otherwise handle
381 // are assignments.
382 if (expr->left()->AsAssignment() != NULL ||
383 expr->right()->AsAssignment() != NULL) {
384 BAILOUT("subexpression of binary operation has side effects");
385 }
386
387 Visit(expr->left());
388 CHECK_BAILOUT;
389 Visit(expr->right());
390 break;
391
392 case Token::BIT_XOR:
393 BAILOUT("BinaryOperation BIT_XOR");
394 case Token::BIT_AND:
395 BAILOUT("BinaryOperation BIT_AND");
396 case Token::SHL:
397 BAILOUT("BinaryOperation SHL");
398 case Token::SAR:
399 BAILOUT("BinaryOperation SAR");
400 case Token::SHR:
401 BAILOUT("BinaryOperation SHR");
402 case Token::ADD:
403 BAILOUT("BinaryOperation ADD");
404 case Token::SUB:
405 BAILOUT("BinaryOperation SUB");
406 case Token::MUL:
407 BAILOUT("BinaryOperation MUL");
408 case Token::DIV:
409 BAILOUT("BinaryOperation DIV");
410 case Token::MOD:
411 BAILOUT("BinaryOperation MOD");
412 default:
413 UNREACHABLE();
414 }
415 }
416
417
418 void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
419 BAILOUT("CompareOperation");
420 }
421
422
423 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
424 BAILOUT("ThisFunction");
425 }
426
427 #undef BAILOUT
428 #undef CHECK_BAILOUT
429
430
36 #define __ ACCESS_MASM(masm()) 431 #define __ ACCESS_MASM(masm())
37 432
433 Handle<Code> FastCodeGenerator::MakeCode(CompilationInfo* info) {
434 // Label the AST before calling MakeCodePrologue, so AST node numbers are
435 // printed with the AST.
436 AstLabeler labeler;
437 labeler.Label(info);
438
439 LivenessAnalyzer analyzer;
440 analyzer.Analyze(info->function());
441
442 CodeGenerator::MakeCodePrologue(info);
443
444 const int kInitialBufferSize = 4 * KB;
445 MacroAssembler masm(NULL, kInitialBufferSize);
446
447 // Generate the fast-path code.
448 FastCodeGenerator fast_cgen(&masm);
449 fast_cgen.Generate(info);
450 if (fast_cgen.HasStackOverflow()) {
451 ASSERT(!Top::has_pending_exception());
452 return Handle<Code>::null();
453 }
454
455 // Generate the full code for the function in bailout mode, using the same
456 // macro assembler.
457 CodeGenerator cgen(&masm);
458 CodeGeneratorScope scope(&cgen);
459 cgen.Generate(info, CodeGenerator::SECONDARY);
460 if (cgen.HasStackOverflow()) {
461 ASSERT(!Top::has_pending_exception());
462 return Handle<Code>::null();
463 }
464
465 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
466 return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
467 }
468
469
470 void FastCodeGenerator::VisitDeclaration(Declaration* decl) {
471 UNREACHABLE();
472 }
473
474
475 void FastCodeGenerator::VisitBlock(Block* stmt) {
476 VisitStatements(stmt->statements());
477 }
478
479
480 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
481 Visit(stmt->expression());
482 }
483
484
485 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
486 // Nothing to do.
487 }
488
489
490 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
491 UNREACHABLE();
492 }
493
494
495 void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
496 UNREACHABLE();
497 }
498
499
500 void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
501 UNREACHABLE();
502 }
503
504
505 void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
506 UNREACHABLE();
507 }
508
509
510 void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) {
511 UNREACHABLE();
512 }
513
514
515 void FastCodeGenerator::VisitWithExitStatement(WithExitStatement* stmt) {
516 UNREACHABLE();
517 }
518
519
520 void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
521 UNREACHABLE();
522 }
523
524
525 void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
526 UNREACHABLE();
527 }
528
529
530 void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
531 UNREACHABLE();
532 }
533
534
535 void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
536 UNREACHABLE();
537 }
538
539
540 void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
541 UNREACHABLE();
542 }
543
544
545 void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
546 UNREACHABLE();
547 }
548
549
550 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
551 UNREACHABLE();
552 }
553
554
555 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) {
556 UNREACHABLE();
557 }
558
559
560 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
561 UNREACHABLE();
562 }
563
564
565 void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
566 FunctionBoilerplateLiteral* expr) {
567 UNREACHABLE();
568 }
569
570
571 void FastCodeGenerator::VisitConditional(Conditional* expr) {
572 UNREACHABLE();
573 }
574
575
576 void FastCodeGenerator::VisitSlot(Slot* expr) {
577 UNREACHABLE();
578 }
579
580
581 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
582 ASSERT(expr->var()->is_global() && !expr->var()->is_this());
583 // Check if we can compile a global variable load directly from the cell.
584 ASSERT(info()->has_global_object());
585 LookupResult lookup;
586 info()->global_object()->Lookup(*expr->name(), &lookup);
587 // We only support normal (non-accessor/interceptor) DontDelete properties
588 // for now.
589 ASSERT(lookup.IsProperty());
590 ASSERT_EQ(NORMAL, lookup.type());
591 ASSERT(lookup.IsDontDelete());
592 Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
593
594 // Global variable lookups do not have side effects, so we do not need to
595 // emit code if we are in an effect context.
596 if (!destination().is(no_reg)) {
597 Comment cmnt(masm(), ";; Global");
598 if (FLAG_print_ir) {
599 SmartPointer<char> name = expr->name()->ToCString();
600 PrintF("%d: t%d = Global(%s) // last_use = %d\n", expr->num(),
601 expr->num(), *name, expr->var_def()->last_use()->num());
602 }
603 EmitGlobalVariableLoad(cell);
604 }
605 }
606
607
608 void FastCodeGenerator::VisitLiteral(Literal* expr) {
609 UNREACHABLE();
610 }
611
612
613 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
614 UNREACHABLE();
615 }
616
617
618 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
619 UNREACHABLE();
620 }
621
622
623 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
624 UNREACHABLE();
625 }
626
627
628 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
629 UNREACHABLE();
630 }
631
632
633 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
634 // Known to be a simple this property assignment. Effectively a unary
635 // operation.
636 { Register my_destination = destination();
637 set_destination(accumulator0());
638 Visit(expr->value());
639 set_destination(my_destination);
640 }
641
642 Property* prop = expr->target()->AsProperty();
643 ASSERT_NOT_NULL(prop);
644 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
645 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
646 ASSERT(prop->key()->IsPropertyName());
647 Handle<String> name =
648 Handle<String>::cast(prop->key()->AsLiteral()->handle());
649
650 Comment cmnt(masm(), ";; Store to this");
651 if (FLAG_print_ir) {
652 SmartPointer<char> name_string = name->ToCString();
653 PrintF("%d: ", expr->num());
654 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
655 PrintF("Store(this, \"%s\", t%d) // last_use(this) = %d\n", *name_string,
656 expr->value()->num(),
657 expr->var_def()->last_use()->num());
658 }
659
660 EmitThisPropertyStore(name);
661 }
662
663
664 void FastCodeGenerator::VisitThrow(Throw* expr) {
665 UNREACHABLE();
666 }
667
668
669 void FastCodeGenerator::VisitProperty(Property* expr) {
670 ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
671 ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
672 ASSERT(expr->key()->IsPropertyName());
673 if (!destination().is(no_reg)) {
674 Handle<String> name =
675 Handle<String>::cast(expr->key()->AsLiteral()->handle());
676
677 Comment cmnt(masm(), ";; Load from this");
678 if (FLAG_print_ir) {
679 SmartPointer<char> name_string = name->ToCString();
680 PrintF("%d: t%d = Load(this, \"%s\") // last_use(this) = %d\n",
681 expr->num(), expr->num(), *name_string,
682 expr->var_def()->last_use()->num());
683 }
684 EmitThisPropertyLoad(name);
685 }
686 }
687
688
689 void FastCodeGenerator::VisitCall(Call* expr) {
690 UNREACHABLE();
691 }
692
693
694 void FastCodeGenerator::VisitCallNew(CallNew* expr) {
695 UNREACHABLE();
696 }
697
698
699 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
700 UNREACHABLE();
701 }
702
703
704 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
705 UNREACHABLE();
706 }
707
708
709 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
710 UNREACHABLE();
711 }
712
713
714 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
715 // We support limited binary operations: bitwise OR only allowed to be
716 // nested on the left.
717 ASSERT(expr->op() == Token::BIT_OR);
718 ASSERT(expr->right()->IsLeaf());
719
720 { Register my_destination = destination();
721 set_destination(accumulator1());
722 Visit(expr->left());
723 set_destination(accumulator0());
724 Visit(expr->right());
725 set_destination(my_destination);
726 }
727
728 Comment cmnt(masm(), ";; BIT_OR");
729 if (FLAG_print_ir) {
730 PrintF("%d: ", expr->num());
731 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
732 PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
733 }
734 EmitBitOr();
735 }
736
737
738 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
739 UNREACHABLE();
740 }
741
742
743 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
744 UNREACHABLE();
745 }
746
38 Register FastCodeGenerator::accumulator0() { return eax; } 747 Register FastCodeGenerator::accumulator0() { return eax; }
39 Register FastCodeGenerator::accumulator1() { return edx; } 748 Register FastCodeGenerator::accumulator1() { return edx; }
40 Register FastCodeGenerator::scratch0() { return ecx; } 749 Register FastCodeGenerator::scratch0() { return ecx; }
41 Register FastCodeGenerator::scratch1() { return edi; } 750 Register FastCodeGenerator::scratch1() { return edi; }
42 Register FastCodeGenerator::receiver_reg() { return ebx; } 751 Register FastCodeGenerator::receiver_reg() { return ebx; }
43 Register FastCodeGenerator::context_reg() { return esi; } 752 Register FastCodeGenerator::context_reg() { return esi; }
44 753
45 754
46 void FastCodeGenerator::EmitLoadReceiver() { 755 void FastCodeGenerator::EmitLoadReceiver() {
47 // Offset 2 is due to return address and saved frame pointer. 756 // Offset 2 is due to return address and saved frame pointer.
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 __ ret((scope()->num_parameters() + 1) * kPointerSize); 938 __ ret((scope()->num_parameters() + 1) * kPointerSize);
230 939
231 __ bind(&bailout_); 940 __ bind(&bailout_);
232 } 941 }
233 942
234 943
235 #undef __ 944 #undef __
236 945
237 946
238 } } // namespace v8::internal 947 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.h ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698