OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 7 #if V8_TARGET_ARCH_PPC |
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 3076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 CallIC(ic); | 3087 CallIC(ic); |
3088 | 3088 |
3089 RecordJSReturnSite(expr); | 3089 RecordJSReturnSite(expr); |
3090 // Restore context register. | 3090 // Restore context register. |
3091 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3091 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3092 context()->DropAndPlug(1, r3); | 3092 context()->DropAndPlug(1, r3); |
3093 } | 3093 } |
3094 | 3094 |
3095 | 3095 |
3096 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 3096 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
3097 // r7: copy of the first argument or undefined if it doesn't exist. | 3097 // r8: copy of the first argument or undefined if it doesn't exist. |
3098 if (arg_count > 0) { | 3098 if (arg_count > 0) { |
3099 __ LoadP(r7, MemOperand(sp, arg_count * kPointerSize), r0); | 3099 __ LoadP(r8, MemOperand(sp, arg_count * kPointerSize), r0); |
3100 } else { | 3100 } else { |
3101 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); | 3101 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); |
3102 } | 3102 } |
3103 | 3103 |
| 3104 // r7: the receiver of the enclosing function. |
| 3105 __ LoadP(r7, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3106 |
3104 // r6: the receiver of the enclosing function. | 3107 // r6: the receiver of the enclosing function. |
3105 __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3108 Variable* this_var = scope()->LookupThis(); |
| 3109 DCHECK_NOT_NULL(this_var); |
| 3110 GetVar(r6, this_var); |
3106 | 3111 |
3107 // r5: language mode. | 3112 // r5: language mode. |
3108 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode())); | 3113 __ LoadSmiLiteral(r5, Smi::FromInt(language_mode())); |
3109 | 3114 |
3110 // r4: the start position of the scope the calls resides in. | 3115 // r4: the start position of the scope the calls resides in. |
3111 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); | 3116 __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position())); |
3112 | 3117 |
3113 // Do the runtime call. | 3118 // Do the runtime call. |
3114 __ Push(r7, r6, r5, r4); | 3119 __ Push(r8, r7, r6, r5, r4); |
3115 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3120 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
3116 } | 3121 } |
3117 | 3122 |
3118 | 3123 |
3119 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3124 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
3120 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | 3125 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { |
3121 Variable* this_var = super_ref->this_var()->var(); | 3126 Variable* this_var = super_ref->this_var()->var(); |
3122 GetVar(r4, this_var); | 3127 GetVar(r4, this_var); |
3123 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | 3128 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
3124 Label uninitialized_this; | 3129 Label uninitialized_this; |
3125 __ beq(&uninitialized_this); | 3130 __ beq(&uninitialized_this); |
(...skipping 12 matching lines...) Expand all Loading... |
3138 // through this function. Avoid early returns. | 3143 // through this function. Avoid early returns. |
3139 expr->return_is_recorded_ = false; | 3144 expr->return_is_recorded_ = false; |
3140 #endif | 3145 #endif |
3141 | 3146 |
3142 Comment cmnt(masm_, "[ Call"); | 3147 Comment cmnt(masm_, "[ Call"); |
3143 Expression* callee = expr->expression(); | 3148 Expression* callee = expr->expression(); |
3144 Call::CallType call_type = expr->GetCallType(isolate()); | 3149 Call::CallType call_type = expr->GetCallType(isolate()); |
3145 | 3150 |
3146 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3151 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
3147 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3152 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
3148 // to resolve the function we need to call. Then we call the resolved | 3153 // to resolve the function we need to call and the receiver of the |
3149 // function using the given arguments. | 3154 // call. Then we call the resolved function using the given |
| 3155 // arguments. |
3150 ZoneList<Expression*>* args = expr->arguments(); | 3156 ZoneList<Expression*>* args = expr->arguments(); |
3151 int arg_count = args->length(); | 3157 int arg_count = args->length(); |
3152 | 3158 |
3153 { | 3159 { |
3154 PreservePositionScope pos_scope(masm()->positions_recorder()); | 3160 PreservePositionScope pos_scope(masm()->positions_recorder()); |
3155 VisitForStackValue(callee); | 3161 VisitForStackValue(callee); |
3156 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 3162 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
3157 __ push(r5); // Reserved receiver slot. | 3163 __ push(r5); // Reserved receiver slot. |
3158 | 3164 |
3159 // Push the arguments. | 3165 // Push the arguments. |
3160 for (int i = 0; i < arg_count; i++) { | 3166 for (int i = 0; i < arg_count; i++) { |
3161 VisitForStackValue(args->at(i)); | 3167 VisitForStackValue(args->at(i)); |
3162 } | 3168 } |
3163 | 3169 |
3164 // Push a copy of the function (found below the arguments) and | 3170 // Push a copy of the function (found below the arguments) and |
3165 // resolve eval. | 3171 // resolve eval. |
3166 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3172 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3167 __ push(r4); | 3173 __ push(r4); |
3168 EmitResolvePossiblyDirectEval(arg_count); | 3174 EmitResolvePossiblyDirectEval(arg_count); |
3169 | 3175 |
3170 // Touch up the stack with the resolved function. | 3176 // The runtime call returns a pair of values in r3 (function) and |
| 3177 // r4 (receiver). Touch up the stack with the right values. |
3171 __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3178 __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 3179 __ StoreP(r4, MemOperand(sp, arg_count * kPointerSize), r0); |
3172 | 3180 |
3173 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); | 3181 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
3174 } | 3182 } |
3175 | 3183 |
3176 // Record source position for debugger. | 3184 // Record source position for debugger. |
3177 SetSourcePosition(expr->position()); | 3185 SetSourcePosition(expr->position()); |
3178 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3186 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
3179 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3187 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3180 __ CallStub(&stub); | 3188 __ CallStub(&stub); |
3181 RecordJSReturnSite(expr); | 3189 RecordJSReturnSite(expr); |
(...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4790 | 4798 |
4791 if (property != NULL) { | 4799 if (property != NULL) { |
4792 VisitForStackValue(property->obj()); | 4800 VisitForStackValue(property->obj()); |
4793 VisitForStackValue(property->key()); | 4801 VisitForStackValue(property->key()); |
4794 __ LoadSmiLiteral(r4, Smi::FromInt(language_mode())); | 4802 __ LoadSmiLiteral(r4, Smi::FromInt(language_mode())); |
4795 __ push(r4); | 4803 __ push(r4); |
4796 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4804 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4797 context()->Plug(r3); | 4805 context()->Plug(r3); |
4798 } else if (proxy != NULL) { | 4806 } else if (proxy != NULL) { |
4799 Variable* var = proxy->var(); | 4807 Variable* var = proxy->var(); |
4800 // Delete of an unqualified identifier is disallowed in strict mode but | 4808 // Delete of an unqualified identifier is disallowed in strict mode |
4801 // "delete this" is allowed. | 4809 // but "delete this" is allowed. |
4802 bool is_this = var->HasThisName(isolate()); | 4810 DCHECK(is_sloppy(language_mode()) || var->is_this()); |
4803 DCHECK(is_sloppy(language_mode()) || is_this); | |
4804 if (var->IsUnallocated()) { | 4811 if (var->IsUnallocated()) { |
4805 __ LoadP(r5, GlobalObjectOperand()); | 4812 __ LoadP(r5, GlobalObjectOperand()); |
4806 __ mov(r4, Operand(var->name())); | 4813 __ mov(r4, Operand(var->name())); |
4807 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); | 4814 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); |
4808 __ Push(r5, r4, r3); | 4815 __ Push(r5, r4, r3); |
4809 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4816 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4810 context()->Plug(r3); | 4817 context()->Plug(r3); |
4811 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4818 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4812 // Result of deleting non-global, non-dynamic variables is false. | 4819 // Result of deleting non-global, non-dynamic variables is false. |
4813 // The subexpression does not have side effects. | 4820 // The subexpression does not have side effects. |
4814 context()->Plug(is_this); | 4821 context()->Plug(var->is_this()); |
4815 } else { | 4822 } else { |
4816 // Non-global variable. Call the runtime to try to delete from the | 4823 // Non-global variable. Call the runtime to try to delete from the |
4817 // context where the variable was introduced. | 4824 // context where the variable was introduced. |
4818 DCHECK(!context_register().is(r5)); | 4825 DCHECK(!context_register().is(r5)); |
4819 __ mov(r5, Operand(var->name())); | 4826 __ mov(r5, Operand(var->name())); |
4820 __ Push(context_register(), r5); | 4827 __ Push(context_register(), r5); |
4821 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); | 4828 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); |
4822 context()->Plug(r3); | 4829 context()->Plug(r3); |
4823 } | 4830 } |
4824 } else { | 4831 } else { |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5545 return ON_STACK_REPLACEMENT; | 5552 return ON_STACK_REPLACEMENT; |
5546 } | 5553 } |
5547 | 5554 |
5548 DCHECK(interrupt_address == | 5555 DCHECK(interrupt_address == |
5549 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5556 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5550 return OSR_AFTER_STACK_CHECK; | 5557 return OSR_AFTER_STACK_CHECK; |
5551 } | 5558 } |
5552 } // namespace internal | 5559 } // namespace internal |
5553 } // namespace v8 | 5560 } // namespace v8 |
5554 #endif // V8_TARGET_ARCH_PPC | 5561 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |