• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/execution/execution.h"
6 
7 #include "src/api/api-inl.h"
8 #include "src/compiler/wasm-compiler.h"  // Only for static asserts.
9 #include "src/execution/frames.h"
10 #include "src/execution/isolate-inl.h"
11 #include "src/execution/vm-state-inl.h"
12 #include "src/logging/counters.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 namespace {
18 
NormalizeReceiver(Isolate * isolate,Handle<Object> receiver)19 Handle<Object> NormalizeReceiver(Isolate* isolate, Handle<Object> receiver) {
20   // Convert calls on global objects to be calls on the global
21   // receiver instead to avoid having a 'this' pointer which refers
22   // directly to a global object.
23   if (receiver->IsJSGlobalObject()) {
24     return handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(),
25                   isolate);
26   }
27   return receiver;
28 }
29 
30 struct InvokeParams {
31   static InvokeParams SetUpForNew(Isolate* isolate, Handle<Object> constructor,
32                                   Handle<Object> new_target, int argc,
33                                   Handle<Object>* argv);
34 
35   static InvokeParams SetUpForCall(Isolate* isolate, Handle<Object> callable,
36                                    Handle<Object> receiver, int argc,
37                                    Handle<Object>* argv);
38 
39   static InvokeParams SetUpForTryCall(
40       Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
41       int argc, Handle<Object>* argv,
42       Execution::MessageHandling message_handling,
43       MaybeHandle<Object>* exception_out, bool reschedule_terminate);
44 
45   static InvokeParams SetUpForRunMicrotasks(Isolate* isolate,
46                                             MicrotaskQueue* microtask_queue,
47                                             MaybeHandle<Object>* exception_out);
48 
49   Handle<Object> target;
50   Handle<Object> receiver;
51   int argc;
52   Handle<Object>* argv;
53   Handle<Object> new_target;
54 
55   MicrotaskQueue* microtask_queue;
56 
57   Execution::MessageHandling message_handling;
58   MaybeHandle<Object>* exception_out;
59 
60   bool is_construct;
61   Execution::Target execution_target;
62   bool reschedule_terminate;
63 };
64 
65 // static
SetUpForNew(Isolate * isolate,Handle<Object> constructor,Handle<Object> new_target,int argc,Handle<Object> * argv)66 InvokeParams InvokeParams::SetUpForNew(Isolate* isolate,
67                                        Handle<Object> constructor,
68                                        Handle<Object> new_target, int argc,
69                                        Handle<Object>* argv) {
70   InvokeParams params;
71   params.target = constructor;
72   params.receiver = isolate->factory()->undefined_value();
73   params.argc = argc;
74   params.argv = argv;
75   params.new_target = new_target;
76   params.microtask_queue = nullptr;
77   params.message_handling = Execution::MessageHandling::kReport;
78   params.exception_out = nullptr;
79   params.is_construct = true;
80   params.execution_target = Execution::Target::kCallable;
81   params.reschedule_terminate = true;
82   return params;
83 }
84 
85 // static
SetUpForCall(Isolate * isolate,Handle<Object> callable,Handle<Object> receiver,int argc,Handle<Object> * argv)86 InvokeParams InvokeParams::SetUpForCall(Isolate* isolate,
87                                         Handle<Object> callable,
88                                         Handle<Object> receiver, int argc,
89                                         Handle<Object>* argv) {
90   InvokeParams params;
91   params.target = callable;
92   params.receiver = NormalizeReceiver(isolate, receiver);
93   params.argc = argc;
94   params.argv = argv;
95   params.new_target = isolate->factory()->undefined_value();
96   params.microtask_queue = nullptr;
97   params.message_handling = Execution::MessageHandling::kReport;
98   params.exception_out = nullptr;
99   params.is_construct = false;
100   params.execution_target = Execution::Target::kCallable;
101   params.reschedule_terminate = true;
102   return params;
103 }
104 
105 // static
SetUpForTryCall(Isolate * isolate,Handle<Object> callable,Handle<Object> receiver,int argc,Handle<Object> * argv,Execution::MessageHandling message_handling,MaybeHandle<Object> * exception_out,bool reschedule_terminate)106 InvokeParams InvokeParams::SetUpForTryCall(
107     Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
108     int argc, Handle<Object>* argv, Execution::MessageHandling message_handling,
109     MaybeHandle<Object>* exception_out, bool reschedule_terminate) {
110   InvokeParams params;
111   params.target = callable;
112   params.receiver = NormalizeReceiver(isolate, receiver);
113   params.argc = argc;
114   params.argv = argv;
115   params.new_target = isolate->factory()->undefined_value();
116   params.microtask_queue = nullptr;
117   params.message_handling = message_handling;
118   params.exception_out = exception_out;
119   params.is_construct = false;
120   params.execution_target = Execution::Target::kCallable;
121   params.reschedule_terminate = reschedule_terminate;
122   return params;
123 }
124 
125 // static
SetUpForRunMicrotasks(Isolate * isolate,MicrotaskQueue * microtask_queue,MaybeHandle<Object> * exception_out)126 InvokeParams InvokeParams::SetUpForRunMicrotasks(
127     Isolate* isolate, MicrotaskQueue* microtask_queue,
128     MaybeHandle<Object>* exception_out) {
129   auto undefined = isolate->factory()->undefined_value();
130   InvokeParams params;
131   params.target = undefined;
132   params.receiver = undefined;
133   params.argc = 0;
134   params.argv = nullptr;
135   params.new_target = undefined;
136   params.microtask_queue = microtask_queue;
137   params.message_handling = Execution::MessageHandling::kReport;
138   params.exception_out = exception_out;
139   params.is_construct = false;
140   params.execution_target = Execution::Target::kRunMicrotasks;
141   params.reschedule_terminate = true;
142   return params;
143 }
144 
JSEntry(Isolate * isolate,Execution::Target execution_target,bool is_construct)145 Handle<Code> JSEntry(Isolate* isolate, Execution::Target execution_target,
146                      bool is_construct) {
147   if (is_construct) {
148     DCHECK_EQ(Execution::Target::kCallable, execution_target);
149     return BUILTIN_CODE(isolate, JSConstructEntry);
150   } else if (execution_target == Execution::Target::kCallable) {
151     DCHECK(!is_construct);
152     return BUILTIN_CODE(isolate, JSEntry);
153   } else if (execution_target == Execution::Target::kRunMicrotasks) {
154     DCHECK(!is_construct);
155     return BUILTIN_CODE(isolate, JSRunMicrotasksEntry);
156   }
157   UNREACHABLE();
158 }
159 
NewScriptContext(Isolate * isolate,Handle<JSFunction> function)160 MaybeHandle<Context> NewScriptContext(Isolate* isolate,
161                                       Handle<JSFunction> function) {
162   // Creating a script context is a side effect, so abort if that's not
163   // allowed.
164   if (isolate->debug_execution_mode() == DebugInfo::kSideEffects) {
165     isolate->Throw(*isolate->factory()->NewEvalError(
166         MessageTemplate::kNoSideEffectDebugEvaluate));
167     return MaybeHandle<Context>();
168   }
169   SaveAndSwitchContext save(isolate, function->context());
170   SharedFunctionInfo sfi = function->shared();
171   Handle<Script> script(Script::cast(sfi.script()), isolate);
172   Handle<ScopeInfo> scope_info(sfi.scope_info(), isolate);
173   Handle<NativeContext> native_context(NativeContext::cast(function->context()),
174                                        isolate);
175   Handle<JSGlobalObject> global_object(native_context->global_object(),
176                                        isolate);
177   Handle<ScriptContextTable> script_context(
178       native_context->script_context_table(), isolate);
179 
180   // Find name clashes.
181   for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
182     Handle<String> name(scope_info->ContextLocalName(var), isolate);
183     VariableMode mode = scope_info->ContextLocalMode(var);
184     ScriptContextTable::LookupResult lookup;
185     if (ScriptContextTable::Lookup(isolate, *script_context, *name, &lookup)) {
186       if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
187         Handle<Context> context = ScriptContextTable::GetContext(
188             isolate, script_context, lookup.context_index);
189         // If we are trying to re-declare a REPL-mode let as a let, allow it.
190         if (!(mode == VariableMode::kLet && lookup.mode == VariableMode::kLet &&
191               scope_info->IsReplModeScope() &&
192               context->scope_info().IsReplModeScope())) {
193           // ES#sec-globaldeclarationinstantiation 5.b:
194           // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
195           // exception.
196           MessageLocation location(script, 0, 1);
197           return isolate->ThrowAt<Context>(
198               isolate->factory()->NewSyntaxError(
199                   MessageTemplate::kVarRedeclaration, name),
200               &location);
201         }
202       }
203     }
204 
205     if (IsLexicalVariableMode(mode)) {
206       LookupIterator it(isolate, global_object, name, global_object,
207                         LookupIterator::OWN_SKIP_INTERCEPTOR);
208       Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
209       // Can't fail since the we looking up own properties on the global object
210       // skipping interceptors.
211       CHECK(!maybe.IsNothing());
212       if ((maybe.FromJust() & DONT_DELETE) != 0) {
213         // ES#sec-globaldeclarationinstantiation 5.a:
214         // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
215         // exception.
216         // ES#sec-globaldeclarationinstantiation 5.d:
217         // If hasRestrictedGlobal is true, throw a SyntaxError exception.
218         MessageLocation location(script, 0, 1);
219         return isolate->ThrowAt<Context>(
220             isolate->factory()->NewSyntaxError(
221                 MessageTemplate::kVarRedeclaration, name),
222             &location);
223       }
224 
225       JSGlobalObject::InvalidatePropertyCell(global_object, name);
226     }
227   }
228 
229   Handle<Context> result =
230       isolate->factory()->NewScriptContext(native_context, scope_info);
231 
232   result->Initialize(isolate);
233 
234   Handle<ScriptContextTable> new_script_context_table =
235       ScriptContextTable::Extend(script_context, result);
236   native_context->synchronized_set_script_context_table(
237       *new_script_context_table);
238   return result;
239 }
240 
Invoke(Isolate * isolate,const InvokeParams & params)241 V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate,
242                                                  const InvokeParams& params) {
243   RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kInvoke);
244   DCHECK(!params.receiver->IsJSGlobalObject());
245   DCHECK_LE(params.argc, FixedArray::kMaxLength);
246 
247 #ifdef USE_SIMULATOR
248   // Simulators use separate stacks for C++ and JS. JS stack overflow checks
249   // are performed whenever a JS function is called. However, it can be the case
250   // that the C++ stack grows faster than the JS stack, resulting in an overflow
251   // there. Add a check here to make that less likely.
252   StackLimitCheck check(isolate);
253   if (check.HasOverflowed()) {
254     isolate->StackOverflow();
255     if (params.message_handling == Execution::MessageHandling::kReport) {
256       isolate->ReportPendingMessages();
257     }
258     return MaybeHandle<Object>();
259   }
260 #endif
261 
262   // api callbacks can be called directly, unless we want to take the detour
263   // through JS to set up a frame for break-at-entry.
264   if (params.target->IsJSFunction()) {
265     Handle<JSFunction> function = Handle<JSFunction>::cast(params.target);
266     if ((!params.is_construct || function->IsConstructor()) &&
267         function->shared().IsApiFunction() &&
268         !function->shared().BreakAtEntry()) {
269       SaveAndSwitchContext save(isolate, function->context());
270       DCHECK(function->context().global_object().IsJSGlobalObject());
271 
272       Handle<Object> receiver = params.is_construct
273                                     ? isolate->factory()->the_hole_value()
274                                     : params.receiver;
275       auto value = Builtins::InvokeApiFunction(
276           isolate, params.is_construct, function, receiver, params.argc,
277           params.argv, Handle<HeapObject>::cast(params.new_target));
278       bool has_exception = value.is_null();
279       DCHECK(has_exception == isolate->has_pending_exception());
280       if (has_exception) {
281         if (params.message_handling == Execution::MessageHandling::kReport) {
282           isolate->ReportPendingMessages();
283         }
284         return MaybeHandle<Object>();
285       } else {
286         isolate->clear_pending_message();
287       }
288       return value;
289     }
290 
291     // Set up a ScriptContext when running scripts that need it.
292     if (function->shared().needs_script_context()) {
293       Handle<Context> context;
294       if (!NewScriptContext(isolate, function).ToHandle(&context)) {
295         if (params.message_handling == Execution::MessageHandling::kReport) {
296           isolate->ReportPendingMessages();
297         }
298         return MaybeHandle<Object>();
299       }
300 
301       // We mutate the context if we allocate a script context. This is
302       // guaranteed to only happen once in a native context since scripts will
303       // always produce name clashes with themselves.
304       function->set_context(*context);
305     }
306   }
307 
308   // Entering JavaScript.
309   VMState<JS> state(isolate);
310   CHECK(AllowJavascriptExecution::IsAllowed(isolate));
311   if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
312     isolate->ThrowIllegalOperation();
313     if (params.message_handling == Execution::MessageHandling::kReport) {
314       isolate->ReportPendingMessages();
315     }
316     return MaybeHandle<Object>();
317   }
318   if (!DumpOnJavascriptExecution::IsAllowed(isolate)) {
319     V8::GetCurrentPlatform()->DumpWithoutCrashing();
320     return isolate->factory()->undefined_value();
321   }
322 
323   if (params.execution_target == Execution::Target::kCallable) {
324     Handle<Context> context = isolate->native_context();
325     if (!context->script_execution_callback().IsUndefined(isolate)) {
326       v8::Context::AbortScriptExecutionCallback callback =
327           v8::ToCData<v8::Context::AbortScriptExecutionCallback>(
328               context->script_execution_callback());
329       v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate);
330       v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
331       callback(api_isolate, api_context);
332       DCHECK(!isolate->has_scheduled_exception());
333       // Always throw an exception to abort execution, if callback exists.
334       isolate->ThrowIllegalOperation();
335       return MaybeHandle<Object>();
336     }
337   }
338 
339   // Placeholder for return value.
340   Object value;
341 
342   Handle<Code> code =
343       JSEntry(isolate, params.execution_target, params.is_construct);
344   {
345     // Save and restore context around invocation and block the
346     // allocation of handles without explicit handle scopes.
347     SaveContext save(isolate);
348     SealHandleScope shs(isolate);
349 
350     if (FLAG_clear_exceptions_on_js_entry) isolate->clear_pending_exception();
351 
352     if (params.execution_target == Execution::Target::kCallable) {
353       // clang-format off
354       // {new_target}, {target}, {receiver}, return value: tagged pointers
355       // {argv}: pointer to array of tagged pointers
356       using JSEntryFunction = GeneratedCode<Address(
357           Address root_register_value, Address new_target, Address target,
358           Address receiver, intptr_t argc, Address** argv)>;
359       // clang-format on
360       JSEntryFunction stub_entry =
361           JSEntryFunction::FromAddress(isolate, code->InstructionStart());
362 
363       Address orig_func = params.new_target->ptr();
364       Address func = params.target->ptr();
365       Address recv = params.receiver->ptr();
366       Address** argv = reinterpret_cast<Address**>(params.argv);
367       RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kJS_Execution);
368       value = Object(stub_entry.Call(isolate->isolate_data()->isolate_root(),
369                                      orig_func, func, recv, params.argc, argv));
370     } else {
371       DCHECK_EQ(Execution::Target::kRunMicrotasks, params.execution_target);
372 
373       // clang-format off
374       // return value: tagged pointers
375       // {microtask_queue}: pointer to a C++ object
376       using JSEntryFunction = GeneratedCode<Address(
377           Address root_register_value, MicrotaskQueue* microtask_queue)>;
378       // clang-format on
379       JSEntryFunction stub_entry =
380           JSEntryFunction::FromAddress(isolate, code->InstructionStart());
381 
382       RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kJS_Execution);
383       value = Object(stub_entry.Call(isolate->isolate_data()->isolate_root(),
384                                      params.microtask_queue));
385     }
386   }
387 
388 #ifdef VERIFY_HEAP
389   if (FLAG_verify_heap) {
390     value.ObjectVerify(isolate);
391   }
392 #endif
393 
394   // Update the pending exception flag and return the value.
395   bool has_exception = value.IsException(isolate);
396   DCHECK(has_exception == isolate->has_pending_exception());
397   if (has_exception) {
398     if (params.message_handling == Execution::MessageHandling::kReport) {
399       isolate->ReportPendingMessages();
400     }
401     return MaybeHandle<Object>();
402   } else {
403     isolate->clear_pending_message();
404   }
405 
406   return Handle<Object>(value, isolate);
407 }
408 
InvokeWithTryCatch(Isolate * isolate,const InvokeParams & params)409 MaybeHandle<Object> InvokeWithTryCatch(Isolate* isolate,
410                                        const InvokeParams& params) {
411   bool is_termination = false;
412   MaybeHandle<Object> maybe_result;
413   if (params.exception_out != nullptr) {
414     *params.exception_out = MaybeHandle<Object>();
415   }
416   DCHECK_IMPLIES(
417       params.message_handling == Execution::MessageHandling::kKeepPending,
418       params.exception_out == nullptr);
419   // Enter a try-block while executing the JavaScript code. To avoid
420   // duplicate error printing it must be non-verbose.  Also, to avoid
421   // creating message objects during stack overflow we shouldn't
422   // capture messages.
423   {
424     v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
425     catcher.SetVerbose(false);
426     catcher.SetCaptureMessage(false);
427 
428     maybe_result = Invoke(isolate, params);
429 
430     if (maybe_result.is_null()) {
431       DCHECK(isolate->has_pending_exception());
432       if (isolate->pending_exception() ==
433           ReadOnlyRoots(isolate).termination_exception()) {
434         is_termination = true;
435       } else {
436         if (params.exception_out != nullptr) {
437           DCHECK(catcher.HasCaught());
438           DCHECK(isolate->external_caught_exception());
439           *params.exception_out = v8::Utils::OpenHandle(*catcher.Exception());
440         }
441         if (params.message_handling == Execution::MessageHandling::kReport) {
442           isolate->OptionalRescheduleException(true);
443         }
444       }
445     }
446   }
447 
448   if (is_termination && params.reschedule_terminate) {
449     // Reschedule terminate execution exception.
450     isolate->OptionalRescheduleException(false);
451   }
452 
453   return maybe_result;
454 }
455 
456 }  // namespace
457 
458 // static
Call(Isolate * isolate,Handle<Object> callable,Handle<Object> receiver,int argc,Handle<Object> argv[])459 MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
460                                     Handle<Object> receiver, int argc,
461                                     Handle<Object> argv[]) {
462   return Invoke(isolate, InvokeParams::SetUpForCall(isolate, callable, receiver,
463                                                     argc, argv));
464 }
465 
CallBuiltin(Isolate * isolate,Handle<JSFunction> builtin,Handle<Object> receiver,int argc,Handle<Object> argv[])466 MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
467                                            Handle<JSFunction> builtin,
468                                            Handle<Object> receiver, int argc,
469                                            Handle<Object> argv[]) {
470   DCHECK(builtin->code().is_builtin());
471   DisableBreak no_break(isolate->debug());
472   return Invoke(isolate, InvokeParams::SetUpForCall(isolate, builtin, receiver,
473                                                     argc, argv));
474 }
475 
476 // static
New(Isolate * isolate,Handle<Object> constructor,int argc,Handle<Object> argv[])477 MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
478                                    int argc, Handle<Object> argv[]) {
479   return New(isolate, constructor, constructor, argc, argv);
480 }
481 
482 // static
New(Isolate * isolate,Handle<Object> constructor,Handle<Object> new_target,int argc,Handle<Object> argv[])483 MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
484                                    Handle<Object> new_target, int argc,
485                                    Handle<Object> argv[]) {
486   return Invoke(isolate, InvokeParams::SetUpForNew(isolate, constructor,
487                                                    new_target, argc, argv));
488 }
489 
490 // static
TryCall(Isolate * isolate,Handle<Object> callable,Handle<Object> receiver,int argc,Handle<Object> argv[],MessageHandling message_handling,MaybeHandle<Object> * exception_out,bool reschedule_terminate)491 MaybeHandle<Object> Execution::TryCall(
492     Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
493     int argc, Handle<Object> argv[], MessageHandling message_handling,
494     MaybeHandle<Object>* exception_out, bool reschedule_terminate) {
495   return InvokeWithTryCatch(
496       isolate, InvokeParams::SetUpForTryCall(
497                    isolate, callable, receiver, argc, argv, message_handling,
498                    exception_out, reschedule_terminate));
499 }
500 
501 // static
TryRunMicrotasks(Isolate * isolate,MicrotaskQueue * microtask_queue,MaybeHandle<Object> * exception_out)502 MaybeHandle<Object> Execution::TryRunMicrotasks(
503     Isolate* isolate, MicrotaskQueue* microtask_queue,
504     MaybeHandle<Object>* exception_out) {
505   return InvokeWithTryCatch(
506       isolate, InvokeParams::SetUpForRunMicrotasks(isolate, microtask_queue,
507                                                    exception_out));
508 }
509 
510 struct StackHandlerMarker {
511   Address next;
512   Address padding;
513 };
514 STATIC_ASSERT(offsetof(StackHandlerMarker, next) ==
515               StackHandlerConstants::kNextOffset);
516 STATIC_ASSERT(offsetof(StackHandlerMarker, padding) ==
517               StackHandlerConstants::kPaddingOffset);
518 STATIC_ASSERT(sizeof(StackHandlerMarker) == StackHandlerConstants::kSize);
519 
CallWasm(Isolate * isolate,Handle<Code> wrapper_code,Address wasm_call_target,Handle<Object> object_ref,Address packed_args)520 void Execution::CallWasm(Isolate* isolate, Handle<Code> wrapper_code,
521                          Address wasm_call_target, Handle<Object> object_ref,
522                          Address packed_args) {
523   using WasmEntryStub = GeneratedCode<Address(
524       Address target, Address object_ref, Address argv, Address c_entry_fp)>;
525   WasmEntryStub stub_entry =
526       WasmEntryStub::FromAddress(isolate, wrapper_code->InstructionStart());
527 
528   // Save and restore context around invocation and block the
529   // allocation of handles without explicit handle scopes.
530   SaveContext save(isolate);
531   SealHandleScope shs(isolate);
532 
533   Address saved_c_entry_fp = *isolate->c_entry_fp_address();
534   Address saved_js_entry_sp = *isolate->js_entry_sp_address();
535   if (saved_js_entry_sp == kNullAddress) {
536     *isolate->js_entry_sp_address() = GetCurrentStackPosition();
537   }
538   StackHandlerMarker stack_handler;
539   stack_handler.next = isolate->thread_local_top()->handler_;
540 #ifdef V8_USE_ADDRESS_SANITIZER
541   stack_handler.padding = GetCurrentStackPosition();
542 #else
543   stack_handler.padding = 0;
544 #endif
545   isolate->thread_local_top()->handler_ =
546       reinterpret_cast<Address>(&stack_handler);
547   trap_handler::SetThreadInWasm();
548 
549   {
550     RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kJS_Execution);
551     STATIC_ASSERT(compiler::CWasmEntryParameters::kCodeEntry == 0);
552     STATIC_ASSERT(compiler::CWasmEntryParameters::kObjectRef == 1);
553     STATIC_ASSERT(compiler::CWasmEntryParameters::kArgumentsBuffer == 2);
554     STATIC_ASSERT(compiler::CWasmEntryParameters::kCEntryFp == 3);
555     Address result = stub_entry.Call(wasm_call_target, object_ref->ptr(),
556                                      packed_args, saved_c_entry_fp);
557     if (result != kNullAddress) {
558       isolate->set_pending_exception(Object(result));
559     }
560   }
561 
562   // If there was an exception, then the thread-in-wasm flag is cleared
563   // already.
564   if (trap_handler::IsThreadInWasm()) {
565     trap_handler::ClearThreadInWasm();
566   }
567   isolate->thread_local_top()->handler_ = stack_handler.next;
568   if (saved_js_entry_sp == kNullAddress) {
569     *isolate->js_entry_sp_address() = saved_js_entry_sp;
570   }
571   *isolate->c_entry_fp_address() = saved_c_entry_fp;
572 }
573 
574 }  // namespace internal
575 }  // namespace v8
576