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

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

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 9 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/frame-element.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 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 82 }
83 83
84 84
85 void FastCodeGenSyntaxChecker::VisitDeclarations( 85 void FastCodeGenSyntaxChecker::VisitDeclarations(
86 ZoneList<Declaration*>* decls) { 86 ZoneList<Declaration*>* decls) {
87 if (!decls->is_empty()) BAILOUT("Function has declarations"); 87 if (!decls->is_empty()) BAILOUT("Function has declarations");
88 } 88 }
89 89
90 90
91 void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) { 91 void FastCodeGenSyntaxChecker::VisitStatements(ZoneList<Statement*>* stmts) {
92 for (int i = 0, len = stmts->length(); i < len; i++) { 92 if (stmts->length() != 1) {
93 Visit(stmts->at(i)); 93 BAILOUT("Function body is not a singleton statement.");
94 CHECK_BAILOUT;
95 } 94 }
95 Visit(stmts->at(0));
96 } 96 }
97 97
98 98
99 void FastCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) { 99 void FastCodeGenSyntaxChecker::VisitDeclaration(Declaration* decl) {
100 UNREACHABLE(); 100 UNREACHABLE();
101 } 101 }
102 102
103 103
104 void FastCodeGenSyntaxChecker::VisitBlock(Block* stmt) { 104 void FastCodeGenSyntaxChecker::VisitBlock(Block* stmt) {
105 VisitStatements(stmt->statements()); 105 VisitStatements(stmt->statements());
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 213
214 void FastCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) { 214 void FastCodeGenSyntaxChecker::VisitVariableProxy(VariableProxy* expr) {
215 // Only global variable references are supported. 215 // Only global variable references are supported.
216 Variable* var = expr->var(); 216 Variable* var = expr->var();
217 if (!var->is_global() || var->is_this()) BAILOUT("Non-global variable"); 217 if (!var->is_global() || var->is_this()) BAILOUT("Non-global variable");
218 218
219 // Check if the global variable is existing and non-deletable. 219 // Check if the global variable is existing and non-deletable.
220 if (info()->has_global_object()) { 220 if (info()->has_global_object()) {
221 LookupResult lookup; 221 LookupResult lookup;
222 info()->global_object()->Lookup(*expr->name(), &lookup); 222 info()->global_object()->Lookup(*expr->name(), &lookup);
223 if (!lookup.IsValid() || !lookup.IsDontDelete()) { 223 if (!lookup.IsProperty()) {
224 BAILOUT("Non-existing or deletable global variable"); 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");
225 } 233 }
226 } 234 }
227 } 235 }
228 236
229 237
230 void FastCodeGenSyntaxChecker::VisitLiteral(Literal* expr) { 238 void FastCodeGenSyntaxChecker::VisitLiteral(Literal* expr) {
231 BAILOUT("Literal"); 239 BAILOUT("Literal");
232 } 240 }
233 241
234 242
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 277
270 // We will only specialize for fields on the object itself. 278 // We will only specialize for fields on the object itself.
271 // Expression::IsPropertyName implies that the name is a literal 279 // Expression::IsPropertyName implies that the name is a literal
272 // symbol but we do not assume that. 280 // symbol but we do not assume that.
273 Literal* key = prop->key()->AsLiteral(); 281 Literal* key = prop->key()->AsLiteral();
274 if (key != NULL && key->handle()->IsString()) { 282 if (key != NULL && key->handle()->IsString()) {
275 Handle<Object> receiver = info()->receiver(); 283 Handle<Object> receiver = info()->receiver();
276 Handle<String> name = Handle<String>::cast(key->handle()); 284 Handle<String> name = Handle<String>::cast(key->handle());
277 LookupResult lookup; 285 LookupResult lookup;
278 receiver->Lookup(*name, &lookup); 286 receiver->Lookup(*name, &lookup);
287 if (!lookup.IsProperty()) {
288 BAILOUT("Assigned property not found at compile time");
289 }
279 if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment"); 290 if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
280 if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment"); 291 if (!lookup.type() == FIELD) BAILOUT("Non-field property assignment");
281 } else { 292 } else {
282 UNREACHABLE(); 293 UNREACHABLE();
283 BAILOUT("Unexpected non-string-literal property key"); 294 BAILOUT("Unexpected non-string-literal property key");
284 } 295 }
285 296
286 Visit(expr->value()); 297 Visit(expr->value());
287 } 298 }
288 299
289 300
290 void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) { 301 void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
291 BAILOUT("Throw"); 302 BAILOUT("Throw");
292 } 303 }
293 304
294 305
295 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) { 306 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
296 BAILOUT("Property"); 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 }
297 } 334 }
298 335
299 336
300 void FastCodeGenSyntaxChecker::VisitCall(Call* expr) { 337 void FastCodeGenSyntaxChecker::VisitCall(Call* expr) {
301 BAILOUT("Call"); 338 BAILOUT("Call");
302 } 339 }
303 340
304 341
305 void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) { 342 void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
306 BAILOUT("CallNew"); 343 BAILOUT("CallNew");
307 } 344 }
308 345
309 346
310 void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) { 347 void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
311 BAILOUT("CallRuntime"); 348 BAILOUT("CallRuntime");
312 } 349 }
313 350
314 351
315 void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) { 352 void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
316 BAILOUT("UnaryOperation"); 353 BAILOUT("UnaryOperation");
317 } 354 }
318 355
319 356
320 void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) { 357 void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
321 BAILOUT("CountOperation"); 358 BAILOUT("CountOperation");
322 } 359 }
323 360
324 361
325 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) { 362 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
326 BAILOUT("BinaryOperation"); 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 }
327 } 415 }
328 416
329 417
330 void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) { 418 void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
331 BAILOUT("CompareOperation"); 419 BAILOUT("CompareOperation");
332 } 420 }
333 421
334 422
335 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 423 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
336 BAILOUT("ThisFunction"); 424 BAILOUT("ThisFunction");
337 } 425 }
338 426
339 #undef BAILOUT 427 #undef BAILOUT
340 #undef CHECK_BAILOUT 428 #undef CHECK_BAILOUT
341 429
342 430
343 #define __ ACCESS_MASM(masm()) 431 #define __ ACCESS_MASM(masm())
344 432
345 Handle<Code> FastCodeGenerator::MakeCode(CompilationInfo* info) { 433 Handle<Code> FastCodeGenerator::MakeCode(CompilationInfo* info) {
346 // Label the AST before calling MakeCodePrologue, so AST node numbers are 434 // Label the AST before calling MakeCodePrologue, so AST node numbers are
347 // printed with the AST. 435 // printed with the AST.
348 AstLabeler labeler; 436 AstLabeler labeler;
349 labeler.Label(info); 437 labeler.Label(info);
350 438
439 LivenessAnalyzer analyzer;
440 analyzer.Analyze(info->function());
441
351 CodeGenerator::MakeCodePrologue(info); 442 CodeGenerator::MakeCodePrologue(info);
352 443
353 const int kInitialBufferSize = 4 * KB; 444 const int kInitialBufferSize = 4 * KB;
354 MacroAssembler masm(NULL, kInitialBufferSize); 445 MacroAssembler masm(NULL, kInitialBufferSize);
355 446
356 // Generate the fast-path code. 447 // Generate the fast-path code.
357 FastCodeGenerator fast_cgen(&masm); 448 FastCodeGenerator fast_cgen(&masm);
358 fast_cgen.Generate(info); 449 fast_cgen.Generate(info);
359 if (fast_cgen.HasStackOverflow()) { 450 if (fast_cgen.HasStackOverflow()) {
360 ASSERT(!Top::has_pending_exception()); 451 ASSERT(!Top::has_pending_exception());
361 return Handle<Code>::null(); 452 return Handle<Code>::null();
362 } 453 }
363 454
364 // Generate the full code for the function in bailout mode, using the same 455 // Generate the full code for the function in bailout mode, using the same
365 // macro assembler. 456 // macro assembler.
366 CodeGenerator cgen(&masm); 457 CodeGenerator cgen(&masm);
367 CodeGeneratorScope scope(&cgen); 458 CodeGeneratorScope scope(&cgen);
368 cgen.Generate(info, CodeGenerator::SECONDARY); 459 info->set_mode(CompilationInfo::SECONDARY);
460 cgen.Generate(info);
369 if (cgen.HasStackOverflow()) { 461 if (cgen.HasStackOverflow()) {
370 ASSERT(!Top::has_pending_exception()); 462 ASSERT(!Top::has_pending_exception());
371 return Handle<Code>::null(); 463 return Handle<Code>::null();
372 } 464 }
373 465
374 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); 466 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
375 return CodeGenerator::MakeCodeEpilogue(&masm, flags, info); 467 return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
376 } 468 }
377 469
378 470
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 } 574 }
483 575
484 576
485 void FastCodeGenerator::VisitSlot(Slot* expr) { 577 void FastCodeGenerator::VisitSlot(Slot* expr) {
486 UNREACHABLE(); 578 UNREACHABLE();
487 } 579 }
488 580
489 581
490 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 582 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
491 ASSERT(expr->var()->is_global() && !expr->var()->is_this()); 583 ASSERT(expr->var()->is_global() && !expr->var()->is_this());
492 Comment cmnt(masm(), ";; Global");
493 if (FLAG_print_ir) {
494 SmartPointer<char> name = expr->name()->ToCString();
495 PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
496 }
497
498 // Check if we can compile a global variable load directly from the cell. 584 // Check if we can compile a global variable load directly from the cell.
499 ASSERT(info()->has_global_object()); 585 ASSERT(info()->has_global_object());
500 LookupResult lookup; 586 LookupResult lookup;
501 info()->global_object()->Lookup(*expr->name(), &lookup); 587 info()->global_object()->Lookup(*expr->name(), &lookup);
502 // We only support DontDelete properties for now. 588 // We only support normal (non-accessor/interceptor) DontDelete properties
503 ASSERT(lookup.IsValid()); 589 // for now.
590 ASSERT(lookup.IsProperty());
591 ASSERT_EQ(NORMAL, lookup.type());
504 ASSERT(lookup.IsDontDelete()); 592 ASSERT(lookup.IsDontDelete());
505 Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup)); 593 Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
506 EmitGlobalVariableLoad(cell); 594
595 // Global variable lookups do not have side effects, so we do not need to
596 // emit code if we are in an effect context.
597 if (!destination().is(no_reg)) {
598 Comment cmnt(masm(), ";; Global");
599 if (FLAG_print_ir) {
600 SmartPointer<char> name = expr->name()->ToCString();
601 PrintF("%d: t%d = Global(%s) // last_use = %d\n", expr->num(),
602 expr->num(), *name, expr->var_def()->last_use()->num());
603 }
604 EmitGlobalVariableLoad(cell);
605 }
507 } 606 }
508 607
509 608
510 void FastCodeGenerator::VisitLiteral(Literal* expr) { 609 void FastCodeGenerator::VisitLiteral(Literal* expr) {
511 UNREACHABLE(); 610 UNREACHABLE();
512 } 611 }
513 612
514 613
515 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 614 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
516 UNREACHABLE(); 615 UNREACHABLE();
517 } 616 }
518 617
519 618
520 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 619 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
521 UNREACHABLE(); 620 UNREACHABLE();
522 } 621 }
523 622
524 623
525 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 624 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
526 UNREACHABLE(); 625 UNREACHABLE();
527 } 626 }
528 627
529 628
530 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 629 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
531 UNREACHABLE(); 630 UNREACHABLE();
532 } 631 }
533 632
534 633
535 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 634 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
536 // Known to be a simple this property assignment. 635 // Known to be a simple this property assignment. Effectively a unary
537 Visit(expr->value()); 636 // operation.
637 { Register my_destination = destination();
638 set_destination(accumulator0());
639 Visit(expr->value());
640 set_destination(my_destination);
641 }
538 642
539 Property* prop = expr->target()->AsProperty(); 643 Property* prop = expr->target()->AsProperty();
540 ASSERT_NOT_NULL(prop); 644 ASSERT_NOT_NULL(prop);
541 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy()); 645 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
542 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this()); 646 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
543 ASSERT(prop->key()->IsPropertyName()); 647 ASSERT(prop->key()->IsPropertyName());
544 Handle<String> name = 648 Handle<String> name =
545 Handle<String>::cast(prop->key()->AsLiteral()->handle()); 649 Handle<String>::cast(prop->key()->AsLiteral()->handle());
546 650
547 Comment cmnt(masm(), ";; Store(this)"); 651 Comment cmnt(masm(), ";; Store to this");
548 if (FLAG_print_ir) { 652 if (FLAG_print_ir) {
549 SmartPointer<char> name_string = name->ToCString(); 653 SmartPointer<char> name_string = name->ToCString();
550 PrintF("%d: t%d = Store(this, \"%s\", t%d)\n", 654 PrintF("%d: ", expr->num());
551 expr->num(), expr->num(), *name_string, expr->value()->num()); 655 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
656 PrintF("Store(this, \"%s\", t%d) // last_use(this) = %d\n", *name_string,
657 expr->value()->num(),
658 expr->var_def()->last_use()->num());
552 } 659 }
553 660
554 EmitThisPropertyStore(name); 661 EmitThisPropertyStore(name);
555 } 662 }
556 663
557 664
558 void FastCodeGenerator::VisitThrow(Throw* expr) { 665 void FastCodeGenerator::VisitThrow(Throw* expr) {
559 UNREACHABLE(); 666 UNREACHABLE();
560 } 667 }
561 668
562 669
563 void FastCodeGenerator::VisitProperty(Property* expr) { 670 void FastCodeGenerator::VisitProperty(Property* expr) {
564 UNREACHABLE(); 671 ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
672 ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
673 ASSERT(expr->key()->IsPropertyName());
674 if (!destination().is(no_reg)) {
675 Handle<String> name =
676 Handle<String>::cast(expr->key()->AsLiteral()->handle());
677
678 Comment cmnt(masm(), ";; Load from this");
679 if (FLAG_print_ir) {
680 SmartPointer<char> name_string = name->ToCString();
681 PrintF("%d: t%d = Load(this, \"%s\") // last_use(this) = %d\n",
682 expr->num(), expr->num(), *name_string,
683 expr->var_def()->last_use()->num());
684 }
685 EmitThisPropertyLoad(name);
686 }
565 } 687 }
566 688
567 689
568 void FastCodeGenerator::VisitCall(Call* expr) { 690 void FastCodeGenerator::VisitCall(Call* expr) {
569 UNREACHABLE(); 691 UNREACHABLE();
570 } 692 }
571 693
572 694
573 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 695 void FastCodeGenerator::VisitCallNew(CallNew* expr) {
574 UNREACHABLE(); 696 UNREACHABLE();
575 } 697 }
576 698
577 699
578 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 700 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
579 UNREACHABLE(); 701 UNREACHABLE();
580 } 702 }
581 703
582 704
583 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 705 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
584 UNREACHABLE(); 706 UNREACHABLE();
585 } 707 }
586 708
587 709
588 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 710 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
589 UNREACHABLE(); 711 UNREACHABLE();
590 } 712 }
591 713
592 714
593 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 715 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
594 UNREACHABLE(); 716 // We support limited binary operations: bitwise OR only allowed to be
717 // nested on the left.
718 ASSERT(expr->op() == Token::BIT_OR);
719 ASSERT(expr->right()->IsLeaf());
720
721 { Register my_destination = destination();
722 set_destination(accumulator1());
723 Visit(expr->left());
724 set_destination(accumulator0());
725 Visit(expr->right());
726 set_destination(my_destination);
727 }
728
729 Comment cmnt(masm(), ";; BIT_OR");
730 if (FLAG_print_ir) {
731 PrintF("%d: ", expr->num());
732 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
733 PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
734 }
735 EmitBitOr();
595 } 736 }
596 737
597 738
598 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 739 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
599 UNREACHABLE(); 740 UNREACHABLE();
600 } 741 }
601 742
602 743
603 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 744 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
604 UNREACHABLE(); 745 UNREACHABLE();
605 } 746 }
606 747
607 #undef __ 748 #undef __
608 749
609 750
610 } } // namespace v8::internal 751 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/frame-element.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698