OLD | NEW |
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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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(); |
65 for (int i = 0; i < locals_count; i++) { | 65 for (int i = 0; i < locals_count; i++) { |
66 __ push(Immediate(Factory::undefined_value())); | 66 __ push(Immediate(Factory::undefined_value())); |
67 } | 67 } |
68 } | 68 } |
69 | 69 |
| 70 bool function_in_register = true; |
| 71 |
| 72 Variable* arguments = fun->scope()->arguments()->AsVariable(); |
| 73 if (arguments != NULL) { |
| 74 // Function uses arguments object. |
| 75 Comment cmnt(masm_, "[ Allocate arguments object"); |
| 76 __ push(edi); |
| 77 // Receiver is located above the frame pointer, return address and |
| 78 // parameters. |
| 79 __ lea(edx, Operand(ebp, (fun->num_parameters() + 2) * kPointerSize)); |
| 80 __ push(edx); |
| 81 __ push(Immediate(Smi::FromInt(fun->num_parameters()))); |
| 82 // Arguments to ArgumentsAccessStub: |
| 83 // function, receiver address, parameter count. |
| 84 // The stub will rewrite receiever and parameter count if the previous |
| 85 // stack frame was an arguments adapter frame. |
| 86 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
| 87 __ CallStub(&stub); |
| 88 Slot* arguments_slot = arguments->slot(); |
| 89 __ mov(Operand(ebp, SlotOffset(arguments_slot)), eax); |
| 90 Slot* dot_arguments_slot = |
| 91 fun->scope()->arguments_shadow()->AsVariable()->slot(); |
| 92 __ mov(Operand(ebp, SlotOffset(dot_arguments_slot)), eax); |
| 93 |
| 94 function_in_register = false; |
| 95 } |
| 96 |
70 // Possibly allocate a local context. | 97 // Possibly allocate a local context. |
71 if (fun->scope()->num_heap_slots() > 0) { | 98 if (fun->scope()->num_heap_slots() > 0) { |
72 Comment cmnt(masm_, "[ Allocate local context"); | 99 Comment cmnt(masm_, "[ Allocate local context"); |
73 // Argument to NewContext is the function, still in edi. | 100 if (function_in_register) { |
74 __ push(edi); | 101 // Argument to NewContext is the function, still in edi. |
| 102 __ push(edi); |
| 103 } else { |
| 104 // Argument to NewContext is the function, no longer in edi. |
| 105 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 106 } |
75 __ CallRuntime(Runtime::kNewContext, 1); | 107 __ CallRuntime(Runtime::kNewContext, 1); |
76 // Context is returned in both eax and esi. It replaces the context | 108 // Context is returned in both eax and esi. It replaces the context |
77 // passed to us. It's saved in the stack and kept live in esi. | 109 // passed to us. It's saved in the stack and kept live in esi. |
78 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); | 110 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
79 #ifdef DEBUG | 111 #ifdef DEBUG |
80 // Assert we do not have to copy any parameters into the context. | 112 // Assert we do not have to copy any parameters into the context. |
81 for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) { | 113 for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) { |
82 Slot* slot = fun->scope()->parameter(i)->slot(); | 114 Slot* slot = fun->scope()->parameter(i)->slot(); |
83 ASSERT(slot != NULL && slot->type() != Slot::CONTEXT); | 115 ASSERT(slot != NULL && slot->type() != Slot::CONTEXT); |
84 } | 116 } |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 __ mov(ecx, expr->name()); | 450 __ mov(ecx, expr->name()); |
419 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 451 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
420 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 452 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
421 // By emitting a nop we make sure that we do not have a test eax | 453 // By emitting a nop we make sure that we do not have a test eax |
422 // instruction after the call it is treated specially by the LoadIC code | 454 // instruction after the call it is treated specially by the LoadIC code |
423 // Remember that the assembler may choose to do peephole optimization | 455 // Remember that the assembler may choose to do peephole optimization |
424 // (eg, push/pop elimination). | 456 // (eg, push/pop elimination). |
425 __ nop(); | 457 __ nop(); |
426 | 458 |
427 DropAndMove(expr->context(), eax); | 459 DropAndMove(expr->context(), eax); |
428 } else { | 460 } else if (rewrite->AsSlot() != NULL) { |
429 Slot* slot = rewrite->AsSlot(); | 461 Slot* slot = rewrite->AsSlot(); |
430 ASSERT_NE(NULL, slot); | |
431 switch (slot->type()) { | 462 switch (slot->type()) { |
432 case Slot::LOCAL: | 463 case Slot::LOCAL: |
433 case Slot::PARAMETER: { | 464 case Slot::PARAMETER: { |
434 Comment cmnt(masm_, "Stack slot"); | 465 Comment cmnt(masm_, "Stack slot"); |
435 Move(expr->context(), slot); | 466 Move(expr->context(), slot); |
436 break; | 467 break; |
437 } | 468 } |
438 | 469 |
439 case Slot::CONTEXT: { | 470 case Slot::CONTEXT: { |
440 Comment cmnt(masm_, "Context slot"); | 471 Comment cmnt(masm_, "Context slot"); |
(...skipping 20 matching lines...) Expand all Loading... |
461 } | 492 } |
462 __ mov(eax, Operand(eax, Context::SlotOffset(slot->index()))); | 493 __ mov(eax, Operand(eax, Context::SlotOffset(slot->index()))); |
463 Move(expr->context(), eax); | 494 Move(expr->context(), eax); |
464 break; | 495 break; |
465 } | 496 } |
466 | 497 |
467 case Slot::LOOKUP: | 498 case Slot::LOOKUP: |
468 UNREACHABLE(); | 499 UNREACHABLE(); |
469 break; | 500 break; |
470 } | 501 } |
| 502 } else { |
| 503 // The parameter variable has been rewritten into an explict access to |
| 504 // the arguments object. |
| 505 Property* property = rewrite->AsProperty(); |
| 506 ASSERT_NOT_NULL(property); |
| 507 ASSERT_EQ(expr->context(), property->context()); |
| 508 Visit(property); |
471 } | 509 } |
472 } | 510 } |
473 | 511 |
474 | 512 |
475 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 513 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
476 Comment cmnt(masm_, "[ RegExpLiteral"); | 514 Comment cmnt(masm_, "[ RegExpLiteral"); |
477 Label done; | 515 Label done; |
478 // Registers will be used as follows: | 516 // Registers will be used as follows: |
479 // edi = JS function. | 517 // edi = JS function. |
480 // ebx = literals array. | 518 // ebx = literals array. |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 true_label_ = saved_true; | 1540 true_label_ = saved_true; |
1503 false_label_ = saved_false; | 1541 false_label_ = saved_false; |
1504 // Convert current context to test context: End post-test code. | 1542 // Convert current context to test context: End post-test code. |
1505 } | 1543 } |
1506 | 1544 |
1507 | 1545 |
1508 #undef __ | 1546 #undef __ |
1509 | 1547 |
1510 | 1548 |
1511 } } // namespace v8::internal | 1549 } } // namespace v8::internal |
OLD | NEW |