5 #if V8_TARGET_ARCH_IA32 7 #include "src/api-arguments-inl.h" 8 #include "src/assembler-inl.h" 9 #include "src/base/bits.h" 10 #include "src/bootstrapper.h" 11 #include "src/code-stubs.h" 12 #include "src/frame-constants.h" 13 #include "src/frames.h" 14 #include "src/ic/ic.h" 15 #include "src/ic/stub-cache.h" 16 #include "src/isolate.h" 17 #include "src/macro-assembler.h" 18 #include "src/objects/api-callbacks.h" 19 #include "src/regexp/jsregexp.h" 20 #include "src/regexp/regexp-macro-assembler.h" 21 #include "src/runtime/runtime.h" 26 #define __ ACCESS_MASM(masm) 28 void JSEntryStub::Generate(MacroAssembler* masm) {
29 Label invoke, handler_entry, exit;
30 Label not_outermost_js, not_outermost_js_2;
33 NoRootArrayScope uninitialized_root_register(masm);
40 StackFrame::Type marker = type();
41 __ push(Immediate(StackFrame::TypeToMarker(marker)));
42 ExternalReference context_address =
43 ExternalReference::Create(IsolateAddressId::kContextAddress, isolate());
44 __ push(Operand(context_address.address(),
45 RelocInfo::EXTERNAL_REFERENCE));
51 __ InitializeRootRegister();
55 ExternalReference c_entry_fp =
56 ExternalReference::Create(IsolateAddressId::kCEntryFPAddress, isolate());
57 __ push(__ ExternalReferenceAsOperand(c_entry_fp, edi));
60 ExternalReference js_entry_sp =
61 ExternalReference::Create(IsolateAddressId::kJSEntrySPAddress, isolate());
62 __ cmp(__ ExternalReferenceAsOperand(js_entry_sp, edi), Immediate(0));
63 __ j(not_equal, ¬_outermost_js, Label::kNear);
64 __ mov(__ ExternalReferenceAsOperand(js_entry_sp, edi), ebp);
65 __ push(Immediate(StackFrame::OUTERMOST_JSENTRY_FRAME));
66 __ jmp(&invoke, Label::kNear);
67 __ bind(¬_outermost_js);
68 __ push(Immediate(StackFrame::INNER_JSENTRY_FRAME));
73 __ bind(&handler_entry);
74 handler_offset_ = handler_entry.pos();
77 ExternalReference pending_exception = ExternalReference::Create(
78 IsolateAddressId::kPendingExceptionAddress, isolate());
79 __ mov(__ ExternalReferenceAsOperand(pending_exception, edi), eax);
80 __ mov(eax, Immediate(isolate()->factory()->exception()));
85 __ PushStackHandler(edi);
91 __ Call(EntryTrampoline(), RelocInfo::CODE_TARGET);
94 __ PopStackHandler(edi);
100 __ cmp(edi, Immediate(StackFrame::OUTERMOST_JSENTRY_FRAME));
101 __ j(not_equal, ¬_outermost_js_2);
102 __ mov(__ ExternalReferenceAsOperand(js_entry_sp, edi), Immediate(0));
103 __ bind(¬_outermost_js_2);
106 __ pop(__ ExternalReferenceAsOperand(c_entry_fp, edi));
112 __ add(esp, Immediate(2 * kPointerSize));
120 static Operand ApiParameterOperand(
int index) {
121 return Operand(esp, index * kPointerSize);
130 static void PrepareCallApiFunction(MacroAssembler* masm,
int argc,
132 __ EnterApiExitFrame(argc, scratch);
133 if (__ emit_debug_code()) {
134 __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue)));
142 static void CallApiFunctionAndReturn(MacroAssembler* masm,
143 Register function_address,
144 ExternalReference thunk_ref,
145 Operand thunk_last_arg,
int stack_space,
146 Operand* stack_space_operand,
147 Operand return_value_operand) {
148 Isolate* isolate = masm->isolate();
150 ExternalReference next_address =
151 ExternalReference::handle_scope_next_address(isolate);
152 ExternalReference limit_address =
153 ExternalReference::handle_scope_limit_address(isolate);
154 ExternalReference level_address =
155 ExternalReference::handle_scope_level_address(isolate);
157 DCHECK(edx == function_address);
159 __ add(__ ExternalReferenceAsOperand(level_address, esi), Immediate(1));
160 __ mov(esi, __ ExternalReferenceAsOperand(next_address, esi));
161 __ mov(edi, __ ExternalReferenceAsOperand(limit_address, edi));
163 if (FLAG_log_timer_events) {
164 FrameScope frame(masm, StackFrame::MANUAL);
165 __ PushSafepointRegisters();
166 __ PrepareCallCFunction(1, eax);
167 __ Move(Operand(esp, 0),
168 Immediate(ExternalReference::isolate_address(isolate)));
169 __ CallCFunction(ExternalReference::log_enter_external_function(), 1);
170 __ PopSafepointRegisters();
174 Label profiler_disabled;
175 Label end_profiler_check;
176 __ Move(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
177 __ cmpb(Operand(eax, 0), Immediate(0));
178 __ j(zero, &profiler_disabled);
181 __ mov(thunk_last_arg, function_address);
183 __ Move(eax, Immediate(thunk_ref));
185 __ jmp(&end_profiler_check);
187 __ bind(&profiler_disabled);
189 __ call(function_address);
190 __ bind(&end_profiler_check);
192 if (FLAG_log_timer_events) {
193 FrameScope frame(masm, StackFrame::MANUAL);
194 __ PushSafepointRegisters();
195 __ PrepareCallCFunction(1, eax);
196 __ mov(eax, Immediate(ExternalReference::isolate_address(isolate)));
197 __ mov(Operand(esp, 0), eax);
198 __ CallCFunction(ExternalReference::log_leave_external_function(), 1);
199 __ PopSafepointRegisters();
204 __ mov(eax, return_value_operand);
206 Label promote_scheduled_exception;
207 Label delete_allocated_handles;
208 Label leave_exit_frame;
213 __ mov(__ ExternalReferenceAsOperand(next_address, ecx), esi);
214 __ sub(__ ExternalReferenceAsOperand(level_address, ecx), Immediate(1));
215 __ Assert(above_equal, AbortReason::kInvalidHandleScopeLevel);
216 __ cmp(edi, __ ExternalReferenceAsOperand(limit_address, ecx));
217 __ j(not_equal, &delete_allocated_handles);
220 __ bind(&leave_exit_frame);
221 if (stack_space_operand !=
nullptr) {
222 __ mov(edx, *stack_space_operand);
224 __ LeaveApiExitFrame();
227 ExternalReference scheduled_exception_address =
228 ExternalReference::scheduled_exception_address(isolate);
229 __ mov(ecx, __ ExternalReferenceAsOperand(scheduled_exception_address, ecx));
230 __ CompareRoot(ecx, RootIndex::kTheHoleValue);
231 __ j(not_equal, &promote_scheduled_exception);
236 Register return_value = eax;
239 __ JumpIfSmi(return_value, &ok, Label::kNear);
240 __ mov(map, FieldOperand(return_value, HeapObject::kMapOffset));
242 __ CmpInstanceType(map, LAST_NAME_TYPE);
243 __ j(below_equal, &ok, Label::kNear);
245 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE);
246 __ j(above_equal, &ok, Label::kNear);
248 __ CompareRoot(map, RootIndex::kHeapNumberMap);
249 __ j(equal, &ok, Label::kNear);
251 __ CompareRoot(return_value, RootIndex::kUndefinedValue);
252 __ j(equal, &ok, Label::kNear);
254 __ CompareRoot(return_value, RootIndex::kTrueValue);
255 __ j(equal, &ok, Label::kNear);
257 __ CompareRoot(return_value, RootIndex::kFalseValue);
258 __ j(equal, &ok, Label::kNear);
260 __ CompareRoot(return_value, RootIndex::kNullValue);
261 __ j(equal, &ok, Label::kNear);
263 __ Abort(AbortReason::kAPICallReturnedInvalidObject);
268 if (stack_space_operand !=
nullptr) {
269 DCHECK_EQ(0, stack_space);
274 __ ret(stack_space * kPointerSize);
278 __ bind(&promote_scheduled_exception);
279 __ TailCallRuntime(Runtime::kPromoteScheduledException);
282 ExternalReference delete_extensions =
283 ExternalReference::delete_handle_scope_extensions();
284 __ bind(&delete_allocated_handles);
285 __ mov(__ ExternalReferenceAsOperand(limit_address, ecx), edi);
287 __ Move(eax, Immediate(ExternalReference::isolate_address(isolate)));
288 __ mov(Operand(esp, 0), eax);
289 __ Move(eax, Immediate(delete_extensions));
292 __ jmp(&leave_exit_frame);
295 void CallApiCallbackStub::Generate(MacroAssembler* masm) {
309 Register call_data = eax;
310 Register holder = ecx;
311 Register api_function_address = edx;
312 Register return_address = edi;
314 typedef FunctionCallbackArguments FCA;
316 STATIC_ASSERT(FCA::kArgsLength == 6);
317 STATIC_ASSERT(FCA::kNewTargetIndex == 5);
318 STATIC_ASSERT(FCA::kDataIndex == 4);
319 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
320 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
321 STATIC_ASSERT(FCA::kIsolateIndex == 1);
322 STATIC_ASSERT(FCA::kHolderIndex == 0);
324 __ pop(return_address);
327 __ PushRoot(RootIndex::kUndefinedValue);
333 __ PushRoot(RootIndex::kUndefinedValue);
335 __ PushRoot(RootIndex::kUndefinedValue);
337 __ Push(Immediate(ExternalReference::isolate_address(isolate())));
341 Register scratch = call_data;
343 __ mov(scratch, esp);
346 __ push(return_address);
352 const int kApiArgc = 1 + 1;
356 const int kApiStackSpace = 3;
358 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace, edi);
361 __ mov(ApiParameterOperand(2), scratch);
362 __ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize));
364 __ mov(ApiParameterOperand(3), scratch);
366 __ Move(ApiParameterOperand(4), Immediate(argc()));
369 __ lea(scratch, ApiParameterOperand(2));
370 __ mov(ApiParameterOperand(0), scratch);
372 ExternalReference thunk_ref = ExternalReference::invoke_function_callback();
375 int return_value_offset = 2 + FCA::kReturnValueOffset;
376 Operand return_value_operand(ebp, return_value_offset * kPointerSize);
377 const int stack_space = argc() + FCA::kArgsLength + 1;
378 Operand* stack_space_operand =
nullptr;
379 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
380 ApiParameterOperand(1), stack_space,
381 stack_space_operand, return_value_operand);
385 void CallApiGetterStub::Generate(MacroAssembler* masm) {
388 STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0);
389 STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1);
390 STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2);
391 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3);
392 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4);
393 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5);
394 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6);
395 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7);
397 Register receiver = ApiGetterDescriptor::ReceiverRegister();
398 Register holder = ApiGetterDescriptor::HolderRegister();
399 Register callback = ApiGetterDescriptor::CallbackRegister();
400 Register scratch = edi;
401 DCHECK(!AreAliased(receiver, holder, callback, scratch));
405 __ push(FieldOperand(callback, AccessorInfo::kDataOffset));
406 __ PushRoot(RootIndex::kUndefinedValue);
408 __ PushRoot(RootIndex::kUndefinedValue);
409 __ Push(Immediate(ExternalReference::isolate_address(isolate())));
411 __ push(Immediate(Smi::zero()));
412 __ push(FieldOperand(callback, AccessorInfo::kNameOffset));
416 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
421 const int kApiArgc = 3 + 1;
423 PrepareCallApiFunction(masm, kApiArgc, scratch);
427 __ lea(scratch, Operand(ebp, kPointerSize + 2 * kPointerSize));
430 Operand info_object = ApiParameterOperand(3);
431 __ mov(info_object, scratch);
434 __ sub(scratch, Immediate(kPointerSize));
435 __ mov(ApiParameterOperand(0), scratch);
437 __ lea(scratch, info_object);
438 __ mov(ApiParameterOperand(1), scratch);
440 Operand thunk_last_arg = ApiParameterOperand(2);
442 ExternalReference thunk_ref =
443 ExternalReference::invoke_accessor_getter_callback();
445 __ mov(scratch, FieldOperand(callback, AccessorInfo::kJsGetterOffset));
446 Register function_address = edx;
447 __ mov(function_address,
448 FieldOperand(scratch, Foreign::kForeignAddressOffset));
450 Operand return_value_operand(
451 ebp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize);
452 CallApiFunctionAndReturn(masm, function_address, thunk_ref, thunk_last_arg,
453 kStackUnwindSpace,
nullptr, return_value_operand);
461 #endif // V8_TARGET_ARCH_IA32