| 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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
| 8 | 8 |
| 9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
| 10 // | 10 // |
| (...skipping 3063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3074 // by the vector above. | 3074 // by the vector above. |
| 3075 CallIC(ic); | 3075 CallIC(ic); |
| 3076 RecordJSReturnSite(expr); | 3076 RecordJSReturnSite(expr); |
| 3077 // Restore context register. | 3077 // Restore context register. |
| 3078 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3078 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3079 context()->DropAndPlug(1, v0); | 3079 context()->DropAndPlug(1, v0); |
| 3080 } | 3080 } |
| 3081 | 3081 |
| 3082 | 3082 |
| 3083 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 3083 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
| 3084 // a6: copy of the first argument or undefined if it doesn't exist. | 3084 // a7: copy of the first argument or undefined if it doesn't exist. |
| 3085 if (arg_count > 0) { | 3085 if (arg_count > 0) { |
| 3086 __ ld(a6, MemOperand(sp, arg_count * kPointerSize)); | 3086 __ ld(a7, MemOperand(sp, arg_count * kPointerSize)); |
| 3087 } else { | 3087 } else { |
| 3088 __ LoadRoot(a6, Heap::kUndefinedValueRootIndex); | 3088 __ LoadRoot(a7, Heap::kUndefinedValueRootIndex); |
| 3089 } | 3089 } |
| 3090 | 3090 |
| 3091 // a6: the receiver of the enclosing function. |
| 3092 __ ld(a6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3093 |
| 3091 // a5: the receiver of the enclosing function. | 3094 // a5: the receiver of the enclosing function. |
| 3092 __ ld(a5, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3095 Variable* this_var = scope()->LookupThis(); |
| 3096 DCHECK_NOT_NULL(this_var); |
| 3097 __ ld(a5, VarOperand(this_var, a5)); |
| 3093 | 3098 |
| 3094 // a4: the language mode. | 3099 // a4: the language mode. |
| 3095 __ li(a4, Operand(Smi::FromInt(language_mode()))); | 3100 __ li(a4, Operand(Smi::FromInt(language_mode()))); |
| 3096 | 3101 |
| 3097 // a1: the start position of the scope the calls resides in. | 3102 // a1: the start position of the scope the calls resides in. |
| 3098 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); | 3103 __ li(a1, Operand(Smi::FromInt(scope()->start_position()))); |
| 3099 | 3104 |
| 3100 // Do the runtime call. | 3105 // Do the runtime call. |
| 3106 __ Push(a7); |
| 3101 __ Push(a6, a5, a4, a1); | 3107 __ Push(a6, a5, a4, a1); |
| 3102 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3108 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
| 3103 } | 3109 } |
| 3104 | 3110 |
| 3105 | 3111 |
| 3106 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3112 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3107 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | 3113 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { |
| 3108 Variable* this_var = super_ref->this_var()->var(); | 3114 Variable* this_var = super_ref->this_var()->var(); |
| 3109 GetVar(a1, this_var); | 3115 GetVar(a1, this_var); |
| 3110 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3116 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 3111 Label uninitialized_this; | 3117 Label uninitialized_this; |
| 3112 __ Branch(&uninitialized_this, eq, a1, Operand(at)); | 3118 __ Branch(&uninitialized_this, eq, a1, Operand(at)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3125 // through this function. Avoid early returns. | 3131 // through this function. Avoid early returns. |
| 3126 expr->return_is_recorded_ = false; | 3132 expr->return_is_recorded_ = false; |
| 3127 #endif | 3133 #endif |
| 3128 | 3134 |
| 3129 Comment cmnt(masm_, "[ Call"); | 3135 Comment cmnt(masm_, "[ Call"); |
| 3130 Expression* callee = expr->expression(); | 3136 Expression* callee = expr->expression(); |
| 3131 Call::CallType call_type = expr->GetCallType(isolate()); | 3137 Call::CallType call_type = expr->GetCallType(isolate()); |
| 3132 | 3138 |
| 3133 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3139 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
| 3134 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3140 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 3135 // to resolve the function we need to call. Then we call the resolved | 3141 // to resolve the function we need to call and the receiver of the |
| 3136 // function using the given arguments. | 3142 // call. Then we call the resolved function using the given |
| 3143 // arguments. |
| 3137 ZoneList<Expression*>* args = expr->arguments(); | 3144 ZoneList<Expression*>* args = expr->arguments(); |
| 3138 int arg_count = args->length(); | 3145 int arg_count = args->length(); |
| 3139 | 3146 |
| 3140 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 3147 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
| 3141 VisitForStackValue(callee); | 3148 VisitForStackValue(callee); |
| 3142 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 3149 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
| 3143 __ push(a2); // Reserved receiver slot. | 3150 __ push(a2); // Reserved receiver slot. |
| 3144 | 3151 |
| 3145 // Push the arguments. | 3152 // Push the arguments. |
| 3146 for (int i = 0; i < arg_count; i++) { | 3153 for (int i = 0; i < arg_count; i++) { |
| 3147 VisitForStackValue(args->at(i)); | 3154 VisitForStackValue(args->at(i)); |
| 3148 } | 3155 } |
| 3149 | 3156 |
| 3150 // Push a copy of the function (found below the arguments) and | 3157 // Push a copy of the function (found below the arguments) and |
| 3151 // resolve eval. | 3158 // resolve eval. |
| 3152 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3159 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3153 __ push(a1); | 3160 __ push(a1); |
| 3154 EmitResolvePossiblyDirectEval(arg_count); | 3161 EmitResolvePossiblyDirectEval(arg_count); |
| 3155 | 3162 |
| 3156 // Touch up the stack with the resolved function. | 3163 // The runtime call returns a pair of values in v0 (function) and |
| 3164 // v1 (receiver). Touch up the stack with the right values. |
| 3157 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3165 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3166 __ sd(v1, MemOperand(sp, arg_count * kPointerSize)); |
| 3158 | 3167 |
| 3159 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); | 3168 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
| 3160 } | 3169 } |
| 3161 // Record source position for debugger. | 3170 // Record source position for debugger. |
| 3162 SetSourcePosition(expr->position()); | 3171 SetSourcePosition(expr->position()); |
| 3163 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3172 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 3164 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3173 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3165 __ CallStub(&stub); | 3174 __ CallStub(&stub); |
| 3166 RecordJSReturnSite(expr); | 3175 RecordJSReturnSite(expr); |
| 3167 // Restore context register. | 3176 // Restore context register. |
| (...skipping 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4777 | 4786 |
| 4778 if (property != NULL) { | 4787 if (property != NULL) { |
| 4779 VisitForStackValue(property->obj()); | 4788 VisitForStackValue(property->obj()); |
| 4780 VisitForStackValue(property->key()); | 4789 VisitForStackValue(property->key()); |
| 4781 __ li(a1, Operand(Smi::FromInt(language_mode()))); | 4790 __ li(a1, Operand(Smi::FromInt(language_mode()))); |
| 4782 __ push(a1); | 4791 __ push(a1); |
| 4783 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4792 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4784 context()->Plug(v0); | 4793 context()->Plug(v0); |
| 4785 } else if (proxy != NULL) { | 4794 } else if (proxy != NULL) { |
| 4786 Variable* var = proxy->var(); | 4795 Variable* var = proxy->var(); |
| 4787 // Delete of an unqualified identifier is disallowed in strict mode but | 4796 // Delete of an unqualified identifier is disallowed in strict mode |
| 4788 // "delete this" is allowed. | 4797 // but "delete this" is allowed. |
| 4789 bool is_this = var->HasThisName(isolate()); | 4798 DCHECK(is_sloppy(language_mode()) || var->is_this()); |
| 4790 DCHECK(is_sloppy(language_mode()) || is_this); | |
| 4791 if (var->IsUnallocated()) { | 4799 if (var->IsUnallocated()) { |
| 4792 __ ld(a2, GlobalObjectOperand()); | 4800 __ ld(a2, GlobalObjectOperand()); |
| 4793 __ li(a1, Operand(var->name())); | 4801 __ li(a1, Operand(var->name())); |
| 4794 __ li(a0, Operand(Smi::FromInt(SLOPPY))); | 4802 __ li(a0, Operand(Smi::FromInt(SLOPPY))); |
| 4795 __ Push(a2, a1, a0); | 4803 __ Push(a2, a1, a0); |
| 4796 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4804 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4797 context()->Plug(v0); | 4805 context()->Plug(v0); |
| 4798 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4806 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4799 // Result of deleting non-global, non-dynamic variables is false. | 4807 // Result of deleting non-global, non-dynamic variables is false. |
| 4800 // The subexpression does not have side effects. | 4808 // The subexpression does not have side effects. |
| 4801 context()->Plug(is_this); | 4809 context()->Plug(var->is_this()); |
| 4802 } else { | 4810 } else { |
| 4803 // Non-global variable. Call the runtime to try to delete from the | 4811 // Non-global variable. Call the runtime to try to delete from the |
| 4804 // context where the variable was introduced. | 4812 // context where the variable was introduced. |
| 4805 DCHECK(!context_register().is(a2)); | 4813 DCHECK(!context_register().is(a2)); |
| 4806 __ li(a2, Operand(var->name())); | 4814 __ li(a2, Operand(var->name())); |
| 4807 __ Push(context_register(), a2); | 4815 __ Push(context_register(), a2); |
| 4808 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); | 4816 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); |
| 4809 context()->Plug(v0); | 4817 context()->Plug(v0); |
| 4810 } | 4818 } |
| 4811 } else { | 4819 } else { |
| (...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5545 reinterpret_cast<uint64_t>( | 5553 reinterpret_cast<uint64_t>( |
| 5546 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5554 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 5547 return OSR_AFTER_STACK_CHECK; | 5555 return OSR_AFTER_STACK_CHECK; |
| 5548 } | 5556 } |
| 5549 | 5557 |
| 5550 | 5558 |
| 5551 } // namespace internal | 5559 } // namespace internal |
| 5552 } // namespace v8 | 5560 } // namespace v8 |
| 5553 | 5561 |
| 5554 #endif // V8_TARGET_ARCH_MIPS64 | 5562 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |