OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 #ifdef DEBUG | 107 #ifdef DEBUG |
108 if (strlen(FLAG_stop_at) > 0 && | 108 if (strlen(FLAG_stop_at) > 0 && |
109 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 109 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
110 __ int3(); | 110 __ int3(); |
111 } | 111 } |
112 #endif | 112 #endif |
113 | 113 |
114 // Sloppy mode functions and builtins need to replace the receiver with the | 114 // Sloppy mode functions and builtins need to replace the receiver with the |
115 // global proxy when called as functions (without an explicit receiver | 115 // global proxy when called as functions (without an explicit receiver |
116 // object). | 116 // object). |
117 if (info->strict_mode() == SLOPPY && !info->is_native()) { | 117 if (is_sloppy(info->language_mode()) && !info->is_native()) { |
118 Label ok; | 118 Label ok; |
119 // +1 for return address. | 119 // +1 for return address. |
120 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; | 120 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; |
121 __ mov(ecx, Operand(esp, receiver_offset)); | 121 __ mov(ecx, Operand(esp, receiver_offset)); |
122 | 122 |
123 __ cmp(ecx, isolate()->factory()->undefined_value()); | 123 __ cmp(ecx, isolate()->factory()->undefined_value()); |
124 __ j(not_equal, &ok, Label::kNear); | 124 __ j(not_equal, &ok, Label::kNear); |
125 | 125 |
126 __ mov(ecx, GlobalObjectOperand()); | 126 __ mov(ecx, GlobalObjectOperand()); |
127 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset)); | 127 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset)); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 int offset = num_parameters * kPointerSize; | 250 int offset = num_parameters * kPointerSize; |
251 __ lea(edx, | 251 __ lea(edx, |
252 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); | 252 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); |
253 __ push(edx); | 253 __ push(edx); |
254 __ push(Immediate(Smi::FromInt(num_parameters))); | 254 __ push(Immediate(Smi::FromInt(num_parameters))); |
255 // Arguments to ArgumentsAccessStub: | 255 // Arguments to ArgumentsAccessStub: |
256 // function, receiver address, parameter count. | 256 // function, receiver address, parameter count. |
257 // The stub will rewrite receiver and parameter count if the previous | 257 // The stub will rewrite receiver and parameter count if the previous |
258 // stack frame was an arguments adapter frame. | 258 // stack frame was an arguments adapter frame. |
259 ArgumentsAccessStub::Type type; | 259 ArgumentsAccessStub::Type type; |
260 if (strict_mode() == STRICT) { | 260 if (is_strict(language_mode())) { |
261 type = ArgumentsAccessStub::NEW_STRICT; | 261 type = ArgumentsAccessStub::NEW_STRICT; |
262 } else if (function()->has_duplicate_parameters()) { | 262 } else if (function()->has_duplicate_parameters()) { |
263 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 263 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
264 } else { | 264 } else { |
265 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 265 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
266 } | 266 } |
267 ArgumentsAccessStub stub(isolate(), type); | 267 ArgumentsAccessStub stub(isolate(), type); |
268 __ CallStub(&stub); | 268 __ CallStub(&stub); |
269 | 269 |
270 SetVar(arguments, eax, ebx, edx); | 270 SetVar(arguments, eax, ebx, edx); |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 // space for nested functions that don't need literals cloning. If | 1215 // space for nested functions that don't need literals cloning. If |
1216 // we're running with the --always-opt or the --prepare-always-opt | 1216 // we're running with the --always-opt or the --prepare-always-opt |
1217 // flag, we need to use the runtime function so that the new function | 1217 // flag, we need to use the runtime function so that the new function |
1218 // we are creating here gets a chance to have its code optimized and | 1218 // we are creating here gets a chance to have its code optimized and |
1219 // doesn't just get a copy of the existing unoptimized code. | 1219 // doesn't just get a copy of the existing unoptimized code. |
1220 if (!FLAG_always_opt && | 1220 if (!FLAG_always_opt && |
1221 !FLAG_prepare_always_opt && | 1221 !FLAG_prepare_always_opt && |
1222 !pretenure && | 1222 !pretenure && |
1223 scope()->is_function_scope() && | 1223 scope()->is_function_scope() && |
1224 info->num_literals() == 0) { | 1224 info->num_literals() == 0) { |
1225 FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind()); | 1225 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); |
1226 __ mov(ebx, Immediate(info)); | 1226 __ mov(ebx, Immediate(info)); |
1227 __ CallStub(&stub); | 1227 __ CallStub(&stub); |
1228 } else { | 1228 } else { |
1229 __ push(esi); | 1229 __ push(esi); |
1230 __ push(Immediate(info)); | 1230 __ push(Immediate(info)); |
1231 __ push(Immediate(pretenure | 1231 __ push(Immediate(pretenure |
1232 ? isolate()->factory()->true_value() | 1232 ? isolate()->factory()->true_value() |
1233 : isolate()->factory()->false_value())); | 1233 : isolate()->factory()->false_value())); |
1234 __ CallRuntime(Runtime::kNewClosure, 3); | 1234 __ CallRuntime(Runtime::kNewClosure, 3); |
1235 } | 1235 } |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 } else { | 1662 } else { |
1663 VisitForEffect(value); | 1663 VisitForEffect(value); |
1664 } | 1664 } |
1665 break; | 1665 break; |
1666 } | 1666 } |
1667 __ push(Operand(esp, 0)); // Duplicate receiver. | 1667 __ push(Operand(esp, 0)); // Duplicate receiver. |
1668 VisitForStackValue(key); | 1668 VisitForStackValue(key); |
1669 VisitForStackValue(value); | 1669 VisitForStackValue(value); |
1670 if (property->emit_store()) { | 1670 if (property->emit_store()) { |
1671 EmitSetHomeObjectIfNeeded(value, 2); | 1671 EmitSetHomeObjectIfNeeded(value, 2); |
1672 __ push(Immediate(Smi::FromInt(SLOPPY))); // Strict mode | 1672 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
1673 __ CallRuntime(Runtime::kSetProperty, 4); | 1673 __ CallRuntime(Runtime::kSetProperty, 4); |
1674 } else { | 1674 } else { |
1675 __ Drop(3); | 1675 __ Drop(3); |
1676 } | 1676 } |
1677 break; | 1677 break; |
1678 case ObjectLiteral::Property::PROTOTYPE: | 1678 case ObjectLiteral::Property::PROTOTYPE: |
1679 __ push(Operand(esp, 0)); // Duplicate receiver. | 1679 __ push(Operand(esp, 0)); // Duplicate receiver. |
1680 VisitForStackValue(value); | 1680 VisitForStackValue(value); |
1681 DCHECK(property->emit_store()); | 1681 DCHECK(property->emit_store()); |
1682 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1682 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2565 break; | 2565 break; |
2566 } | 2566 } |
2567 case KEYED_PROPERTY: { | 2567 case KEYED_PROPERTY: { |
2568 __ push(eax); // Preserve value. | 2568 __ push(eax); // Preserve value. |
2569 VisitForStackValue(prop->obj()); | 2569 VisitForStackValue(prop->obj()); |
2570 VisitForAccumulatorValue(prop->key()); | 2570 VisitForAccumulatorValue(prop->key()); |
2571 __ Move(StoreDescriptor::NameRegister(), eax); | 2571 __ Move(StoreDescriptor::NameRegister(), eax); |
2572 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2572 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
2573 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2573 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2574 Handle<Code> ic = | 2574 Handle<Code> ic = |
2575 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2575 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2576 CallIC(ic); | 2576 CallIC(ic); |
2577 break; | 2577 break; |
2578 } | 2578 } |
2579 } | 2579 } |
2580 context()->Plug(eax); | 2580 context()->Plug(eax); |
2581 } | 2581 } |
2582 | 2582 |
2583 | 2583 |
2584 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2584 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2585 Variable* var, MemOperand location) { | 2585 Variable* var, MemOperand location) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 __ push(Immediate(var->name())); | 2631 __ push(Immediate(var->name())); |
2632 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2632 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2633 __ bind(&assign); | 2633 __ bind(&assign); |
2634 EmitStoreToStackLocalOrContextSlot(var, location); | 2634 EmitStoreToStackLocalOrContextSlot(var, location); |
2635 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2635 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2636 if (var->IsLookupSlot()) { | 2636 if (var->IsLookupSlot()) { |
2637 // Assignment to var. | 2637 // Assignment to var. |
2638 __ push(eax); // Value. | 2638 __ push(eax); // Value. |
2639 __ push(esi); // Context. | 2639 __ push(esi); // Context. |
2640 __ push(Immediate(var->name())); | 2640 __ push(Immediate(var->name())); |
2641 __ push(Immediate(Smi::FromInt(strict_mode()))); | 2641 __ push(Immediate(Smi::FromInt(language_mode()))); |
2642 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2642 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2643 } else { | 2643 } else { |
2644 // Assignment to var or initializing assignment to let/const in harmony | 2644 // Assignment to var or initializing assignment to let/const in harmony |
2645 // mode. | 2645 // mode. |
2646 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2646 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2647 MemOperand location = VarOperand(var, ecx); | 2647 MemOperand location = VarOperand(var, ecx); |
2648 if (generate_debug_code_ && op == Token::INIT_LET) { | 2648 if (generate_debug_code_ && op == Token::INIT_LET) { |
2649 // Check for an uninitialized let binding. | 2649 // Check for an uninitialized let binding. |
2650 __ mov(edx, location); | 2650 __ mov(edx, location); |
2651 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2651 __ cmp(edx, isolate()->factory()->the_hole_value()); |
2652 __ Check(equal, kLetBindingReInitialization); | 2652 __ Check(equal, kLetBindingReInitialization); |
2653 } | 2653 } |
2654 EmitStoreToStackLocalOrContextSlot(var, location); | 2654 EmitStoreToStackLocalOrContextSlot(var, location); |
2655 } | 2655 } |
2656 } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) { | 2656 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) { |
2657 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2657 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
2658 } | 2658 } |
2659 } | 2659 } |
2660 | 2660 |
2661 | 2661 |
2662 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2662 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2663 // Assignment to a property, using a named store IC. | 2663 // Assignment to a property, using a named store IC. |
2664 // eax : value | 2664 // eax : value |
2665 // esp[0] : receiver | 2665 // esp[0] : receiver |
2666 | 2666 |
(...skipping 14 matching lines...) Expand all Loading... |
2681 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2681 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2682 // Assignment to named property of super. | 2682 // Assignment to named property of super. |
2683 // eax : value | 2683 // eax : value |
2684 // stack : receiver ('this'), home_object | 2684 // stack : receiver ('this'), home_object |
2685 DCHECK(prop != NULL); | 2685 DCHECK(prop != NULL); |
2686 Literal* key = prop->key()->AsLiteral(); | 2686 Literal* key = prop->key()->AsLiteral(); |
2687 DCHECK(key != NULL); | 2687 DCHECK(key != NULL); |
2688 | 2688 |
2689 __ push(Immediate(key->value())); | 2689 __ push(Immediate(key->value())); |
2690 __ push(eax); | 2690 __ push(eax); |
2691 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2691 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict |
2692 : Runtime::kStoreToSuper_Sloppy), | 2692 : Runtime::kStoreToSuper_Sloppy), |
2693 4); | 2693 4); |
2694 } | 2694 } |
2695 | 2695 |
2696 | 2696 |
2697 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2697 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
2698 // Assignment to named property of super. | 2698 // Assignment to named property of super. |
2699 // eax : value | 2699 // eax : value |
2700 // stack : receiver ('this'), home_object, key | 2700 // stack : receiver ('this'), home_object, key |
2701 | 2701 |
2702 __ push(eax); | 2702 __ push(eax); |
2703 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict | 2703 __ CallRuntime( |
2704 : Runtime::kStoreKeyedToSuper_Sloppy), | 2704 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
2705 4); | 2705 : Runtime::kStoreKeyedToSuper_Sloppy), |
| 2706 4); |
2706 } | 2707 } |
2707 | 2708 |
2708 | 2709 |
2709 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2710 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2710 // Assignment to a property, using a keyed store IC. | 2711 // Assignment to a property, using a keyed store IC. |
2711 // eax : value | 2712 // eax : value |
2712 // esp[0] : key | 2713 // esp[0] : key |
2713 // esp[kPointerSize] : receiver | 2714 // esp[kPointerSize] : receiver |
2714 | 2715 |
2715 __ pop(StoreDescriptor::NameRegister()); // Key. | 2716 __ pop(StoreDescriptor::NameRegister()); // Key. |
2716 __ pop(StoreDescriptor::ReceiverRegister()); | 2717 __ pop(StoreDescriptor::ReceiverRegister()); |
2717 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2718 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2718 // Record source code position before IC call. | 2719 // Record source code position before IC call. |
2719 SetSourcePosition(expr->position()); | 2720 SetSourcePosition(expr->position()); |
2720 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2721 Handle<Code> ic = |
| 2722 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2721 CallIC(ic, expr->AssignmentFeedbackId()); | 2723 CallIC(ic, expr->AssignmentFeedbackId()); |
2722 | 2724 |
2723 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2725 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2724 context()->Plug(eax); | 2726 context()->Plug(eax); |
2725 } | 2727 } |
2726 | 2728 |
2727 | 2729 |
2728 void FullCodeGenerator::VisitProperty(Property* expr) { | 2730 void FullCodeGenerator::VisitProperty(Property* expr) { |
2729 Comment cmnt(masm_, "[ Property"); | 2731 Comment cmnt(masm_, "[ Property"); |
2730 Expression* key = expr->key(); | 2732 Expression* key = expr->key(); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2925 __ push(Operand(esp, arg_count * kPointerSize)); | 2927 __ push(Operand(esp, arg_count * kPointerSize)); |
2926 } else { | 2928 } else { |
2927 __ push(Immediate(isolate()->factory()->undefined_value())); | 2929 __ push(Immediate(isolate()->factory()->undefined_value())); |
2928 } | 2930 } |
2929 | 2931 |
2930 // Push the enclosing function. | 2932 // Push the enclosing function. |
2931 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2933 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
2932 // Push the receiver of the enclosing function. | 2934 // Push the receiver of the enclosing function. |
2933 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); | 2935 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); |
2934 // Push the language mode. | 2936 // Push the language mode. |
2935 __ push(Immediate(Smi::FromInt(strict_mode()))); | 2937 __ push(Immediate(Smi::FromInt(language_mode()))); |
2936 | 2938 |
2937 // Push the start position of the scope the calls resides in. | 2939 // Push the start position of the scope the calls resides in. |
2938 __ push(Immediate(Smi::FromInt(scope()->start_position()))); | 2940 __ push(Immediate(Smi::FromInt(scope()->start_position()))); |
2939 | 2941 |
2940 // Do the runtime call. | 2942 // Do the runtime call. |
2941 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2943 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2942 } | 2944 } |
2943 | 2945 |
2944 | 2946 |
2945 void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) { | 2947 void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) { |
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4497 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4499 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
4498 switch (expr->op()) { | 4500 switch (expr->op()) { |
4499 case Token::DELETE: { | 4501 case Token::DELETE: { |
4500 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4502 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
4501 Property* property = expr->expression()->AsProperty(); | 4503 Property* property = expr->expression()->AsProperty(); |
4502 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4504 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4503 | 4505 |
4504 if (property != NULL) { | 4506 if (property != NULL) { |
4505 VisitForStackValue(property->obj()); | 4507 VisitForStackValue(property->obj()); |
4506 VisitForStackValue(property->key()); | 4508 VisitForStackValue(property->key()); |
4507 __ push(Immediate(Smi::FromInt(strict_mode()))); | 4509 __ push(Immediate(Smi::FromInt(language_mode()))); |
4508 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4510 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4509 context()->Plug(eax); | 4511 context()->Plug(eax); |
4510 } else if (proxy != NULL) { | 4512 } else if (proxy != NULL) { |
4511 Variable* var = proxy->var(); | 4513 Variable* var = proxy->var(); |
4512 // Delete of an unqualified identifier is disallowed in strict mode | 4514 // Delete of an unqualified identifier is disallowed in strict mode |
4513 // but "delete this" is allowed. | 4515 // but "delete this" is allowed. |
4514 DCHECK(strict_mode() == SLOPPY || var->is_this()); | 4516 DCHECK(is_sloppy(language_mode()) || var->is_this()); |
4515 if (var->IsUnallocated()) { | 4517 if (var->IsUnallocated()) { |
4516 __ push(GlobalObjectOperand()); | 4518 __ push(GlobalObjectOperand()); |
4517 __ push(Immediate(var->name())); | 4519 __ push(Immediate(var->name())); |
4518 __ push(Immediate(Smi::FromInt(SLOPPY))); | 4520 __ push(Immediate(Smi::FromInt(SLOPPY))); |
4519 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4521 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4520 context()->Plug(eax); | 4522 context()->Plug(eax); |
4521 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4523 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4522 // Result of deleting non-global variables is false. 'this' is | 4524 // Result of deleting non-global variables is false. 'this' is |
4523 // not really a variable, though we implement it as one. The | 4525 // not really a variable, though we implement it as one. The |
4524 // subexpression does not have side effects. | 4526 // subexpression does not have side effects. |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4831 } | 4833 } |
4832 } else { | 4834 } else { |
4833 context()->Plug(eax); | 4835 context()->Plug(eax); |
4834 } | 4836 } |
4835 break; | 4837 break; |
4836 } | 4838 } |
4837 case KEYED_PROPERTY: { | 4839 case KEYED_PROPERTY: { |
4838 __ pop(StoreDescriptor::NameRegister()); | 4840 __ pop(StoreDescriptor::NameRegister()); |
4839 __ pop(StoreDescriptor::ReceiverRegister()); | 4841 __ pop(StoreDescriptor::ReceiverRegister()); |
4840 Handle<Code> ic = | 4842 Handle<Code> ic = |
4841 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4843 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
4842 CallIC(ic, expr->CountStoreFeedbackId()); | 4844 CallIC(ic, expr->CountStoreFeedbackId()); |
4843 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4845 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4844 if (expr->is_postfix()) { | 4846 if (expr->is_postfix()) { |
4845 // Result is on the stack | 4847 // Result is on the stack |
4846 if (!context()->IsEffect()) { | 4848 if (!context()->IsEffect()) { |
4847 context()->PlugTOS(); | 4849 context()->PlugTOS(); |
4848 } | 4850 } |
4849 } else { | 4851 } else { |
4850 context()->Plug(eax); | 4852 context()->Plug(eax); |
4851 } | 4853 } |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5288 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5290 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
5289 Assembler::target_address_at(call_target_address, | 5291 Assembler::target_address_at(call_target_address, |
5290 unoptimized_code)); | 5292 unoptimized_code)); |
5291 return OSR_AFTER_STACK_CHECK; | 5293 return OSR_AFTER_STACK_CHECK; |
5292 } | 5294 } |
5293 | 5295 |
5294 | 5296 |
5295 } } // namespace v8::internal | 5297 } } // namespace v8::internal |
5296 | 5298 |
5297 #endif // V8_TARGET_ARCH_IA32 | 5299 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |