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_X64 | 7 #if V8_TARGET_ARCH_X64 |
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 2986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 // Push copy of the first argument or undefined if it doesn't exist. | 2997 // Push copy of the first argument or undefined if it doesn't exist. |
2998 if (arg_count > 0) { | 2998 if (arg_count > 0) { |
2999 __ Push(Operand(rsp, arg_count * kPointerSize)); | 2999 __ Push(Operand(rsp, arg_count * kPointerSize)); |
3000 } else { | 3000 } else { |
3001 __ PushRoot(Heap::kUndefinedValueRootIndex); | 3001 __ PushRoot(Heap::kUndefinedValueRootIndex); |
3002 } | 3002 } |
3003 | 3003 |
3004 // Push the enclosing function. | 3004 // Push the enclosing function. |
3005 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 3005 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
3006 | 3006 |
| 3007 // Push the receiver of the enclosing function and do runtime call. |
| 3008 Variable* this_var = scope()->LookupThis(); |
| 3009 DCHECK_NOT_NULL(this_var); |
| 3010 __ Push(VarOperand(this_var, rcx)); |
| 3011 |
3007 // Push the language mode. | 3012 // Push the language mode. |
3008 __ Push(Smi::FromInt(language_mode())); | 3013 __ Push(Smi::FromInt(language_mode())); |
3009 | 3014 |
3010 // Push the start position of the scope the calls resides in. | 3015 // Push the start position of the scope the calls resides in. |
3011 __ Push(Smi::FromInt(scope()->start_position())); | 3016 __ Push(Smi::FromInt(scope()->start_position())); |
3012 | 3017 |
3013 // Do the runtime call. | 3018 // Do the runtime call. |
3014 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 3019 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
3015 } | 3020 } |
3016 | 3021 |
3017 | 3022 |
3018 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3023 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
3019 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { | 3024 SuperCallReference* super_ref, FeedbackVectorICSlot slot) { |
3020 Variable* this_var = super_ref->this_var()->var(); | 3025 Variable* this_var = super_ref->this_var()->var(); |
3021 GetVar(rcx, this_var); | 3026 GetVar(rcx, this_var); |
3022 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); | 3027 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); |
3023 Label uninitialized_this; | 3028 Label uninitialized_this; |
3024 __ j(equal, &uninitialized_this); | 3029 __ j(equal, &uninitialized_this); |
(...skipping 11 matching lines...) Expand all Loading... |
3036 // through this function. Avoid early returns. | 3041 // through this function. Avoid early returns. |
3037 expr->return_is_recorded_ = false; | 3042 expr->return_is_recorded_ = false; |
3038 #endif | 3043 #endif |
3039 | 3044 |
3040 Comment cmnt(masm_, "[ Call"); | 3045 Comment cmnt(masm_, "[ Call"); |
3041 Expression* callee = expr->expression(); | 3046 Expression* callee = expr->expression(); |
3042 Call::CallType call_type = expr->GetCallType(isolate()); | 3047 Call::CallType call_type = expr->GetCallType(isolate()); |
3043 | 3048 |
3044 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3049 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
3045 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3050 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
3046 // to resolve the function we need to call. Then we call the resolved | 3051 // to resolve the function we need to call and the receiver of the call. |
3047 // function using the given arguments. | 3052 // Then we call the resolved function using the given arguments. |
3048 ZoneList<Expression*>* args = expr->arguments(); | 3053 ZoneList<Expression*>* args = expr->arguments(); |
3049 int arg_count = args->length(); | 3054 int arg_count = args->length(); |
3050 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 3055 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
3051 VisitForStackValue(callee); | 3056 VisitForStackValue(callee); |
3052 __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot. | 3057 __ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot. |
3053 | 3058 |
3054 // Push the arguments. | 3059 // Push the arguments. |
3055 for (int i = 0; i < arg_count; i++) { | 3060 for (int i = 0; i < arg_count; i++) { |
3056 VisitForStackValue(args->at(i)); | 3061 VisitForStackValue(args->at(i)); |
3057 } | 3062 } |
3058 | 3063 |
3059 // Push a copy of the function (found below the arguments) and resolve | 3064 // Push a copy of the function (found below the arguments) and resolve |
3060 // eval. | 3065 // eval. |
3061 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); | 3066 __ Push(Operand(rsp, (arg_count + 1) * kPointerSize)); |
3062 EmitResolvePossiblyDirectEval(arg_count); | 3067 EmitResolvePossiblyDirectEval(arg_count); |
3063 | 3068 |
3064 // Touch up the callee. | 3069 // The runtime call returns a pair of values in rax (function) and |
| 3070 // rdx (receiver). Touch up the stack with the right values. |
| 3071 __ movp(Operand(rsp, (arg_count + 0) * kPointerSize), rdx); |
3065 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); | 3072 __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); |
3066 | 3073 |
3067 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); | 3074 PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS); |
3068 } | 3075 } |
3069 // Record source position for debugger. | 3076 // Record source position for debugger. |
3070 SetSourcePosition(expr->position()); | 3077 SetSourcePosition(expr->position()); |
3071 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3078 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
3072 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 3079 __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
3073 __ CallStub(&stub); | 3080 __ CallStub(&stub); |
3074 RecordJSReturnSite(expr); | 3081 RecordJSReturnSite(expr); |
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4714 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4721 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4715 | 4722 |
4716 if (property != NULL) { | 4723 if (property != NULL) { |
4717 VisitForStackValue(property->obj()); | 4724 VisitForStackValue(property->obj()); |
4718 VisitForStackValue(property->key()); | 4725 VisitForStackValue(property->key()); |
4719 __ Push(Smi::FromInt(language_mode())); | 4726 __ Push(Smi::FromInt(language_mode())); |
4720 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4727 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4721 context()->Plug(rax); | 4728 context()->Plug(rax); |
4722 } else if (proxy != NULL) { | 4729 } else if (proxy != NULL) { |
4723 Variable* var = proxy->var(); | 4730 Variable* var = proxy->var(); |
4724 // Delete of an unqualified identifier is disallowed in strict mode but | 4731 // Delete of an unqualified identifier is disallowed in strict mode |
4725 // "delete this" is allowed. | 4732 // but "delete this" is allowed. |
4726 bool is_this = var->HasThisName(isolate()); | 4733 DCHECK(is_sloppy(language_mode()) || var->is_this()); |
4727 DCHECK(is_sloppy(language_mode()) || is_this); | |
4728 if (var->IsUnallocated()) { | 4734 if (var->IsUnallocated()) { |
4729 __ Push(GlobalObjectOperand()); | 4735 __ Push(GlobalObjectOperand()); |
4730 __ Push(var->name()); | 4736 __ Push(var->name()); |
4731 __ Push(Smi::FromInt(SLOPPY)); | 4737 __ Push(Smi::FromInt(SLOPPY)); |
4732 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4738 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4733 context()->Plug(rax); | 4739 context()->Plug(rax); |
4734 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4740 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4735 // Result of deleting non-global variables is false. 'this' is | 4741 // Result of deleting non-global variables is false. 'this' is |
4736 // not really a variable, though we implement it as one. The | 4742 // not really a variable, though we implement it as one. The |
4737 // subexpression does not have side effects. | 4743 // subexpression does not have side effects. |
4738 context()->Plug(is_this); | 4744 context()->Plug(var->is_this()); |
4739 } else { | 4745 } else { |
4740 // Non-global variable. Call the runtime to try to delete from the | 4746 // Non-global variable. Call the runtime to try to delete from the |
4741 // context where the variable was introduced. | 4747 // context where the variable was introduced. |
4742 __ Push(context_register()); | 4748 __ Push(context_register()); |
4743 __ Push(var->name()); | 4749 __ Push(var->name()); |
4744 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); | 4750 __ CallRuntime(Runtime::kDeleteLookupSlot, 2); |
4745 context()->Plug(rax); | 4751 context()->Plug(rax); |
4746 } | 4752 } |
4747 } else { | 4753 } else { |
4748 // Result of deleting non-property, non-variable reference is true. | 4754 // Result of deleting non-property, non-variable reference is true. |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5481 Assembler::target_address_at(call_target_address, | 5487 Assembler::target_address_at(call_target_address, |
5482 unoptimized_code)); | 5488 unoptimized_code)); |
5483 return OSR_AFTER_STACK_CHECK; | 5489 return OSR_AFTER_STACK_CHECK; |
5484 } | 5490 } |
5485 | 5491 |
5486 | 5492 |
5487 } // namespace internal | 5493 } // namespace internal |
5488 } // namespace v8 | 5494 } // namespace v8 |
5489 | 5495 |
5490 #endif // V8_TARGET_ARCH_X64 | 5496 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |