OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 | 190 |
191 ZoneList<Statement*>* body = fun->body(); | 191 ZoneList<Statement*>* body = fun->body(); |
192 | 192 |
193 // Initialize state. | 193 // Initialize state. |
194 ASSERT(scope_ == NULL); | 194 ASSERT(scope_ == NULL); |
195 scope_ = fun->scope(); | 195 scope_ = fun->scope(); |
196 ASSERT(frame_ == NULL); | 196 ASSERT(frame_ == NULL); |
197 VirtualFrame virtual_frame(this); | 197 VirtualFrame virtual_frame(this); |
198 frame_ = &virtual_frame; | 198 frame_ = &virtual_frame; |
199 cc_reg_ = no_condition; | 199 cc_reg_ = no_condition; |
| 200 |
| 201 // Adjust for function-level loop nesting. |
| 202 loop_nesting_ += fun->loop_nesting(); |
| 203 |
200 { | 204 { |
201 CodeGenState state(this); | 205 CodeGenState state(this); |
202 | 206 |
203 // Entry | 207 // Entry |
204 // stack: function, receiver, arguments, return address | 208 // stack: function, receiver, arguments, return address |
205 // esp: stack pointer | 209 // esp: stack pointer |
206 // ebp: frame pointer | 210 // ebp: frame pointer |
207 // edi: caller's parameter pointer | 211 // edi: caller's parameter pointer |
208 // esi: callee's context | 212 // esi: callee's context |
209 | 213 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 // Generate a return statement if necessary. | 380 // Generate a return statement if necessary. |
377 if (body->is_empty() || body->last()->AsReturnStatement() == NULL) { | 381 if (body->is_empty() || body->last()->AsReturnStatement() == NULL) { |
378 Literal undefined(Factory::undefined_value()); | 382 Literal undefined(Factory::undefined_value()); |
379 ReturnStatement statement(&undefined); | 383 ReturnStatement statement(&undefined); |
380 statement.set_statement_pos(fun->end_position()); | 384 statement.set_statement_pos(fun->end_position()); |
381 VisitReturnStatement(&statement); | 385 VisitReturnStatement(&statement); |
382 } | 386 } |
383 } | 387 } |
384 } | 388 } |
385 | 389 |
| 390 // Adjust for function-level loop nesting. |
| 391 loop_nesting_ -= fun->loop_nesting(); |
| 392 |
386 // Code generation state must be reset. | 393 // Code generation state must be reset. |
387 scope_ = NULL; | 394 scope_ = NULL; |
388 frame_ = NULL; | 395 frame_ = NULL; |
389 ASSERT(!has_cc()); | 396 ASSERT(!has_cc()); |
390 ASSERT(state_ == NULL); | 397 ASSERT(state_ == NULL); |
| 398 ASSERT(loop_nesting() == 0); |
391 } | 399 } |
392 | 400 |
393 | 401 |
394 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { | 402 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { |
395 // Currently, this assertion will fail if we try to assign to | 403 // Currently, this assertion will fail if we try to assign to |
396 // a constant variable that is constant because it is read-only | 404 // a constant variable that is constant because it is read-only |
397 // (such as the variable referring to a named function expression). | 405 // (such as the variable referring to a named function expression). |
398 // We need to implement assignments to read-only variables. | 406 // We need to implement assignments to read-only variables. |
399 // Ideally, we should do this during AST generation (by converting | 407 // Ideally, we should do this during AST generation (by converting |
400 // such assignments into expression statements); however, in general | 408 // such assignments into expression statements); however, in general |
(...skipping 2286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 // JavaScript example: 'foo(1, 2, 3)' // foo is global | 2695 // JavaScript example: 'foo(1, 2, 3)' // foo is global |
2688 // ---------------------------------- | 2696 // ---------------------------------- |
2689 | 2697 |
2690 // Push the name of the function and the receiver onto the stack. | 2698 // Push the name of the function and the receiver onto the stack. |
2691 frame_->Push(Immediate(var->name())); | 2699 frame_->Push(Immediate(var->name())); |
2692 | 2700 |
2693 // Pass the global object as the receiver and let the IC stub | 2701 // Pass the global object as the receiver and let the IC stub |
2694 // patch the stack to use the global proxy as 'this' in the | 2702 // patch the stack to use the global proxy as 'this' in the |
2695 // invoked function. | 2703 // invoked function. |
2696 LoadGlobal(); | 2704 LoadGlobal(); |
2697 | |
2698 // Load the arguments. | 2705 // Load the arguments. |
2699 for (int i = 0; i < args->length(); i++) { | 2706 for (int i = 0; i < args->length(); i++) { |
2700 Load(args->at(i)); | 2707 Load(args->at(i)); |
2701 } | 2708 } |
2702 | 2709 |
2703 // Setup the receiver register and call the IC initialization code. | 2710 // Setup the receiver register and call the IC initialization code. |
2704 Handle<Code> stub = ComputeCallInitialize(args->length()); | 2711 Handle<Code> stub = (loop_nesting() > 0) |
| 2712 ? ComputeCallInitializeInLoop(args->length()) |
| 2713 : ComputeCallInitialize(args->length()); |
2705 __ RecordPosition(node->position()); | 2714 __ RecordPosition(node->position()); |
2706 __ call(stub, RelocInfo::CODE_TARGET_CONTEXT); | 2715 __ call(stub, RelocInfo::CODE_TARGET_CONTEXT); |
2707 __ mov(esi, frame_->Context()); | 2716 __ mov(esi, frame_->Context()); |
2708 | 2717 |
2709 // Overwrite the function on the stack with the result. | 2718 // Overwrite the function on the stack with the result. |
2710 __ mov(frame_->Top(), eax); | 2719 __ mov(frame_->Top(), eax); |
2711 | 2720 |
2712 } else if (var != NULL && var->slot() != NULL && | 2721 } else if (var != NULL && var->slot() != NULL && |
2713 var->slot()->type() == Slot::LOOKUP) { | 2722 var->slot()->type() == Slot::LOOKUP) { |
2714 // ---------------------------------- | 2723 // ---------------------------------- |
(...skipping 23 matching lines...) Expand all Loading... |
2738 // ------------------------------------------------------------------ | 2747 // ------------------------------------------------------------------ |
2739 | 2748 |
2740 // Push the name of the function and the receiver onto the stack. | 2749 // Push the name of the function and the receiver onto the stack. |
2741 frame_->Push(Immediate(literal->handle())); | 2750 frame_->Push(Immediate(literal->handle())); |
2742 Load(property->obj()); | 2751 Load(property->obj()); |
2743 | 2752 |
2744 // Load the arguments. | 2753 // Load the arguments. |
2745 for (int i = 0; i < args->length(); i++) Load(args->at(i)); | 2754 for (int i = 0; i < args->length(); i++) Load(args->at(i)); |
2746 | 2755 |
2747 // Call the IC initialization code. | 2756 // Call the IC initialization code. |
2748 Handle<Code> stub = ComputeCallInitialize(args->length()); | 2757 Handle<Code> stub = (loop_nesting() > 0) |
| 2758 ? ComputeCallInitializeInLoop(args->length()) |
| 2759 : ComputeCallInitialize(args->length()); |
2749 __ RecordPosition(node->position()); | 2760 __ RecordPosition(node->position()); |
2750 __ call(stub, RelocInfo::CODE_TARGET); | 2761 __ call(stub, RelocInfo::CODE_TARGET); |
2751 __ mov(esi, frame_->Context()); | 2762 __ mov(esi, frame_->Context()); |
2752 | 2763 |
2753 // Overwrite the function on the stack with the result. | 2764 // Overwrite the function on the stack with the result. |
2754 __ mov(frame_->Top(), eax); | 2765 __ mov(frame_->Top(), eax); |
2755 | 2766 |
2756 } else { | 2767 } else { |
2757 // ------------------------------------------- | 2768 // ------------------------------------------- |
2758 // JavaScript example: 'array[index](1, 2, 3)' | 2769 // JavaScript example: 'array[index](1, 2, 3)' |
(...skipping 2383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5142 | 5153 |
5143 // Slow-case: Go through the JavaScript implementation. | 5154 // Slow-case: Go through the JavaScript implementation. |
5144 __ bind(&slow); | 5155 __ bind(&slow); |
5145 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5156 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
5146 } | 5157 } |
5147 | 5158 |
5148 | 5159 |
5149 #undef __ | 5160 #undef __ |
5150 | 5161 |
5151 } } // namespace v8::internal | 5162 } } // namespace v8::internal |
OLD | NEW |