OLD | NEW |
---|---|
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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 // Visit all the explicit declarations unless there is an illegal | 158 // Visit all the explicit declarations unless there is an illegal |
159 // redeclaration. | 159 // redeclaration. |
160 if (scope()->HasIllegalRedeclaration()) { | 160 if (scope()->HasIllegalRedeclaration()) { |
161 scope()->VisitIllegalRedeclaration(this); | 161 scope()->VisitIllegalRedeclaration(this); |
162 } else { | 162 } else { |
163 VisitDeclarations(scope()->declarations()); | 163 VisitDeclarations(scope()->declarations()); |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 { Comment cmnt(masm_, "[ Stack check"); | 167 { Comment cmnt(masm_, "[ Stack check"); |
168 Label ok; | 168 NearLabel ok; |
169 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 169 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
170 __ j(above_equal, &ok); | 170 __ j(above_equal, &ok); |
171 StackCheckStub stub; | 171 StackCheckStub stub; |
172 __ CallStub(&stub); | 172 __ CallStub(&stub); |
173 __ bind(&ok); | 173 __ bind(&ok); |
174 } | 174 } |
175 | 175 |
176 if (FLAG_trace) { | 176 if (FLAG_trace) { |
177 __ CallRuntime(Runtime::kTraceEnter, 0); | 177 __ CallRuntime(Runtime::kTraceEnter, 0); |
178 } | 178 } |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 Label* materialize_false) { | 389 Label* materialize_false) { |
390 switch (context) { | 390 switch (context) { |
391 case Expression::kUninitialized: | 391 case Expression::kUninitialized: |
392 | 392 |
393 case Expression::kEffect: | 393 case Expression::kEffect: |
394 ASSERT_EQ(materialize_true, materialize_false); | 394 ASSERT_EQ(materialize_true, materialize_false); |
395 __ bind(materialize_true); | 395 __ bind(materialize_true); |
396 break; | 396 break; |
397 | 397 |
398 case Expression::kValue: { | 398 case Expression::kValue: { |
399 Label done; | 399 NearLabel done; |
400 switch (location_) { | 400 switch (location_) { |
401 case kAccumulator: | 401 case kAccumulator: |
402 __ bind(materialize_true); | 402 __ bind(materialize_true); |
403 __ Move(result_register(), Factory::true_value()); | 403 __ Move(result_register(), Factory::true_value()); |
404 __ jmp(&done); | 404 __ jmp(&done); |
405 __ bind(materialize_false); | 405 __ bind(materialize_false); |
406 __ Move(result_register(), Factory::false_value()); | 406 __ Move(result_register(), Factory::false_value()); |
407 break; | 407 break; |
408 case kStack: | 408 case kStack: |
409 __ bind(materialize_true); | 409 __ bind(materialize_true); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
671 | 671 |
672 Comment cmnt(masm_, "[ Case comparison"); | 672 Comment cmnt(masm_, "[ Case comparison"); |
673 __ bind(&next_test); | 673 __ bind(&next_test); |
674 next_test.Unuse(); | 674 next_test.Unuse(); |
675 | 675 |
676 // Compile the label expression. | 676 // Compile the label expression. |
677 VisitForValue(clause->label(), kAccumulator); | 677 VisitForValue(clause->label(), kAccumulator); |
678 | 678 |
679 // Perform the comparison as if via '==='. | 679 // Perform the comparison as if via '==='. |
680 if (ShouldInlineSmiCase(Token::EQ_STRICT)) { | 680 if (ShouldInlineSmiCase(Token::EQ_STRICT)) { |
681 Label slow_case; | 681 Label slow_case; |
fschneider
2010/09/15 11:21:08
Indentation off. I think this can be a NearLabel t
Rico
2010/09/15 11:33:30
Actually no, JumpIfNotBothSmi takes a Label
| |
682 __ movq(rdx, Operand(rsp, 0)); // Switch value. | 682 __ movq(rdx, Operand(rsp, 0)); // Switch value. |
683 __ JumpIfNotBothSmi(rdx, rax, &slow_case); | 683 __ JumpIfNotBothSmi(rdx, rax, &slow_case); |
684 __ SmiCompare(rdx, rax); | 684 __ SmiCompare(rdx, rax); |
685 __ j(not_equal, &next_test); | 685 __ j(not_equal, &next_test); |
686 __ Drop(1); // Switch value is no longer needed. | 686 __ Drop(1); // Switch value is no longer needed. |
687 __ jmp(clause->body_target()->entry_label()); | 687 __ jmp(clause->body_target()->entry_label()); |
688 __ bind(&slow_case); | 688 __ bind(&slow_case); |
689 } | 689 } |
690 | 690 |
691 CompareStub stub(equal, true); | 691 CompareStub stub(equal, true); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 // cannot guarantee cache validity, call the runtime system to check | 751 // cannot guarantee cache validity, call the runtime system to check |
752 // cache validity or get the property names in a fixed array. | 752 // cache validity or get the property names in a fixed array. |
753 | 753 |
754 // Get the set of properties to enumerate. | 754 // Get the set of properties to enumerate. |
755 __ push(rax); // Duplicate the enumerable object on the stack. | 755 __ push(rax); // Duplicate the enumerable object on the stack. |
756 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); | 756 __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); |
757 | 757 |
758 // If we got a map from the runtime call, we can do a fast | 758 // If we got a map from the runtime call, we can do a fast |
759 // modification check. Otherwise, we got a fixed array, and we have | 759 // modification check. Otherwise, we got a fixed array, and we have |
760 // to do a slow check. | 760 // to do a slow check. |
761 Label fixed_array; | 761 NearLabel fixed_array; |
762 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 762 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), |
763 Heap::kMetaMapRootIndex); | 763 Heap::kMetaMapRootIndex); |
764 __ j(not_equal, &fixed_array); | 764 __ j(not_equal, &fixed_array); |
765 | 765 |
766 // We got a map in register rax. Get the enumeration cache from it. | 766 // We got a map in register rax. Get the enumeration cache from it. |
767 __ movq(rcx, FieldOperand(rax, Map::kInstanceDescriptorsOffset)); | 767 __ movq(rcx, FieldOperand(rax, Map::kInstanceDescriptorsOffset)); |
768 __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset)); | 768 __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset)); |
769 __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset)); | 769 __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset)); |
770 | 770 |
771 // Setup the four remaining stack slots. | 771 // Setup the four remaining stack slots. |
(...skipping 25 matching lines...) Expand all Loading... | |
797 index.reg, | 797 index.reg, |
798 index.scale, | 798 index.scale, |
799 FixedArray::kHeaderSize)); | 799 FixedArray::kHeaderSize)); |
800 | 800 |
801 // Get the expected map from the stack or a zero map in the | 801 // Get the expected map from the stack or a zero map in the |
802 // permanent slow case into register rdx. | 802 // permanent slow case into register rdx. |
803 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); | 803 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); |
804 | 804 |
805 // Check if the expected map still matches that of the enumerable. | 805 // Check if the expected map still matches that of the enumerable. |
806 // If not, we have to filter the key. | 806 // If not, we have to filter the key. |
807 Label update_each; | 807 NearLabel update_each; |
808 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); | 808 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); |
809 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); | 809 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); |
810 __ j(equal, &update_each); | 810 __ j(equal, &update_each); |
811 | 811 |
812 // Convert the entry to a string or null if it isn't a property | 812 // Convert the entry to a string or null if it isn't a property |
813 // anymore. If the property has been removed while iterating, we | 813 // anymore. If the property has been removed while iterating, we |
814 // just skip it. | 814 // just skip it. |
815 __ push(rcx); // Enumerable. | 815 __ push(rcx); // Enumerable. |
816 __ push(rbx); // Current entry. | 816 __ push(rbx); // Current entry. |
817 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); | 817 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
902 // If no outer scope calls eval, we do not need to check more | 902 // If no outer scope calls eval, we do not need to check more |
903 // context extensions. If we have reached an eval scope, we check | 903 // context extensions. If we have reached an eval scope, we check |
904 // all extensions from this point. | 904 // all extensions from this point. |
905 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; | 905 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; |
906 s = s->outer_scope(); | 906 s = s->outer_scope(); |
907 } | 907 } |
908 | 908 |
909 if (s != NULL && s->is_eval_scope()) { | 909 if (s != NULL && s->is_eval_scope()) { |
910 // Loop up the context chain. There is no frame effect so it is | 910 // Loop up the context chain. There is no frame effect so it is |
911 // safe to use raw labels here. | 911 // safe to use raw labels here. |
912 Label next, fast; | 912 NearLabel next, fast; |
913 if (!context.is(temp)) { | 913 if (!context.is(temp)) { |
914 __ movq(temp, context); | 914 __ movq(temp, context); |
915 } | 915 } |
916 // Load map for comparison into register, outside loop. | 916 // Load map for comparison into register, outside loop. |
917 __ LoadRoot(kScratchRegister, Heap::kGlobalContextMapRootIndex); | 917 __ LoadRoot(kScratchRegister, Heap::kGlobalContextMapRootIndex); |
918 __ bind(&next); | 918 __ bind(&next); |
919 // Terminate at global context. | 919 // Terminate at global context. |
920 __ cmpq(kScratchRegister, FieldOperand(temp, HeapObject::kMapOffset)); | 920 __ cmpq(kScratchRegister, FieldOperand(temp, HeapObject::kMapOffset)); |
921 __ j(equal, &fast); | 921 __ j(equal, &fast); |
922 // Check that extension is NULL. | 922 // Check that extension is NULL. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1061 | 1061 |
1062 Apply(context, rax); | 1062 Apply(context, rax); |
1063 | 1063 |
1064 } else if (slot != NULL) { | 1064 } else if (slot != NULL) { |
1065 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) | 1065 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
1066 ? "Context slot" | 1066 ? "Context slot" |
1067 : "Stack slot"); | 1067 : "Stack slot"); |
1068 if (var->mode() == Variable::CONST) { | 1068 if (var->mode() == Variable::CONST) { |
1069 // Constants may be the hole value if they have not been initialized. | 1069 // Constants may be the hole value if they have not been initialized. |
1070 // Unhole them. | 1070 // Unhole them. |
1071 Label done; | 1071 NearLabel done; |
1072 MemOperand slot_operand = EmitSlotSearch(slot, rax); | 1072 MemOperand slot_operand = EmitSlotSearch(slot, rax); |
1073 __ movq(rax, slot_operand); | 1073 __ movq(rax, slot_operand); |
1074 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 1074 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
1075 __ j(not_equal, &done); | 1075 __ j(not_equal, &done); |
1076 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); | 1076 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
1077 __ bind(&done); | 1077 __ bind(&done); |
1078 Apply(context, rax); | 1078 Apply(context, rax); |
1079 } else { | 1079 } else { |
1080 Apply(context, slot); | 1080 Apply(context, slot); |
1081 } | 1081 } |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1880 __ push(context_register()); | 1880 __ push(context_register()); |
1881 __ Push(var->name()); | 1881 __ Push(var->name()); |
1882 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1882 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
1883 __ push(rax); // Function. | 1883 __ push(rax); // Function. |
1884 __ push(rdx); // Receiver. | 1884 __ push(rdx); // Receiver. |
1885 | 1885 |
1886 // If fast case code has been generated, emit code to push the | 1886 // If fast case code has been generated, emit code to push the |
1887 // function and receiver and have the slow path jump around this | 1887 // function and receiver and have the slow path jump around this |
1888 // code. | 1888 // code. |
1889 if (done.is_linked()) { | 1889 if (done.is_linked()) { |
1890 Label call; | 1890 NearLabel call; |
1891 __ jmp(&call); | 1891 __ jmp(&call); |
1892 __ bind(&done); | 1892 __ bind(&done); |
1893 // Push function. | 1893 // Push function. |
1894 __ push(rax); | 1894 __ push(rax); |
1895 // Push global receiver. | 1895 // Push global receiver. |
1896 __ movq(rbx, CodeGenerator::GlobalObject()); | 1896 __ movq(rbx, CodeGenerator::GlobalObject()); |
1897 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 1897 __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
1898 __ bind(&call); | 1898 __ bind(&call); |
1899 } | 1899 } |
1900 | 1900 |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2242 __ Move(rax, Smi::FromInt(scope()->num_parameters())); | 2242 __ Move(rax, Smi::FromInt(scope()->num_parameters())); |
2243 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 2243 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
2244 __ CallStub(&stub); | 2244 __ CallStub(&stub); |
2245 Apply(context_, rax); | 2245 Apply(context_, rax); |
2246 } | 2246 } |
2247 | 2247 |
2248 | 2248 |
2249 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { | 2249 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { |
2250 ASSERT(args->length() == 0); | 2250 ASSERT(args->length() == 0); |
2251 | 2251 |
2252 Label exit; | 2252 NearLabel exit; |
2253 // Get the number of formal parameters. | 2253 // Get the number of formal parameters. |
2254 __ Move(rax, Smi::FromInt(scope()->num_parameters())); | 2254 __ Move(rax, Smi::FromInt(scope()->num_parameters())); |
2255 | 2255 |
2256 // Check if the calling frame is an arguments adaptor frame. | 2256 // Check if the calling frame is an arguments adaptor frame. |
2257 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2257 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
2258 __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset), | 2258 __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset), |
2259 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2259 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
2260 __ j(not_equal, &exit); | 2260 __ j(not_equal, &exit); |
2261 | 2261 |
2262 // Arguments adaptor case: Read the arguments length from the | 2262 // Arguments adaptor case: Read the arguments length from the |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2701 Register cache = rbx; | 2701 Register cache = rbx; |
2702 Register tmp = rcx; | 2702 Register tmp = rcx; |
2703 __ movq(cache, ContextOperand(rsi, Context::GLOBAL_INDEX)); | 2703 __ movq(cache, ContextOperand(rsi, Context::GLOBAL_INDEX)); |
2704 __ movq(cache, | 2704 __ movq(cache, |
2705 FieldOperand(cache, GlobalObject::kGlobalContextOffset)); | 2705 FieldOperand(cache, GlobalObject::kGlobalContextOffset)); |
2706 __ movq(cache, | 2706 __ movq(cache, |
2707 ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); | 2707 ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); |
2708 __ movq(cache, | 2708 __ movq(cache, |
2709 FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); | 2709 FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); |
2710 | 2710 |
2711 Label done, not_found; | 2711 NearLabel done, not_found; |
2712 // tmp now holds finger offset as a smi. | 2712 // tmp now holds finger offset as a smi. |
2713 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 2713 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
2714 __ movq(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset)); | 2714 __ movq(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset)); |
2715 SmiIndex index = | 2715 SmiIndex index = |
2716 __ SmiToIndex(kScratchRegister, tmp, kPointerSizeLog2); | 2716 __ SmiToIndex(kScratchRegister, tmp, kPointerSizeLog2); |
2717 __ cmpq(key, FieldOperand(cache, | 2717 __ cmpq(key, FieldOperand(cache, |
2718 index.reg, | 2718 index.reg, |
2719 index.scale, | 2719 index.scale, |
2720 FixedArray::kHeaderSize)); | 2720 FixedArray::kHeaderSize)); |
2721 __ j(not_equal, ¬_found); | 2721 __ j(not_equal, ¬_found); |
(...skipping 18 matching lines...) Expand all Loading... | |
2740 ASSERT_EQ(2, args->length()); | 2740 ASSERT_EQ(2, args->length()); |
2741 | 2741 |
2742 Register right = rax; | 2742 Register right = rax; |
2743 Register left = rbx; | 2743 Register left = rbx; |
2744 Register tmp = rcx; | 2744 Register tmp = rcx; |
2745 | 2745 |
2746 VisitForValue(args->at(0), kStack); | 2746 VisitForValue(args->at(0), kStack); |
2747 VisitForValue(args->at(1), kAccumulator); | 2747 VisitForValue(args->at(1), kAccumulator); |
2748 __ pop(left); | 2748 __ pop(left); |
2749 | 2749 |
2750 Label done, fail, ok; | 2750 NearLabel done, fail, ok; |
2751 __ cmpq(left, right); | 2751 __ cmpq(left, right); |
2752 __ j(equal, &ok); | 2752 __ j(equal, &ok); |
2753 // Fail if either is a non-HeapObject. | 2753 // Fail if either is a non-HeapObject. |
2754 Condition either_smi = masm()->CheckEitherSmi(left, right, tmp); | 2754 Condition either_smi = masm()->CheckEitherSmi(left, right, tmp); |
2755 __ j(either_smi, &fail); | 2755 __ j(either_smi, &fail); |
2756 __ j(zero, &fail); | 2756 __ j(zero, &fail); |
2757 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); | 2757 __ movq(tmp, FieldOperand(left, HeapObject::kMapOffset)); |
2758 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), | 2758 __ cmpb(FieldOperand(tmp, Map::kInstanceTypeOffset), |
2759 Immediate(JS_REGEXP_TYPE)); | 2759 Immediate(JS_REGEXP_TYPE)); |
2760 __ j(not_equal, &fail); | 2760 __ j(not_equal, &fail); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2932 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 2932 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
2933 VisitForTypeofValue(expr->expression(), kStack); | 2933 VisitForTypeofValue(expr->expression(), kStack); |
2934 __ CallRuntime(Runtime::kTypeof, 1); | 2934 __ CallRuntime(Runtime::kTypeof, 1); |
2935 Apply(context_, rax); | 2935 Apply(context_, rax); |
2936 break; | 2936 break; |
2937 } | 2937 } |
2938 | 2938 |
2939 case Token::ADD: { | 2939 case Token::ADD: { |
2940 Comment cmt(masm_, "[ UnaryOperation (ADD)"); | 2940 Comment cmt(masm_, "[ UnaryOperation (ADD)"); |
2941 VisitForValue(expr->expression(), kAccumulator); | 2941 VisitForValue(expr->expression(), kAccumulator); |
2942 Label no_conversion; | 2942 NearLabel no_conversion; |
2943 Condition is_smi = masm_->CheckSmi(result_register()); | 2943 Condition is_smi = masm_->CheckSmi(result_register()); |
2944 __ j(is_smi, &no_conversion); | 2944 __ j(is_smi, &no_conversion); |
2945 __ push(result_register()); | 2945 __ push(result_register()); |
2946 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 2946 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
2947 __ bind(&no_conversion); | 2947 __ bind(&no_conversion); |
2948 Apply(context_, result_register()); | 2948 Apply(context_, result_register()); |
2949 break; | 2949 break; |
2950 } | 2950 } |
2951 | 2951 |
2952 case Token::SUB: { | 2952 case Token::SUB: { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3035 } else { | 3035 } else { |
3036 VisitForValue(prop->obj(), kStack); | 3036 VisitForValue(prop->obj(), kStack); |
3037 VisitForValue(prop->key(), kAccumulator); | 3037 VisitForValue(prop->key(), kAccumulator); |
3038 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack | 3038 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack |
3039 __ push(rax); // Copy of key, needed for later store. | 3039 __ push(rax); // Copy of key, needed for later store. |
3040 EmitKeyedPropertyLoad(prop); | 3040 EmitKeyedPropertyLoad(prop); |
3041 } | 3041 } |
3042 } | 3042 } |
3043 | 3043 |
3044 // Call ToNumber only if operand is not a smi. | 3044 // Call ToNumber only if operand is not a smi. |
3045 Label no_conversion; | 3045 NearLabel no_conversion; |
3046 Condition is_smi; | 3046 Condition is_smi; |
3047 is_smi = masm_->CheckSmi(rax); | 3047 is_smi = masm_->CheckSmi(rax); |
3048 __ j(is_smi, &no_conversion); | 3048 __ j(is_smi, &no_conversion); |
3049 __ push(rax); | 3049 __ push(rax); |
3050 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); | 3050 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
3051 __ bind(&no_conversion); | 3051 __ bind(&no_conversion); |
3052 | 3052 |
3053 // Save result for postfix expressions. | 3053 // Save result for postfix expressions. |
3054 if (expr->is_postfix()) { | 3054 if (expr->is_postfix()) { |
3055 switch (context_) { | 3055 switch (context_) { |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3467 __ ret(0); | 3467 __ ret(0); |
3468 } | 3468 } |
3469 | 3469 |
3470 | 3470 |
3471 #undef __ | 3471 #undef __ |
3472 | 3472 |
3473 | 3473 |
3474 } } // namespace v8::internal | 3474 } } // namespace v8::internal |
3475 | 3475 |
3476 #endif // V8_TARGET_ARCH_X64 | 3476 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |