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

Side by Side Diff: src/ia32/fast-codegen-ia32.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/ia32/codegen-ia32.h ('k') | src/x64/codegen-x64.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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // formal parameter count expected by the function. 44 // formal parameter count expected by the function.
45 // 45 //
46 // The live registers are: 46 // The live registers are:
47 // o edi: the JS function object being called (ie, ourselves) 47 // o edi: the JS function object being called (ie, ourselves)
48 // o esi: our context 48 // o esi: our context
49 // o ebp: our caller's frame pointer 49 // o ebp: our caller's frame pointer
50 // o esp: stack pointer (pointing to return address) 50 // o esp: stack pointer (pointing to return address)
51 // 51 //
52 // The function builds a JS frame. Please see JavaScriptFrameConstants in 52 // The function builds a JS frame. Please see JavaScriptFrameConstants in
53 // frames-ia32.h for its layout. 53 // frames-ia32.h for its layout.
54 void FastCodeGenerator::Generate(FunctionLiteral* fun) { 54 void FullCodeGenerator::Generate(FunctionLiteral* fun) {
55 function_ = fun; 55 function_ = fun;
56 SetFunctionPosition(fun); 56 SetFunctionPosition(fun);
57 57
58 __ push(ebp); // Caller's frame pointer. 58 __ push(ebp); // Caller's frame pointer.
59 __ mov(ebp, esp); 59 __ mov(ebp, esp);
60 __ push(esi); // Callee's context. 60 __ push(esi); // Callee's context.
61 __ push(edi); // Callee's JS Function. 61 __ push(edi); // Callee's JS Function.
62 62
63 { Comment cmnt(masm_, "[ Allocate locals"); 63 { Comment cmnt(masm_, "[ Allocate locals");
64 int locals_count = fun->scope()->num_stack_slots(); 64 int locals_count = fun->scope()->num_stack_slots();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 153 }
154 154
155 { Comment cmnt(masm_, "[ return <undefined>;"); 155 { Comment cmnt(masm_, "[ return <undefined>;");
156 // Emit a 'return undefined' in case control fell off the end of the body. 156 // Emit a 'return undefined' in case control fell off the end of the body.
157 __ mov(eax, Factory::undefined_value()); 157 __ mov(eax, Factory::undefined_value());
158 EmitReturnSequence(function_->end_position()); 158 EmitReturnSequence(function_->end_position());
159 } 159 }
160 } 160 }
161 161
162 162
163 void FastCodeGenerator::EmitReturnSequence(int position) { 163 void FullCodeGenerator::EmitReturnSequence(int position) {
164 Comment cmnt(masm_, "[ Return sequence"); 164 Comment cmnt(masm_, "[ Return sequence");
165 if (return_label_.is_bound()) { 165 if (return_label_.is_bound()) {
166 __ jmp(&return_label_); 166 __ jmp(&return_label_);
167 } else { 167 } else {
168 // Common return label 168 // Common return label
169 __ bind(&return_label_); 169 __ bind(&return_label_);
170 if (FLAG_trace) { 170 if (FLAG_trace) {
171 __ push(eax); 171 __ push(eax);
172 __ CallRuntime(Runtime::kTraceExit, 1); 172 __ CallRuntime(Runtime::kTraceExit, 1);
173 } 173 }
(...skipping 12 matching lines...) Expand all
186 #ifdef ENABLE_DEBUGGER_SUPPORT 186 #ifdef ENABLE_DEBUGGER_SUPPORT
187 // Check that the size of the code used for returning matches what is 187 // Check that the size of the code used for returning matches what is
188 // expected by the debugger. 188 // expected by the debugger.
189 ASSERT_EQ(Assembler::kJSReturnSequenceLength, 189 ASSERT_EQ(Assembler::kJSReturnSequenceLength,
190 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 190 masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
191 #endif 191 #endif
192 } 192 }
193 } 193 }
194 194
195 195
196 void FastCodeGenerator::Apply(Expression::Context context, Register reg) { 196 void FullCodeGenerator::Apply(Expression::Context context, Register reg) {
197 switch (context) { 197 switch (context) {
198 case Expression::kUninitialized: 198 case Expression::kUninitialized:
199 UNREACHABLE(); 199 UNREACHABLE();
200 200
201 case Expression::kEffect: 201 case Expression::kEffect:
202 // Nothing to do. 202 // Nothing to do.
203 break; 203 break;
204 204
205 case Expression::kValue: 205 case Expression::kValue:
206 // Move value into place. 206 // Move value into place.
(...skipping 22 matching lines...) Expand all
229 case kStack: 229 case kStack:
230 __ push(result_register()); 230 __ push(result_register());
231 break; 231 break;
232 } 232 }
233 DoTest(context); 233 DoTest(context);
234 break; 234 break;
235 } 235 }
236 } 236 }
237 237
238 238
239 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { 239 void FullCodeGenerator::Apply(Expression::Context context, Slot* slot) {
240 switch (context) { 240 switch (context) {
241 case Expression::kUninitialized: 241 case Expression::kUninitialized:
242 UNREACHABLE(); 242 UNREACHABLE();
243 case Expression::kEffect: 243 case Expression::kEffect:
244 // Nothing to do. 244 // Nothing to do.
245 break; 245 break;
246 case Expression::kValue: { 246 case Expression::kValue: {
247 MemOperand slot_operand = EmitSlotSearch(slot, result_register()); 247 MemOperand slot_operand = EmitSlotSearch(slot, result_register());
248 switch (location_) { 248 switch (location_) {
249 case kAccumulator: 249 case kAccumulator:
(...skipping 22 matching lines...) Expand all
272 case kStack: 272 case kStack:
273 __ push(result_register()); 273 __ push(result_register());
274 break; 274 break;
275 } 275 }
276 DoTest(context); 276 DoTest(context);
277 break; 277 break;
278 } 278 }
279 } 279 }
280 280
281 281
282 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { 282 void FullCodeGenerator::Apply(Expression::Context context, Literal* lit) {
283 switch (context) { 283 switch (context) {
284 case Expression::kUninitialized: 284 case Expression::kUninitialized:
285 UNREACHABLE(); 285 UNREACHABLE();
286 case Expression::kEffect: 286 case Expression::kEffect:
287 // Nothing to do. 287 // Nothing to do.
288 break; 288 break;
289 case Expression::kValue: 289 case Expression::kValue:
290 switch (location_) { 290 switch (location_) {
291 case kAccumulator: 291 case kAccumulator:
292 __ mov(result_register(), lit->handle()); 292 __ mov(result_register(), lit->handle());
(...skipping 20 matching lines...) Expand all
313 case kStack: 313 case kStack:
314 __ push(result_register()); 314 __ push(result_register());
315 break; 315 break;
316 } 316 }
317 DoTest(context); 317 DoTest(context);
318 break; 318 break;
319 } 319 }
320 } 320 }
321 321
322 322
323 void FastCodeGenerator::ApplyTOS(Expression::Context context) { 323 void FullCodeGenerator::ApplyTOS(Expression::Context context) {
324 switch (context) { 324 switch (context) {
325 case Expression::kUninitialized: 325 case Expression::kUninitialized:
326 UNREACHABLE(); 326 UNREACHABLE();
327 327
328 case Expression::kEffect: 328 case Expression::kEffect:
329 __ Drop(1); 329 __ Drop(1);
330 break; 330 break;
331 331
332 case Expression::kValue: 332 case Expression::kValue:
333 switch (location_) { 333 switch (location_) {
(...skipping 20 matching lines...) Expand all
354 case kStack: 354 case kStack:
355 __ mov(result_register(), Operand(esp, 0)); 355 __ mov(result_register(), Operand(esp, 0));
356 break; 356 break;
357 } 357 }
358 DoTest(context); 358 DoTest(context);
359 break; 359 break;
360 } 360 }
361 } 361 }
362 362
363 363
364 void FastCodeGenerator::DropAndApply(int count, 364 void FullCodeGenerator::DropAndApply(int count,
365 Expression::Context context, 365 Expression::Context context,
366 Register reg) { 366 Register reg) {
367 ASSERT(count > 0); 367 ASSERT(count > 0);
368 ASSERT(!reg.is(esp)); 368 ASSERT(!reg.is(esp));
369 switch (context) { 369 switch (context) {
370 case Expression::kUninitialized: 370 case Expression::kUninitialized:
371 UNREACHABLE(); 371 UNREACHABLE();
372 372
373 case Expression::kEffect: 373 case Expression::kEffect:
374 __ Drop(count); 374 __ Drop(count);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 __ mov(result_register(), reg); 406 __ mov(result_register(), reg);
407 __ mov(Operand(esp, 0), result_register()); 407 __ mov(Operand(esp, 0), result_register());
408 break; 408 break;
409 } 409 }
410 DoTest(context); 410 DoTest(context);
411 break; 411 break;
412 } 412 }
413 } 413 }
414 414
415 415
416 void FastCodeGenerator::Apply(Expression::Context context, 416 void FullCodeGenerator::Apply(Expression::Context context,
417 Label* materialize_true, 417 Label* materialize_true,
418 Label* materialize_false) { 418 Label* materialize_false) {
419 switch (context) { 419 switch (context) {
420 case Expression::kUninitialized: 420 case Expression::kUninitialized:
421 421
422 case Expression::kEffect: 422 case Expression::kEffect:
423 ASSERT_EQ(materialize_true, materialize_false); 423 ASSERT_EQ(materialize_true, materialize_false);
424 __ bind(materialize_true); 424 __ bind(materialize_true);
425 break; 425 break;
426 426
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 case kStack: 471 case kStack:
472 __ push(Immediate(Factory::false_value())); 472 __ push(Immediate(Factory::false_value()));
473 break; 473 break;
474 } 474 }
475 __ jmp(false_label_); 475 __ jmp(false_label_);
476 break; 476 break;
477 } 477 }
478 } 478 }
479 479
480 480
481 void FastCodeGenerator::DoTest(Expression::Context context) { 481 void FullCodeGenerator::DoTest(Expression::Context context) {
482 // The value to test is in the accumulator. If the value might be needed 482 // The value to test is in the accumulator. If the value might be needed
483 // on the stack (value/test and test/value contexts with a stack location 483 // on the stack (value/test and test/value contexts with a stack location
484 // desired), then the value is already duplicated on the stack. 484 // desired), then the value is already duplicated on the stack.
485 ASSERT_NE(NULL, true_label_); 485 ASSERT_NE(NULL, true_label_);
486 ASSERT_NE(NULL, false_label_); 486 ASSERT_NE(NULL, false_label_);
487 487
488 // In value/test and test/value expression contexts with stack as the 488 // In value/test and test/value expression contexts with stack as the
489 // desired location, there is already an extra value on the stack. Use a 489 // desired location, there is already an extra value on the stack. Use a
490 // label to discard it if unneeded. 490 // label to discard it if unneeded.
491 Label discard; 491 Label discard;
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 break; 605 break;
606 } 606 }
607 __ bind(&discard); 607 __ bind(&discard);
608 __ Drop(1); 608 __ Drop(1);
609 __ jmp(true_label_); 609 __ jmp(true_label_);
610 break; 610 break;
611 } 611 }
612 } 612 }
613 613
614 614
615 MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) { 615 MemOperand FullCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
616 switch (slot->type()) { 616 switch (slot->type()) {
617 case Slot::PARAMETER: 617 case Slot::PARAMETER:
618 case Slot::LOCAL: 618 case Slot::LOCAL:
619 return Operand(ebp, SlotOffset(slot)); 619 return Operand(ebp, SlotOffset(slot));
620 case Slot::CONTEXT: { 620 case Slot::CONTEXT: {
621 int context_chain_length = 621 int context_chain_length =
622 function_->scope()->ContextChainLength(slot->var()->scope()); 622 function_->scope()->ContextChainLength(slot->var()->scope());
623 __ LoadContext(scratch, context_chain_length); 623 __ LoadContext(scratch, context_chain_length);
624 return CodeGenerator::ContextOperand(scratch, slot->index()); 624 return CodeGenerator::ContextOperand(scratch, slot->index());
625 } 625 }
626 case Slot::LOOKUP: 626 case Slot::LOOKUP:
627 UNREACHABLE(); 627 UNREACHABLE();
628 } 628 }
629 UNREACHABLE(); 629 UNREACHABLE();
630 return Operand(eax, 0); 630 return Operand(eax, 0);
631 } 631 }
632 632
633 633
634 void FastCodeGenerator::Move(Register destination, Slot* source) { 634 void FullCodeGenerator::Move(Register destination, Slot* source) {
635 MemOperand location = EmitSlotSearch(source, destination); 635 MemOperand location = EmitSlotSearch(source, destination);
636 __ mov(destination, location); 636 __ mov(destination, location);
637 } 637 }
638 638
639 639
640 void FastCodeGenerator::Move(Slot* dst, 640 void FullCodeGenerator::Move(Slot* dst,
641 Register src, 641 Register src,
642 Register scratch1, 642 Register scratch1,
643 Register scratch2) { 643 Register scratch2) {
644 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented. 644 ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
645 ASSERT(!scratch1.is(src) && !scratch2.is(src)); 645 ASSERT(!scratch1.is(src) && !scratch2.is(src));
646 MemOperand location = EmitSlotSearch(dst, scratch1); 646 MemOperand location = EmitSlotSearch(dst, scratch1);
647 __ mov(location, src); 647 __ mov(location, src);
648 // Emit the write barrier code if the location is in the heap. 648 // Emit the write barrier code if the location is in the heap.
649 if (dst->type() == Slot::CONTEXT) { 649 if (dst->type() == Slot::CONTEXT) {
650 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize; 650 int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
651 __ RecordWrite(scratch1, offset, src, scratch2); 651 __ RecordWrite(scratch1, offset, src, scratch2);
652 } 652 }
653 } 653 }
654 654
655 655
656 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { 656 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
657 Comment cmnt(masm_, "[ Declaration"); 657 Comment cmnt(masm_, "[ Declaration");
658 Variable* var = decl->proxy()->var(); 658 Variable* var = decl->proxy()->var();
659 ASSERT(var != NULL); // Must have been resolved. 659 ASSERT(var != NULL); // Must have been resolved.
660 Slot* slot = var->slot(); 660 Slot* slot = var->slot();
661 Property* prop = var->AsProperty(); 661 Property* prop = var->AsProperty();
662 662
663 if (slot != NULL) { 663 if (slot != NULL) {
664 switch (slot->type()) { 664 switch (slot->type()) {
665 case Slot::PARAMETER: 665 case Slot::PARAMETER:
666 case Slot::LOCAL: 666 case Slot::LOCAL:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 __ nop(); 744 __ nop();
745 745
746 // Value in eax is ignored (declarations are statements). Receiver 746 // Value in eax is ignored (declarations are statements). Receiver
747 // and key on stack are discarded. 747 // and key on stack are discarded.
748 __ Drop(2); 748 __ Drop(2);
749 } 749 }
750 } 750 }
751 } 751 }
752 752
753 753
754 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 754 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
755 // Call the runtime to declare the globals. 755 // Call the runtime to declare the globals.
756 __ push(esi); // The context is the first argument. 756 __ push(esi); // The context is the first argument.
757 __ push(Immediate(pairs)); 757 __ push(Immediate(pairs));
758 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0))); 758 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0)));
759 __ CallRuntime(Runtime::kDeclareGlobals, 3); 759 __ CallRuntime(Runtime::kDeclareGlobals, 3);
760 // Return value is ignored. 760 // Return value is ignored.
761 } 761 }
762 762
763 763
764 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 764 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
765 Comment cmnt(masm_, "[ FunctionLiteral"); 765 Comment cmnt(masm_, "[ FunctionLiteral");
766 766
767 // Build the function boilerplate and instantiate it. 767 // Build the function boilerplate and instantiate it.
768 Handle<JSFunction> boilerplate = 768 Handle<JSFunction> boilerplate =
769 Compiler::BuildBoilerplate(expr, script_, this); 769 Compiler::BuildBoilerplate(expr, script_, this);
770 if (HasStackOverflow()) return; 770 if (HasStackOverflow()) return;
771 771
772 ASSERT(boilerplate->IsBoilerplate()); 772 ASSERT(boilerplate->IsBoilerplate());
773 773
774 // Create a new closure. 774 // Create a new closure.
775 __ push(esi); 775 __ push(esi);
776 __ push(Immediate(boilerplate)); 776 __ push(Immediate(boilerplate));
777 __ CallRuntime(Runtime::kNewClosure, 2); 777 __ CallRuntime(Runtime::kNewClosure, 2);
778 Apply(context_, eax); 778 Apply(context_, eax);
779 } 779 }
780 780
781 781
782 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 782 void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
783 Comment cmnt(masm_, "[ VariableProxy"); 783 Comment cmnt(masm_, "[ VariableProxy");
784 EmitVariableLoad(expr->var(), context_); 784 EmitVariableLoad(expr->var(), context_);
785 } 785 }
786 786
787 787
788 void FastCodeGenerator::EmitVariableLoad(Variable* var, 788 void FullCodeGenerator::EmitVariableLoad(Variable* var,
789 Expression::Context context) { 789 Expression::Context context) {
790 Expression* rewrite = var->rewrite(); 790 Expression* rewrite = var->rewrite();
791 if (rewrite == NULL) { 791 if (rewrite == NULL) {
792 ASSERT(var->is_global()); 792 ASSERT(var->is_global());
793 Comment cmnt(masm_, "Global variable"); 793 Comment cmnt(masm_, "Global variable");
794 // Use inline caching. Variable name is passed in ecx and the global 794 // Use inline caching. Variable name is passed in ecx and the global
795 // object on the stack. 795 // object on the stack.
796 __ push(CodeGenerator::GlobalObject()); 796 __ push(CodeGenerator::GlobalObject());
797 __ mov(ecx, var->name()); 797 __ mov(ecx, var->name());
798 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 798 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 __ call(ic, RelocInfo::CODE_TARGET); 855 __ call(ic, RelocInfo::CODE_TARGET);
856 // Notice: We must not have a "test eax, ..." instruction after the 856 // Notice: We must not have a "test eax, ..." instruction after the
857 // call. It is treated specially by the LoadIC code. 857 // call. It is treated specially by the LoadIC code.
858 __ nop(); 858 __ nop();
859 // Drop key and object left on the stack by IC. 859 // Drop key and object left on the stack by IC.
860 DropAndApply(2, context, eax); 860 DropAndApply(2, context, eax);
861 } 861 }
862 } 862 }
863 863
864 864
865 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 865 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
866 Comment cmnt(masm_, "[ RegExpLiteral"); 866 Comment cmnt(masm_, "[ RegExpLiteral");
867 Label done; 867 Label done;
868 // Registers will be used as follows: 868 // Registers will be used as follows:
869 // edi = JS function. 869 // edi = JS function.
870 // ebx = literals array. 870 // ebx = literals array.
871 // eax = regexp literal. 871 // eax = regexp literal.
872 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 872 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
873 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 873 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
874 int literal_offset = 874 int literal_offset =
875 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 875 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
876 __ mov(eax, FieldOperand(ebx, literal_offset)); 876 __ mov(eax, FieldOperand(ebx, literal_offset));
877 __ cmp(eax, Factory::undefined_value()); 877 __ cmp(eax, Factory::undefined_value());
878 __ j(not_equal, &done); 878 __ j(not_equal, &done);
879 // Create regexp literal using runtime function 879 // Create regexp literal using runtime function
880 // Result will be in eax. 880 // Result will be in eax.
881 __ push(ebx); 881 __ push(ebx);
882 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 882 __ push(Immediate(Smi::FromInt(expr->literal_index())));
883 __ push(Immediate(expr->pattern())); 883 __ push(Immediate(expr->pattern()));
884 __ push(Immediate(expr->flags())); 884 __ push(Immediate(expr->flags()));
885 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 885 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
886 // Label done: 886 // Label done:
887 __ bind(&done); 887 __ bind(&done);
888 Apply(context_, eax); 888 Apply(context_, eax);
889 } 889 }
890 890
891 891
892 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 892 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
893 Comment cmnt(masm_, "[ ObjectLiteral"); 893 Comment cmnt(masm_, "[ ObjectLiteral");
894 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 894 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
895 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); 895 __ push(FieldOperand(edi, JSFunction::kLiteralsOffset));
896 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 896 __ push(Immediate(Smi::FromInt(expr->literal_index())));
897 __ push(Immediate(expr->constant_properties())); 897 __ push(Immediate(expr->constant_properties()));
898 if (expr->depth() > 1) { 898 if (expr->depth() > 1) {
899 __ CallRuntime(Runtime::kCreateObjectLiteral, 3); 899 __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
900 } else { 900 } else {
901 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3); 901 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
902 } 902 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 } 951 }
952 952
953 if (result_saved) { 953 if (result_saved) {
954 ApplyTOS(context_); 954 ApplyTOS(context_);
955 } else { 955 } else {
956 Apply(context_, eax); 956 Apply(context_, eax);
957 } 957 }
958 } 958 }
959 959
960 960
961 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 961 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
962 Comment cmnt(masm_, "[ ArrayLiteral"); 962 Comment cmnt(masm_, "[ ArrayLiteral");
963 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 963 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
964 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 964 __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
965 __ push(Immediate(Smi::FromInt(expr->literal_index()))); 965 __ push(Immediate(Smi::FromInt(expr->literal_index())));
966 __ push(Immediate(expr->constant_elements())); 966 __ push(Immediate(expr->constant_elements()));
967 if (expr->depth() > 1) { 967 if (expr->depth() > 1) {
968 __ CallRuntime(Runtime::kCreateArrayLiteral, 3); 968 __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
969 } else { 969 } else {
970 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 970 __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
971 } 971 }
(...skipping 29 matching lines...) Expand all
1001 } 1001 }
1002 1002
1003 if (result_saved) { 1003 if (result_saved) {
1004 ApplyTOS(context_); 1004 ApplyTOS(context_);
1005 } else { 1005 } else {
1006 Apply(context_, eax); 1006 Apply(context_, eax);
1007 } 1007 }
1008 } 1008 }
1009 1009
1010 1010
1011 void FastCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1011 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1012 SetSourcePosition(prop->position()); 1012 SetSourcePosition(prop->position());
1013 Literal* key = prop->key()->AsLiteral(); 1013 Literal* key = prop->key()->AsLiteral();
1014 __ mov(ecx, Immediate(key->handle())); 1014 __ mov(ecx, Immediate(key->handle()));
1015 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1015 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1016 __ call(ic, RelocInfo::CODE_TARGET); 1016 __ call(ic, RelocInfo::CODE_TARGET);
1017 __ nop(); 1017 __ nop();
1018 } 1018 }
1019 1019
1020 1020
1021 void FastCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1021 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1022 SetSourcePosition(prop->position()); 1022 SetSourcePosition(prop->position());
1023 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1023 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1024 __ call(ic, RelocInfo::CODE_TARGET); 1024 __ call(ic, RelocInfo::CODE_TARGET);
1025 __ nop(); 1025 __ nop();
1026 } 1026 }
1027 1027
1028 1028
1029 void FastCodeGenerator::EmitBinaryOp(Token::Value op, 1029 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1030 Expression::Context context) { 1030 Expression::Context context) {
1031 __ push(result_register()); 1031 __ push(result_register());
1032 GenericBinaryOpStub stub(op, 1032 GenericBinaryOpStub stub(op,
1033 NO_OVERWRITE, 1033 NO_OVERWRITE,
1034 NO_GENERIC_BINARY_FLAGS); 1034 NO_GENERIC_BINARY_FLAGS);
1035 __ CallStub(&stub); 1035 __ CallStub(&stub);
1036 Apply(context, eax); 1036 Apply(context, eax);
1037 } 1037 }
1038 1038
1039 1039
1040 void FastCodeGenerator::EmitVariableAssignment(Variable* var, 1040 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1041 Expression::Context context) { 1041 Expression::Context context) {
1042 ASSERT(var != NULL); 1042 ASSERT(var != NULL);
1043 ASSERT(var->is_global() || var->slot() != NULL); 1043 ASSERT(var->is_global() || var->slot() != NULL);
1044 if (var->is_global()) { 1044 if (var->is_global()) {
1045 // Assignment to a global variable. Use inline caching for the 1045 // Assignment to a global variable. Use inline caching for the
1046 // assignment. Right-hand-side value is passed in eax, variable name in 1046 // assignment. Right-hand-side value is passed in eax, variable name in
1047 // ecx, and the global object on the stack. 1047 // ecx, and the global object on the stack.
1048 __ mov(ecx, var->name()); 1048 __ mov(ecx, var->name());
1049 __ push(CodeGenerator::GlobalObject()); 1049 __ push(CodeGenerator::GlobalObject());
1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
(...skipping 28 matching lines...) Expand all
1079 Apply(context, result_register()); 1079 Apply(context, result_register());
1080 1080
1081 } else { 1081 } else {
1082 // Variables rewritten as properties are not treated as variables in 1082 // Variables rewritten as properties are not treated as variables in
1083 // assignments. 1083 // assignments.
1084 UNREACHABLE(); 1084 UNREACHABLE();
1085 } 1085 }
1086 } 1086 }
1087 1087
1088 1088
1089 void FastCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1089 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1090 // Assignment to a property, using a named store IC. 1090 // Assignment to a property, using a named store IC.
1091 Property* prop = expr->target()->AsProperty(); 1091 Property* prop = expr->target()->AsProperty();
1092 ASSERT(prop != NULL); 1092 ASSERT(prop != NULL);
1093 ASSERT(prop->key()->AsLiteral() != NULL); 1093 ASSERT(prop->key()->AsLiteral() != NULL);
1094 1094
1095 // If the assignment starts a block of assignments to the same object, 1095 // If the assignment starts a block of assignments to the same object,
1096 // change to slow case to avoid the quadratic behavior of repeatedly 1096 // change to slow case to avoid the quadratic behavior of repeatedly
1097 // adding fast properties. 1097 // adding fast properties.
1098 if (expr->starts_initialization_block()) { 1098 if (expr->starts_initialization_block()) {
1099 __ push(result_register()); 1099 __ push(result_register());
(...skipping 14 matching lines...) Expand all
1114 __ push(eax); // Result of assignment, saved even if not needed. 1114 __ push(eax); // Result of assignment, saved even if not needed.
1115 __ push(Operand(esp, kPointerSize)); // Receiver is under value. 1115 __ push(Operand(esp, kPointerSize)); // Receiver is under value.
1116 __ CallRuntime(Runtime::kToFastProperties, 1); 1116 __ CallRuntime(Runtime::kToFastProperties, 1);
1117 __ pop(eax); 1117 __ pop(eax);
1118 } 1118 }
1119 1119
1120 DropAndApply(1, context_, eax); 1120 DropAndApply(1, context_, eax);
1121 } 1121 }
1122 1122
1123 1123
1124 void FastCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 1124 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1125 // Assignment to a property, using a keyed store IC. 1125 // Assignment to a property, using a keyed store IC.
1126 1126
1127 // If the assignment starts a block of assignments to the same object, 1127 // If the assignment starts a block of assignments to the same object,
1128 // change to slow case to avoid the quadratic behavior of repeatedly 1128 // change to slow case to avoid the quadratic behavior of repeatedly
1129 // adding fast properties. 1129 // adding fast properties.
1130 if (expr->starts_initialization_block()) { 1130 if (expr->starts_initialization_block()) {
1131 __ push(result_register()); 1131 __ push(result_register());
1132 // Receiver is now under the key and value. 1132 // Receiver is now under the key and value.
1133 __ push(Operand(esp, 2 * kPointerSize)); 1133 __ push(Operand(esp, 2 * kPointerSize));
1134 __ CallRuntime(Runtime::kToSlowProperties, 1); 1134 __ CallRuntime(Runtime::kToSlowProperties, 1);
(...skipping 15 matching lines...) Expand all
1150 __ push(Operand(esp, 2 * kPointerSize)); 1150 __ push(Operand(esp, 2 * kPointerSize));
1151 __ CallRuntime(Runtime::kToFastProperties, 1); 1151 __ CallRuntime(Runtime::kToFastProperties, 1);
1152 __ pop(eax); 1152 __ pop(eax);
1153 } 1153 }
1154 1154
1155 // Receiver and key are still on stack. 1155 // Receiver and key are still on stack.
1156 DropAndApply(2, context_, eax); 1156 DropAndApply(2, context_, eax);
1157 } 1157 }
1158 1158
1159 1159
1160 void FastCodeGenerator::VisitProperty(Property* expr) { 1160 void FullCodeGenerator::VisitProperty(Property* expr) {
1161 Comment cmnt(masm_, "[ Property"); 1161 Comment cmnt(masm_, "[ Property");
1162 Expression* key = expr->key(); 1162 Expression* key = expr->key();
1163 1163
1164 // Evaluate the receiver. 1164 // Evaluate the receiver.
1165 VisitForValue(expr->obj(), kStack); 1165 VisitForValue(expr->obj(), kStack);
1166 1166
1167 if (key->IsPropertyName()) { 1167 if (key->IsPropertyName()) {
1168 EmitNamedPropertyLoad(expr); 1168 EmitNamedPropertyLoad(expr);
1169 // Drop receiver left on the stack by IC. 1169 // Drop receiver left on the stack by IC.
1170 DropAndApply(1, context_, eax); 1170 DropAndApply(1, context_, eax);
1171 } else { 1171 } else {
1172 VisitForValue(expr->key(), kStack); 1172 VisitForValue(expr->key(), kStack);
1173 EmitKeyedPropertyLoad(expr); 1173 EmitKeyedPropertyLoad(expr);
1174 // Drop key and receiver left on the stack by IC. 1174 // Drop key and receiver left on the stack by IC.
1175 DropAndApply(2, context_, eax); 1175 DropAndApply(2, context_, eax);
1176 } 1176 }
1177 } 1177 }
1178 1178
1179 1179
1180 void FastCodeGenerator::EmitCallWithIC(Call* expr, 1180 void FullCodeGenerator::EmitCallWithIC(Call* expr,
1181 Handle<Object> name, 1181 Handle<Object> name,
1182 RelocInfo::Mode mode) { 1182 RelocInfo::Mode mode) {
1183 // Code common for calls using the IC. 1183 // Code common for calls using the IC.
1184 ZoneList<Expression*>* args = expr->arguments(); 1184 ZoneList<Expression*>* args = expr->arguments();
1185 int arg_count = args->length(); 1185 int arg_count = args->length();
1186 for (int i = 0; i < arg_count; i++) { 1186 for (int i = 0; i < arg_count; i++) {
1187 VisitForValue(args->at(i), kStack); 1187 VisitForValue(args->at(i), kStack);
1188 } 1188 }
1189 __ Set(ecx, Immediate(name)); 1189 __ Set(ecx, Immediate(name));
1190 // Record source position of the IC call. 1190 // Record source position of the IC call.
1191 SetSourcePosition(expr->position()); 1191 SetSourcePosition(expr->position());
1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 1192 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); 1193 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
1194 __ call(ic, mode); 1194 __ call(ic, mode);
1195 // Restore context register. 1195 // Restore context register.
1196 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1196 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1197 Apply(context_, eax); 1197 Apply(context_, eax);
1198 } 1198 }
1199 1199
1200 1200
1201 void FastCodeGenerator::EmitCallWithStub(Call* expr) { 1201 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1202 // Code common for calls using the call stub. 1202 // Code common for calls using the call stub.
1203 ZoneList<Expression*>* args = expr->arguments(); 1203 ZoneList<Expression*>* args = expr->arguments();
1204 int arg_count = args->length(); 1204 int arg_count = args->length();
1205 for (int i = 0; i < arg_count; i++) { 1205 for (int i = 0; i < arg_count; i++) {
1206 VisitForValue(args->at(i), kStack); 1206 VisitForValue(args->at(i), kStack);
1207 } 1207 }
1208 // Record source position for debugger. 1208 // Record source position for debugger.
1209 SetSourcePosition(expr->position()); 1209 SetSourcePosition(expr->position());
1210 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE); 1210 CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1211 __ CallStub(&stub); 1211 __ CallStub(&stub);
1212 // Restore context register. 1212 // Restore context register.
1213 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1213 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1214 DropAndApply(1, context_, eax); 1214 DropAndApply(1, context_, eax);
1215 } 1215 }
1216 1216
1217 1217
1218 void FastCodeGenerator::VisitCall(Call* expr) { 1218 void FullCodeGenerator::VisitCall(Call* expr) {
1219 Comment cmnt(masm_, "[ Call"); 1219 Comment cmnt(masm_, "[ Call");
1220 Expression* fun = expr->expression(); 1220 Expression* fun = expr->expression();
1221 Variable* var = fun->AsVariableProxy()->AsVariable(); 1221 Variable* var = fun->AsVariableProxy()->AsVariable();
1222 1222
1223 if (var != NULL && var->is_possibly_eval()) { 1223 if (var != NULL && var->is_possibly_eval()) {
1224 // Call to the identifier 'eval'. 1224 // Call to the identifier 'eval'.
1225 UNREACHABLE(); 1225 UNREACHABLE();
1226 } else if (var != NULL && !var->is_this() && var->is_global()) { 1226 } else if (var != NULL && !var->is_this() && var->is_global()) {
1227 // Push global object as receiver for the call IC. 1227 // Push global object as receiver for the call IC.
1228 __ push(CodeGenerator::GlobalObject()); 1228 __ push(CodeGenerator::GlobalObject());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 VisitForValue(fun, kStack); 1279 VisitForValue(fun, kStack);
1280 // Load global receiver object. 1280 // Load global receiver object.
1281 __ mov(ebx, CodeGenerator::GlobalObject()); 1281 __ mov(ebx, CodeGenerator::GlobalObject());
1282 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 1282 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
1283 // Emit function call. 1283 // Emit function call.
1284 EmitCallWithStub(expr); 1284 EmitCallWithStub(expr);
1285 } 1285 }
1286 } 1286 }
1287 1287
1288 1288
1289 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 1289 void FullCodeGenerator::VisitCallNew(CallNew* expr) {
1290 Comment cmnt(masm_, "[ CallNew"); 1290 Comment cmnt(masm_, "[ CallNew");
1291 // According to ECMA-262, section 11.2.2, page 44, the function 1291 // According to ECMA-262, section 11.2.2, page 44, the function
1292 // expression in new calls must be evaluated before the 1292 // expression in new calls must be evaluated before the
1293 // arguments. 1293 // arguments.
1294 // Push function on the stack. 1294 // Push function on the stack.
1295 VisitForValue(expr->expression(), kStack); 1295 VisitForValue(expr->expression(), kStack);
1296 1296
1297 // Push global object (receiver). 1297 // Push global object (receiver).
1298 __ push(CodeGenerator::GlobalObject()); 1298 __ push(CodeGenerator::GlobalObject());
1299 1299
(...skipping 14 matching lines...) Expand all
1314 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize)); 1314 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
1315 1315
1316 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); 1316 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall));
1317 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL); 1317 __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
1318 1318
1319 // Replace function on TOS with result in eax, or pop it. 1319 // Replace function on TOS with result in eax, or pop it.
1320 DropAndApply(1, context_, eax); 1320 DropAndApply(1, context_, eax);
1321 } 1321 }
1322 1322
1323 1323
1324 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 1324 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1325 Comment cmnt(masm_, "[ CallRuntime"); 1325 Comment cmnt(masm_, "[ CallRuntime");
1326 ZoneList<Expression*>* args = expr->arguments(); 1326 ZoneList<Expression*>* args = expr->arguments();
1327 1327
1328 if (expr->is_jsruntime()) { 1328 if (expr->is_jsruntime()) {
1329 // Prepare for calling JS runtime function. 1329 // Prepare for calling JS runtime function.
1330 __ mov(eax, CodeGenerator::GlobalObject()); 1330 __ mov(eax, CodeGenerator::GlobalObject());
1331 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 1331 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
1332 } 1332 }
1333 1333
1334 // Push the arguments ("left-to-right"). 1334 // Push the arguments ("left-to-right").
(...skipping 11 matching lines...) Expand all
1346 // Restore context register. 1346 // Restore context register.
1347 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 1347 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
1348 } else { 1348 } else {
1349 // Call the C runtime function. 1349 // Call the C runtime function.
1350 __ CallRuntime(expr->function(), arg_count); 1350 __ CallRuntime(expr->function(), arg_count);
1351 } 1351 }
1352 Apply(context_, eax); 1352 Apply(context_, eax);
1353 } 1353 }
1354 1354
1355 1355
1356 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 1356 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1357 switch (expr->op()) { 1357 switch (expr->op()) {
1358 case Token::VOID: { 1358 case Token::VOID: {
1359 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 1359 Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1360 VisitForEffect(expr->expression()); 1360 VisitForEffect(expr->expression());
1361 switch (context_) { 1361 switch (context_) {
1362 case Expression::kUninitialized: 1362 case Expression::kUninitialized:
1363 UNREACHABLE(); 1363 UNREACHABLE();
1364 break; 1364 break;
1365 case Expression::kEffect: 1365 case Expression::kEffect:
1366 break; 1366 break;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 Apply(context_, eax); 1456 Apply(context_, eax);
1457 break; 1457 break;
1458 } 1458 }
1459 1459
1460 default: 1460 default:
1461 UNREACHABLE(); 1461 UNREACHABLE();
1462 } 1462 }
1463 } 1463 }
1464 1464
1465 1465
1466 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 1466 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1467 Comment cmnt(masm_, "[ CountOperation"); 1467 Comment cmnt(masm_, "[ CountOperation");
1468 1468
1469 // Expression can only be a property, a global or a (parameter or local) 1469 // Expression can only be a property, a global or a (parameter or local)
1470 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1470 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1471 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1471 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1472 LhsKind assign_type = VARIABLE; 1472 LhsKind assign_type = VARIABLE;
1473 Property* prop = expr->expression()->AsProperty(); 1473 Property* prop = expr->expression()->AsProperty();
1474 // In case of a property we use the uninitialized expression context 1474 // In case of a property we use the uninitialized expression context
1475 // of the key to detect a named property. 1475 // of the key to detect a named property.
1476 if (prop != NULL) { 1476 if (prop != NULL) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 } 1588 }
1589 } else { 1589 } else {
1590 DropAndApply(2, context_, eax); 1590 DropAndApply(2, context_, eax);
1591 } 1591 }
1592 break; 1592 break;
1593 } 1593 }
1594 } 1594 }
1595 } 1595 }
1596 1596
1597 1597
1598 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 1598 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1599 Comment cmnt(masm_, "[ BinaryOperation"); 1599 Comment cmnt(masm_, "[ BinaryOperation");
1600 switch (expr->op()) { 1600 switch (expr->op()) {
1601 case Token::COMMA: 1601 case Token::COMMA:
1602 VisitForEffect(expr->left()); 1602 VisitForEffect(expr->left());
1603 Visit(expr->right()); 1603 Visit(expr->right());
1604 break; 1604 break;
1605 1605
1606 case Token::OR: 1606 case Token::OR:
1607 case Token::AND: 1607 case Token::AND:
1608 EmitLogicalOperation(expr); 1608 EmitLogicalOperation(expr);
(...skipping 14 matching lines...) Expand all
1623 VisitForValue(expr->right(), kAccumulator); 1623 VisitForValue(expr->right(), kAccumulator);
1624 EmitBinaryOp(expr->op(), context_); 1624 EmitBinaryOp(expr->op(), context_);
1625 break; 1625 break;
1626 1626
1627 default: 1627 default:
1628 UNREACHABLE(); 1628 UNREACHABLE();
1629 } 1629 }
1630 } 1630 }
1631 1631
1632 1632
1633 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1633 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1634 Comment cmnt(masm_, "[ CompareOperation"); 1634 Comment cmnt(masm_, "[ CompareOperation");
1635 1635
1636 // Always perform the comparison for its control flow. Pack the result 1636 // Always perform the comparison for its control flow. Pack the result
1637 // into the expression's context after the comparison is performed. 1637 // into the expression's context after the comparison is performed.
1638 Label materialize_true, materialize_false, done; 1638 Label materialize_true, materialize_false, done;
1639 // Initially assume we are in a test context. 1639 // Initially assume we are in a test context.
1640 Label* if_true = true_label_; 1640 Label* if_true = true_label_;
1641 Label* if_false = false_label_; 1641 Label* if_false = false_label_;
1642 switch (context_) { 1642 switch (context_) {
1643 case Expression::kUninitialized: 1643 case Expression::kUninitialized:
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 __ jmp(if_false); 1738 __ jmp(if_false);
1739 } 1739 }
1740 } 1740 }
1741 1741
1742 // Convert the result of the comparison into one expected for this 1742 // Convert the result of the comparison into one expected for this
1743 // expression's context. 1743 // expression's context.
1744 Apply(context_, if_true, if_false); 1744 Apply(context_, if_true, if_false);
1745 } 1745 }
1746 1746
1747 1747
1748 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1748 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1749 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1749 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1750 Apply(context_, eax); 1750 Apply(context_, eax);
1751 } 1751 }
1752 1752
1753 1753
1754 Register FastCodeGenerator::result_register() { return eax; } 1754 Register FullCodeGenerator::result_register() { return eax; }
1755 1755
1756 1756
1757 Register FastCodeGenerator::context_register() { return esi; } 1757 Register FullCodeGenerator::context_register() { return esi; }
1758 1758
1759 1759
1760 void FastCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 1760 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
1761 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 1761 ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
1762 __ mov(Operand(ebp, frame_offset), value); 1762 __ mov(Operand(ebp, frame_offset), value);
1763 } 1763 }
1764 1764
1765 1765
1766 void FastCodeGenerator::LoadContextField(Register dst, int context_index) { 1766 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
1767 __ mov(dst, CodeGenerator::ContextOperand(esi, context_index)); 1767 __ mov(dst, CodeGenerator::ContextOperand(esi, context_index));
1768 } 1768 }
1769 1769
1770 1770
1771 // ---------------------------------------------------------------------------- 1771 // ----------------------------------------------------------------------------
1772 // Non-local control flow support. 1772 // Non-local control flow support.
1773 1773
1774 void FastCodeGenerator::EnterFinallyBlock() { 1774 void FullCodeGenerator::EnterFinallyBlock() {
1775 // Cook return address on top of stack (smi encoded Code* delta) 1775 // Cook return address on top of stack (smi encoded Code* delta)
1776 ASSERT(!result_register().is(edx)); 1776 ASSERT(!result_register().is(edx));
1777 __ mov(edx, Operand(esp, 0)); 1777 __ mov(edx, Operand(esp, 0));
1778 __ sub(Operand(edx), Immediate(masm_->CodeObject())); 1778 __ sub(Operand(edx), Immediate(masm_->CodeObject()));
1779 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); 1779 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
1780 ASSERT_EQ(0, kSmiTag); 1780 ASSERT_EQ(0, kSmiTag);
1781 __ add(edx, Operand(edx)); // Convert to smi. 1781 __ add(edx, Operand(edx)); // Convert to smi.
1782 __ mov(Operand(esp, 0), edx); 1782 __ mov(Operand(esp, 0), edx);
1783 // Store result register while executing finally block. 1783 // Store result register while executing finally block.
1784 __ push(result_register()); 1784 __ push(result_register());
1785 } 1785 }
1786 1786
1787 1787
1788 void FastCodeGenerator::ExitFinallyBlock() { 1788 void FullCodeGenerator::ExitFinallyBlock() {
1789 ASSERT(!result_register().is(edx)); 1789 ASSERT(!result_register().is(edx));
1790 // Restore result register from stack. 1790 // Restore result register from stack.
1791 __ pop(result_register()); 1791 __ pop(result_register());
1792 // Uncook return address. 1792 // Uncook return address.
1793 __ mov(edx, Operand(esp, 0)); 1793 __ mov(edx, Operand(esp, 0));
1794 __ sar(edx, 1); // Convert smi to int. 1794 __ sar(edx, 1); // Convert smi to int.
1795 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1795 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1796 __ mov(Operand(esp, 0), edx); 1796 __ mov(Operand(esp, 0), edx);
1797 // And return. 1797 // And return.
1798 __ ret(0); 1798 __ ret(0);
1799 } 1799 }
1800 1800
1801 1801
1802 #undef __ 1802 #undef __
1803 1803
1804 } } // namespace v8::internal 1804 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698