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