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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
| 7 #include "src/api-arguments.h" |
7 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 9 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 11 #include "src/full-codegen/full-codegen.h" |
11 #include "src/ia32/frames-ia32.h" | 12 #include "src/ia32/frames-ia32.h" |
12 | 13 |
13 namespace v8 { | 14 namespace v8 { |
14 namespace internal { | 15 namespace internal { |
15 | 16 |
16 #define __ ACCESS_MASM(masm) | 17 #define __ ACCESS_MASM(masm) |
(...skipping 2851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2868 // ----------------------------------- | 2869 // ----------------------------------- |
2869 | 2870 |
2870 // CheckSpreadAndPushToStack will push edx to save it. | 2871 // CheckSpreadAndPushToStack will push edx to save it. |
2871 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); | 2872 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); |
2872 CheckSpreadAndPushToStack(masm); | 2873 CheckSpreadAndPushToStack(masm); |
2873 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2874 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2874 TailCallMode::kDisallow), | 2875 TailCallMode::kDisallow), |
2875 RelocInfo::CODE_TARGET); | 2876 RelocInfo::CODE_TARGET); |
2876 } | 2877 } |
2877 | 2878 |
| 2879 namespace { |
| 2880 |
| 2881 // Prepares stack to put arguments (aligns and so on). Reserves |
| 2882 // space for return value if needed (assumes the return value is a handle). |
| 2883 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1) |
| 2884 // etc. Saves context (esi). If space was reserved for return value then |
| 2885 // stores the pointer to the reserved slot into esi. |
| 2886 void PrepareCallApiFunction(MacroAssembler* masm, int argc) { |
| 2887 __ EnterApiExitFrame(argc); |
| 2888 if (__ emit_debug_code()) { |
| 2889 __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue))); |
| 2890 } |
| 2891 } |
| 2892 |
| 2893 // Generates an Operand for saving parameters after PrepareCallApiFunction. |
| 2894 Operand ApiParameterOperand(int index) { |
| 2895 return MemOperand(esp, index * kPointerSize); |
| 2896 } |
| 2897 |
| 2898 } // namespace |
| 2899 |
| 2900 // static |
| 2901 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) { |
| 2902 // ----------- S t a t e ------------- |
| 2903 // -- eax : the number of arguments (not incl. the receiver) |
| 2904 // -- edx : api function address |
| 2905 // -- esp[0] : return address |
| 2906 // -- esp[4] : holder |
| 2907 // -- esp[8] : isolate |
| 2908 // -- esp[12] : return value default |
| 2909 // -- esp[16] : return value |
| 2910 // -- esp[20] : call data |
| 2911 // -- esp[24] : target |
| 2912 // -- esp[28] : context save |
| 2913 // -- esp[32] : new.target |
| 2914 // -- esp[36] : last argument |
| 2915 // -- esp[32 + argc * 4] : first argument |
| 2916 // -- esp[36 + argc * 4] : receiver |
| 2917 // ----------------------------------- |
| 2918 typedef FunctionCallbackArguments FCA; |
| 2919 |
| 2920 STATIC_ASSERT(FCA::kNewTargetIndex == 7); |
| 2921 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| 2922 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
| 2923 STATIC_ASSERT(FCA::kDataIndex == 4); |
| 2924 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
| 2925 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
| 2926 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
| 2927 STATIC_ASSERT(FCA::kHolderIndex == 0); |
| 2928 STATIC_ASSERT(FCA::kArgsLength == 8); |
| 2929 |
| 2930 // Compute the pointer to the implicit args on the stack. |
| 2931 __ lea(ebx, MemOperand(esp, kPCOnStackSize)); |
| 2932 |
| 2933 // API function gets reference to the v8::Arguments. If CPU profiler |
| 2934 // is enabled wrapper function will be called and we need to pass |
| 2935 // address of the callback as additional parameter, always allocate |
| 2936 // space for it. |
| 2937 const int kApiArgc = 1 + 1; |
| 2938 |
| 2939 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space |
| 2940 // since it's not controlled by the GC. |
| 2941 const int kApiStackSpace = 3; |
| 2942 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace); |
| 2943 // Initialize FunctionCallbackInfo::implicit_args_. |
| 2944 __ mov(ApiParameterOperand(2), ebx); |
| 2945 // Initialize FunctionCallbackInfo::values_. |
| 2946 __ lea(ebx, MemOperand(ebx, eax, times_pointer_size, |
| 2947 (FCA::kArgsLength - 1) * kPointerSize)); |
| 2948 __ mov(ApiParameterOperand(3), ebx); |
| 2949 // Initialize FunctionCallbackInfo::length_. |
| 2950 __ mov(ApiParameterOperand(4), eax); |
| 2951 |
| 2952 // Load first argument with pointer to FunctionCallbackInfo. |
| 2953 __ lea(ebx, ApiParameterOperand(2)); |
| 2954 __ mov(ApiParameterOperand(0), ebx); |
| 2955 |
| 2956 ExternalReference const next_address = |
| 2957 ExternalReference::handle_scope_next_address(masm->isolate()); |
| 2958 ExternalReference const limit_address = |
| 2959 ExternalReference::handle_scope_limit_address(masm->isolate()); |
| 2960 ExternalReference const level_address = |
| 2961 ExternalReference::handle_scope_level_address(masm->isolate()); |
| 2962 |
| 2963 // Allocate HandleScope in callee-save registers. |
| 2964 __ mov(ebx, Operand::StaticVariable(next_address)); |
| 2965 __ mov(edi, Operand::StaticVariable(limit_address)); |
| 2966 __ add(Operand::StaticVariable(level_address), Immediate(1)); |
| 2967 |
| 2968 // Check if profiling is active, and if so call the function indirectly |
| 2969 // via the invoke_function_callback helper. |
| 2970 Label call_indirect, done_call; |
| 2971 __ cmpb(Operand::StaticVariable( |
| 2972 ExternalReference::is_profiling_address(masm->isolate())), |
| 2973 Immediate(0)); |
| 2974 __ j(not_zero, &call_indirect, Label::kNear); |
| 2975 { |
| 2976 // Call the API function directly. |
| 2977 __ call(edx); |
| 2978 } |
| 2979 __ jmp(&done_call, Label::kNear); |
| 2980 __ bind(&call_indirect); |
| 2981 { |
| 2982 // Call the API function indirectly when profiling is on. |
| 2983 __ mov(ApiParameterOperand(1), edx); |
| 2984 __ mov(eax, Immediate(ExternalReference::invoke_function_callback( |
| 2985 masm->isolate()))); |
| 2986 __ call(eax); |
| 2987 } |
| 2988 __ bind(&done_call); |
| 2989 |
| 2990 // No more valid handles (the result handle was the last one). Restore |
| 2991 // previous handle scope. |
| 2992 Label delete_allocated_handles; |
| 2993 __ mov(Operand::StaticVariable(next_address), ebx); |
| 2994 __ sub(Operand::StaticVariable(level_address), Immediate(1)); |
| 2995 __ cmp(edi, Operand::StaticVariable(limit_address)); |
| 2996 __ j(not_equal, &delete_allocated_handles); |
| 2997 |
| 2998 // Leave the API exit frame. |
| 2999 Label leave_exit_frame; |
| 3000 __ bind(&leave_exit_frame); |
| 3001 __ mov(eax, MemOperand(ebp, (2 + FCA::kReturnValueOffset) * kPointerSize)); |
| 3002 __ mov(esi, MemOperand(ebp, (2 + FCA::kContextSaveIndex) * kPointerSize)); |
| 3003 __ mov(ebx, ApiParameterOperand(4)); |
| 3004 __ LeaveApiExitFrame(false); |
| 3005 |
| 3006 // Check if the function scheduled an exception. |
| 3007 Label promote_scheduled_exception; |
| 3008 __ cmp(Operand::StaticVariable( |
| 3009 ExternalReference::scheduled_exception_address(masm->isolate())), |
| 3010 Immediate(masm->isolate()->factory()->the_hole_value())); |
| 3011 __ j(not_equal, &promote_scheduled_exception); |
| 3012 |
| 3013 // Check if the function returned a valid JavaScript value. |
| 3014 __ AssertApiCallResult(eax); |
| 3015 |
| 3016 // Drop the arguments and return. |
| 3017 __ PopReturnAddressTo(ecx); |
| 3018 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, |
| 3019 (FCA::kArgsLength + 1) * kPointerSize)); |
| 3020 __ PushReturnAddressFrom(ecx); |
| 3021 __ Ret(); |
| 3022 |
| 3023 // Re-throw by promoting a scheduled exception. |
| 3024 __ bind(&promote_scheduled_exception); |
| 3025 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
| 3026 |
| 3027 // HandleScope limit has changed. Delete allocated extensions. |
| 3028 __ bind(&delete_allocated_handles); |
| 3029 { |
| 3030 __ mov(Operand::StaticVariable(limit_address), edi); |
| 3031 __ mov(Operand(esp, 0), |
| 3032 Immediate(ExternalReference::isolate_address(masm->isolate()))); |
| 3033 __ mov(eax, Immediate(ExternalReference::delete_handle_scope_extensions( |
| 3034 masm->isolate()))); |
| 3035 __ call(eax); |
| 3036 } |
| 3037 __ jmp(&leave_exit_frame); |
| 3038 } |
| 3039 |
2878 // static | 3040 // static |
2879 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 3041 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2880 // ----------- S t a t e ------------- | 3042 // ----------- S t a t e ------------- |
2881 // -- eax : the number of arguments (not including the receiver) | 3043 // -- eax : the number of arguments (not including the receiver) |
2882 // -- edx : the new target (checked to be a constructor) | 3044 // -- edx : the new target (checked to be a constructor) |
2883 // -- edi : the constructor to call (checked to be a JSFunction) | 3045 // -- edi : the constructor to call (checked to be a JSFunction) |
2884 // ----------------------------------- | 3046 // ----------------------------------- |
2885 __ AssertFunction(edi); | 3047 __ AssertFunction(edi); |
2886 | 3048 |
2887 // Calling convention for function specific ConstructStubs require | 3049 // Calling convention for function specific ConstructStubs require |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 } | 3419 } |
3258 // Now jump to the instructions of the returned code object. | 3420 // Now jump to the instructions of the returned code object. |
3259 __ jmp(edi); | 3421 __ jmp(edi); |
3260 } | 3422 } |
3261 | 3423 |
3262 #undef __ | 3424 #undef __ |
3263 } // namespace internal | 3425 } // namespace internal |
3264 } // namespace v8 | 3426 } // namespace v8 |
3265 | 3427 |
3266 #endif // V8_TARGET_ARCH_IA32 | 3428 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |