Bug Summary

File:out/../deps/v8/src/execution/execution.cc
Warning:line 64, column 45
Forming reference to null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name execution.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D V8_GYP_BUILD -D V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D V8_TARGET_ARCH_X64 -D V8_HAVE_TARGET_OS -D V8_TARGET_OS_LINUX -D V8_EMBEDDER_STRING="-node.8" -D ENABLE_DISASSEMBLER -D V8_PROMISE_INTERNAL_FIELD_COUNT=1 -D V8_SHORT_BUILTIN_CALLS -D OBJECT_PRINT -D V8_INTL_SUPPORT -D V8_ATOMIC_OBJECT_FIELD_WRITES -D V8_ENABLE_LAZY_SOURCE_POSITIONS -D V8_USE_SIPHASH -D V8_SHARED_RO_HEAP -D V8_WIN64_UNWINDING_INFO -D V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -D V8_SNAPSHOT_COMPRESSION -D V8_ENABLE_WEBASSEMBLY -D V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS -D V8_ALLOCATION_FOLDING -D V8_ALLOCATION_SITE_TRACKING -D V8_SCRIPTORMODULE_LEGACY_LIFETIME -D V8_ADVANCED_BIGINT_ALGORITHMS -D ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/v8 -I ../deps/v8/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/inspector-generated-output-root -I ../deps/v8/third_party/inspector_protocol -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/generate-bytecode-output-root -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/v8/third_party/zlib -I ../deps/v8/third_party/zlib/google -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-return-type -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/v8/src/execution/execution.cc
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/debug/debug.h"
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/runtime-call-stats-scope.h"
13
14#if V8_ENABLE_WEBASSEMBLY1
15#include "src/compiler/wasm-compiler.h" // Only for static asserts.
16#include "src/wasm/code-space-access.h"
17#include "src/wasm/wasm-engine.h"
18#endif // V8_ENABLE_WEBASSEMBLY
19
20namespace v8 {
21namespace internal {
22
23namespace {
24
25Handle<Object> NormalizeReceiver(Isolate* isolate, Handle<Object> receiver) {
26 // Convert calls on global objects to be calls on the global
27 // receiver instead to avoid having a 'this' pointer which refers
28 // directly to a global object.
29 if (receiver->IsJSGlobalObject()) {
30 return handle(Handle<JSGlobalObject>::cast(receiver)->global_proxy(),
31 isolate);
32 }
33 return receiver;
34}
35
36struct InvokeParams {
37 static InvokeParams SetUpForNew(Isolate* isolate, Handle<Object> constructor,
38 Handle<Object> new_target, int argc,
39 Handle<Object>* argv);
40
41 static InvokeParams SetUpForCall(Isolate* isolate, Handle<Object> callable,
42 Handle<Object> receiver, int argc,
43 Handle<Object>* argv);
44
45 static InvokeParams SetUpForTryCall(
46 Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
47 int argc, Handle<Object>* argv,
48 Execution::MessageHandling message_handling,
49 MaybeHandle<Object>* exception_out, bool reschedule_terminate);
50
51 static InvokeParams SetUpForRunMicrotasks(Isolate* isolate,
52 MicrotaskQueue* microtask_queue,
53 MaybeHandle<Object>* exception_out);
54
55 bool IsScript() const {
56 if (!target->IsJSFunction()) return false;
57 Handle<JSFunction> function = Handle<JSFunction>::cast(target);
58 return function->shared().is_script();
59 }
60
61 Handle<FixedArray> GetAndResetHostDefinedOptions() {
62 DCHECK(IsScript())((void) 0);
63 DCHECK_EQ(argc, 1)((void) 0);
64 auto options = Handle<FixedArray>::cast(argv[0]);
12
Forming reference to null pointer
65 argv = nullptr;
66 argc = 0;
67 return options;
68 }
69
70 Handle<Object> target;
71 Handle<Object> receiver;
72 int argc;
73 Handle<Object>* argv;
74 Handle<Object> new_target;
75
76 MicrotaskQueue* microtask_queue;
77
78 Execution::MessageHandling message_handling;
79 MaybeHandle<Object>* exception_out;
80
81 bool is_construct;
82 Execution::Target execution_target;
83 bool reschedule_terminate;
84};
85
86// static
87InvokeParams InvokeParams::SetUpForNew(Isolate* isolate,
88 Handle<Object> constructor,
89 Handle<Object> new_target, int argc,
90 Handle<Object>* argv) {
91 InvokeParams params;
92 params.target = constructor;
93 params.receiver = isolate->factory()->undefined_value();
94 DCHECK(!params.IsScript())((void) 0);
95 params.argc = argc;
96 params.argv = argv;
97 params.new_target = new_target;
98 params.microtask_queue = nullptr;
99 params.message_handling = Execution::MessageHandling::kReport;
100 params.exception_out = nullptr;
101 params.is_construct = true;
102 params.execution_target = Execution::Target::kCallable;
103 params.reschedule_terminate = true;
104 return params;
105}
106
107// static
108InvokeParams InvokeParams::SetUpForCall(Isolate* isolate,
109 Handle<Object> callable,
110 Handle<Object> receiver, int argc,
111 Handle<Object>* argv) {
112 InvokeParams params;
113 params.target = callable;
114 params.receiver = NormalizeReceiver(isolate, receiver);
115 // Check for host-defined options argument for scripts.
116 DCHECK_IMPLIES(params.IsScript(), argc == 1)((void) 0);
117 DCHECK_IMPLIES(params.IsScript(), argv[0]->IsFixedArray())((void) 0);
118 params.argc = argc;
119 params.argv = argv;
120 params.new_target = isolate->factory()->undefined_value();
121 params.microtask_queue = nullptr;
122 params.message_handling = Execution::MessageHandling::kReport;
123 params.exception_out = nullptr;
124 params.is_construct = false;
125 params.execution_target = Execution::Target::kCallable;
126 params.reschedule_terminate = true;
127 return params;
128}
129
130// static
131InvokeParams InvokeParams::SetUpForTryCall(
132 Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
133 int argc, Handle<Object>* argv, Execution::MessageHandling message_handling,
134 MaybeHandle<Object>* exception_out, bool reschedule_terminate) {
135 InvokeParams params;
136 params.target = callable;
137 params.receiver = NormalizeReceiver(isolate, receiver);
138 // Check for host-defined options argument for scripts.
139 DCHECK_IMPLIES(params.IsScript(), argc == 1)((void) 0);
140 DCHECK_IMPLIES(params.IsScript(), argv[0]->IsFixedArray())((void) 0);
141 params.argc = argc;
142 params.argv = argv;
143 params.new_target = isolate->factory()->undefined_value();
144 params.microtask_queue = nullptr;
145 params.message_handling = message_handling;
146 params.exception_out = exception_out;
147 params.is_construct = false;
148 params.execution_target = Execution::Target::kCallable;
149 params.reschedule_terminate = reschedule_terminate;
150 return params;
151}
152
153// static
154InvokeParams InvokeParams::SetUpForRunMicrotasks(
155 Isolate* isolate, MicrotaskQueue* microtask_queue,
156 MaybeHandle<Object>* exception_out) {
157 auto undefined = isolate->factory()->undefined_value();
158 InvokeParams params;
159 params.target = undefined;
160 params.receiver = undefined;
161 params.argc = 0;
162 params.argv = nullptr;
163 params.new_target = undefined;
164 params.microtask_queue = microtask_queue;
165 params.message_handling = Execution::MessageHandling::kReport;
166 params.exception_out = exception_out;
167 params.is_construct = false;
168 params.execution_target = Execution::Target::kRunMicrotasks;
169 params.reschedule_terminate = true;
170 return params;
2
Null pointer value stored to field 'argv'
171}
172
173Handle<CodeT> JSEntry(Isolate* isolate, Execution::Target execution_target,
174 bool is_construct) {
175 if (is_construct) {
176 DCHECK_EQ(Execution::Target::kCallable, execution_target)((void) 0);
177 return BUILTIN_CODE(isolate, JSConstructEntry)(isolate)->builtins()->code_handle(i::Builtin::kJSConstructEntry
)
;
178 } else if (execution_target == Execution::Target::kCallable) {
179 DCHECK(!is_construct)((void) 0);
180 return BUILTIN_CODE(isolate, JSEntry)(isolate)->builtins()->code_handle(i::Builtin::kJSEntry
)
;
181 } else if (execution_target == Execution::Target::kRunMicrotasks) {
182 DCHECK(!is_construct)((void) 0);
183 return BUILTIN_CODE(isolate, JSRunMicrotasksEntry)(isolate)->builtins()->code_handle(i::Builtin::kJSRunMicrotasksEntry
)
;
184 }
185 UNREACHABLE()V8_Fatal("unreachable code");
186}
187
188MaybeHandle<Context> NewScriptContext(Isolate* isolate,
189 Handle<JSFunction> function,
190 Handle<FixedArray> host_defined_options) {
191 // TODO(cbruni, 1244145): Use passed in host_defined_options.
192 // Creating a script context is a side effect, so abort if that's not
193 // allowed.
194 if (isolate->debug_execution_mode() == DebugInfo::kSideEffects) {
195 isolate->Throw(*isolate->factory()->NewEvalError(
196 MessageTemplate::kNoSideEffectDebugEvaluate));
197 return MaybeHandle<Context>();
198 }
199 SaveAndSwitchContext save(isolate, function->context());
200 SharedFunctionInfo sfi = function->shared();
201 Handle<Script> script(Script::cast(sfi.script()), isolate);
202 Handle<ScopeInfo> scope_info(sfi.scope_info(), isolate);
203 Handle<NativeContext> native_context(NativeContext::cast(function->context()),
204 isolate);
205 Handle<JSGlobalObject> global_object(native_context->global_object(),
206 isolate);
207 Handle<ScriptContextTable> script_context(
208 native_context->script_context_table(), isolate);
209
210 // Find name clashes.
211 for (auto it : ScopeInfo::IterateLocalNames(scope_info)) {
212 Handle<String> name(it->name(), isolate);
213 VariableMode mode = scope_info->ContextLocalMode(it->index());
214 VariableLookupResult lookup;
215 if (script_context->Lookup(name, &lookup)) {
216 if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
217 Handle<Context> context = ScriptContextTable::GetContext(
218 isolate, script_context, lookup.context_index);
219 // If we are trying to re-declare a REPL-mode let as a let or REPL-mode
220 // const as a const, allow it.
221 if (!(((mode == VariableMode::kLet &&
222 lookup.mode == VariableMode::kLet) ||
223 (mode == VariableMode::kConst &&
224 lookup.mode == VariableMode::kConst)) &&
225 scope_info->IsReplModeScope() &&
226 context->scope_info().IsReplModeScope())) {
227 // ES#sec-globaldeclarationinstantiation 5.b:
228 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
229 // exception.
230 MessageLocation location(script, 0, 1);
231 return isolate->ThrowAt<Context>(
232 isolate->factory()->NewSyntaxError(
233 MessageTemplate::kVarRedeclaration, name),
234 &location);
235 }
236 }
237 }
238
239 if (IsLexicalVariableMode(mode)) {
240 LookupIterator it(isolate, global_object, name, global_object,
241 LookupIterator::OWN_SKIP_INTERCEPTOR);
242 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
243 // Can't fail since the we looking up own properties on the global object
244 // skipping interceptors.
245 CHECK(!maybe.IsNothing())do { if ((__builtin_expect(!!(!(!maybe.IsNothing())), 0))) { V8_Fatal
("Check failed: %s.", "!maybe.IsNothing()"); } } while (false
)
;
246 if ((maybe.FromJust() & DONT_DELETE) != 0) {
247 // ES#sec-globaldeclarationinstantiation 5.a:
248 // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
249 // exception.
250 // ES#sec-globaldeclarationinstantiation 5.d:
251 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
252 MessageLocation location(script, 0, 1);
253 return isolate->ThrowAt<Context>(
254 isolate->factory()->NewSyntaxError(
255 MessageTemplate::kVarRedeclaration, name),
256 &location);
257 }
258
259 JSGlobalObject::InvalidatePropertyCell(global_object, name);
260 }
261 }
262
263 Handle<Context> result =
264 isolate->factory()->NewScriptContext(native_context, scope_info);
265
266 result->Initialize(isolate);
267 // In REPL mode, we are allowed to add/modify let/const variables.
268 // We use the previous defined script context for those.
269 const bool ignore_duplicates = scope_info->IsReplModeScope();
270 Handle<ScriptContextTable> new_script_context_table =
271 ScriptContextTable::Extend(isolate, script_context, result,
272 ignore_duplicates);
273 native_context->synchronized_set_script_context_table(
274 *new_script_context_table);
275 return result;
276}
277
278V8_WARN_UNUSED_RESULT__attribute__((warn_unused_result)) MaybeHandle<Object> Invoke(Isolate* isolate,
279 const InvokeParams& params) {
280 RCS_SCOPE(isolate, RuntimeCallCounterId::kInvoke);
281 DCHECK(!params.receiver->IsJSGlobalObject())((void) 0);
282 DCHECK_LE(params.argc, FixedArray::kMaxLength)((void) 0);
283
284#if V8_ENABLE_WEBASSEMBLY1
285 // When executing JS code, there should be no {CodeSpaceWriteScope} open.
286 DCHECK(!wasm::CodeSpaceWriteScope::IsInScope())((void) 0);
287 // If we have PKU support for Wasm, ensure that code is currently write
288 // protected for this thread.
289 DCHECK_IMPLIES(wasm::GetWasmCodeManager()->HasMemoryProtectionKeySupport(),((void) 0)
290 !wasm::GetWasmCodeManager()->MemoryProtectionKeyWritable())((void) 0);
291#endif // V8_ENABLE_WEBASSEMBLY
292
293#ifdef USE_SIMULATOR
294 // Simulators use separate stacks for C++ and JS. JS stack overflow checks
295 // are performed whenever a JS function is called. However, it can be the case
296 // that the C++ stack grows faster than the JS stack, resulting in an overflow
297 // there. Add a check here to make that less likely.
298 StackLimitCheck check(isolate);
299 if (check.HasOverflowed()) {
300 isolate->StackOverflow();
301 if (params.message_handling == Execution::MessageHandling::kReport) {
302 isolate->ReportPendingMessages();
303 }
304 return MaybeHandle<Object>();
305 }
306#endif
307
308 // api callbacks can be called directly, unless we want to take the detour
309 // through JS to set up a frame for break-at-entry.
310 if (params.target->IsJSFunction()) {
8
Taking true branch
311 Handle<JSFunction> function = Handle<JSFunction>::cast(params.target);
312 if ((!params.is_construct
8.1
Field 'is_construct' is false
|| function->IsConstructor()) &&
9
Taking false branch
313 function->shared().IsApiFunction() &&
314 !function->shared().BreakAtEntry()) {
315 SaveAndSwitchContext save(isolate, function->context());
316 DCHECK(function->context().global_object().IsJSGlobalObject())((void) 0);
317
318 Handle<Object> receiver = params.is_construct
319 ? isolate->factory()->the_hole_value()
320 : params.receiver;
321 auto value = Builtins::InvokeApiFunction(
322 isolate, params.is_construct, function, receiver, params.argc,
323 params.argv, Handle<HeapObject>::cast(params.new_target));
324 bool has_exception = value.is_null();
325 DCHECK(has_exception == isolate->has_pending_exception())((void) 0);
326 if (has_exception) {
327 if (params.message_handling == Execution::MessageHandling::kReport) {
328 isolate->ReportPendingMessages();
329 }
330 return MaybeHandle<Object>();
331 } else {
332 isolate->clear_pending_message();
333 }
334 return value;
335 }
336#ifdef DEBUG
337 if (function->shared().is_script()) {
338 DCHECK(params.IsScript())((void) 0);
339 DCHECK(params.receiver->IsJSGlobalProxy())((void) 0);
340 DCHECK_EQ(params.argc, 1)((void) 0);
341 DCHECK(params.argv[0]->IsFixedArray())((void) 0);
342 } else {
343 DCHECK(!params.IsScript())((void) 0);
344 }
345#endif
346 // Set up a ScriptContext when running scripts that need it.
347 if (function->shared().needs_script_context()) {
10
Taking true branch
348 Handle<Context> context;
349 Handle<FixedArray> host_defined_options =
350 const_cast<InvokeParams&>(params).GetAndResetHostDefinedOptions();
11
Calling 'InvokeParams::GetAndResetHostDefinedOptions'
351 if (!NewScriptContext(isolate, function, host_defined_options)
352 .ToHandle(&context)) {
353 if (params.message_handling == Execution::MessageHandling::kReport) {
354 isolate->ReportPendingMessages();
355 }
356 return MaybeHandle<Object>();
357 }
358
359 // We mutate the context if we allocate a script context. This is
360 // guaranteed to only happen once in a native context since scripts will
361 // always produce name clashes with themselves.
362 function->set_context(*context);
363 }
364 }
365
366 // Entering JavaScript.
367 VMState<JS> state(isolate);
368 CHECK(AllowJavascriptExecution::IsAllowed(isolate))do { if ((__builtin_expect(!!(!(AllowJavascriptExecution::IsAllowed
(isolate))), 0))) { V8_Fatal("Check failed: %s.", "AllowJavascriptExecution::IsAllowed(isolate)"
); } } while (false)
;
369 if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
370 isolate->ThrowIllegalOperation();
371 if (params.message_handling == Execution::MessageHandling::kReport) {
372 isolate->ReportPendingMessages();
373 }
374 return MaybeHandle<Object>();
375 }
376 if (!DumpOnJavascriptExecution::IsAllowed(isolate)) {
377 V8::GetCurrentPlatform()->DumpWithoutCrashing();
378 return isolate->factory()->undefined_value();
379 }
380
381 if (params.execution_target == Execution::Target::kCallable) {
382 Handle<Context> context = isolate->native_context();
383 if (!context->script_execution_callback().IsUndefined(isolate)) {
384 v8::Context::AbortScriptExecutionCallback callback =
385 v8::ToCData<v8::Context::AbortScriptExecutionCallback>(
386 context->script_execution_callback());
387 v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate);
388 v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
389 callback(api_isolate, api_context);
390 DCHECK(!isolate->has_scheduled_exception())((void) 0);
391 // Always throw an exception to abort execution, if callback exists.
392 isolate->ThrowIllegalOperation();
393 return MaybeHandle<Object>();
394 }
395 }
396
397 // Placeholder for return value.
398 Object value;
399 Handle<CodeT> code =
400 JSEntry(isolate, params.execution_target, params.is_construct);
401 {
402 // Save and restore context around invocation and block the
403 // allocation of handles without explicit handle scopes.
404 SaveContext save(isolate);
405 SealHandleScope shs(isolate);
406
407 if (FLAG_clear_exceptions_on_js_entry) isolate->clear_pending_exception();
408
409 if (params.execution_target == Execution::Target::kCallable) {
410 // clang-format off
411 // {new_target}, {target}, {receiver}, return value: tagged pointers
412 // {argv}: pointer to array of tagged pointers
413 using JSEntryFunction = GeneratedCode<Address(
414 Address root_register_value, Address new_target, Address target,
415 Address receiver, intptr_t argc, Address** argv)>;
416 // clang-format on
417 JSEntryFunction stub_entry =
418 JSEntryFunction::FromAddress(isolate, code->InstructionStart());
419
420 Address orig_func = params.new_target->ptr();
421 Address func = params.target->ptr();
422 Address recv = params.receiver->ptr();
423 Address** argv = reinterpret_cast<Address**>(params.argv);
424 RCS_SCOPE(isolate, RuntimeCallCounterId::kJS_Execution);
425 value = Object(stub_entry.Call(isolate->isolate_data()->isolate_root(),
426 orig_func, func, recv,
427 JSParameterCount(params.argc), argv));
428 } else {
429 DCHECK_EQ(Execution::Target::kRunMicrotasks, params.execution_target)((void) 0);
430
431 // clang-format off
432 // return value: tagged pointers
433 // {microtask_queue}: pointer to a C++ object
434 using JSEntryFunction = GeneratedCode<Address(
435 Address root_register_value, MicrotaskQueue* microtask_queue)>;
436 // clang-format on
437 JSEntryFunction stub_entry =
438 JSEntryFunction::FromAddress(isolate, code->InstructionStart());
439
440 RCS_SCOPE(isolate, RuntimeCallCounterId::kJS_Execution);
441 value = Object(stub_entry.Call(isolate->isolate_data()->isolate_root(),
442 params.microtask_queue));
443 }
444 }
445
446#ifdef VERIFY_HEAP
447 if (FLAG_verify_heap) {
448 value.ObjectVerify(isolate);
449 }
450#endif
451
452 // Update the pending exception flag and return the value.
453 bool has_exception = value.IsException(isolate);
454 DCHECK(has_exception == isolate->has_pending_exception())((void) 0);
455 if (has_exception) {
456 if (params.message_handling == Execution::MessageHandling::kReport) {
457 isolate->ReportPendingMessages();
458 }
459 return MaybeHandle<Object>();
460 } else {
461 isolate->clear_pending_message();
462 }
463
464 return Handle<Object>(value, isolate);
465}
466
467MaybeHandle<Object> InvokeWithTryCatch(Isolate* isolate,
468 const InvokeParams& params) {
469 bool is_termination = false;
470 MaybeHandle<Object> maybe_result;
471 if (params.exception_out != nullptr) {
5
Assuming the condition is false
6
Taking false branch
472 *params.exception_out = MaybeHandle<Object>();
473 }
474 DCHECK_IMPLIES(((void) 0)
475 params.message_handling == Execution::MessageHandling::kKeepPending,((void) 0)
476 params.exception_out == nullptr)((void) 0);
477 // Enter a try-block while executing the JavaScript code. To avoid
478 // duplicate error printing it must be non-verbose. Also, to avoid
479 // creating message objects during stack overflow we shouldn't
480 // capture messages.
481 {
482 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
483 catcher.SetVerbose(false);
484 catcher.SetCaptureMessage(false);
485
486 maybe_result = Invoke(isolate, params);
7
Calling 'Invoke'
487
488 if (maybe_result.is_null()) {
489 DCHECK(isolate->has_pending_exception())((void) 0);
490 if (isolate->pending_exception() ==
491 ReadOnlyRoots(isolate).termination_exception()) {
492 is_termination = true;
493 } else {
494 if (params.exception_out != nullptr) {
495 DCHECK(catcher.HasCaught())((void) 0);
496 DCHECK(isolate->external_caught_exception())((void) 0);
497 *params.exception_out = v8::Utils::OpenHandle(*catcher.Exception());
498 }
499 if (params.message_handling == Execution::MessageHandling::kReport) {
500 isolate->OptionalRescheduleException(true);
501 }
502 }
503 }
504 }
505
506 if (is_termination && params.reschedule_terminate) {
507 // Reschedule terminate execution exception.
508 isolate->OptionalRescheduleException(false);
509 }
510
511 return maybe_result;
512}
513
514} // namespace
515
516// static
517MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
518 Handle<Object> receiver, int argc,
519 Handle<Object> argv[]) {
520 // Use Execution::CallScript instead for scripts:
521 DCHECK_IMPLIES(callable->IsJSFunction(),((void) 0)
522 !JSFunction::cast(*callable).shared().is_script())((void) 0);
523 return Invoke(isolate, InvokeParams::SetUpForCall(isolate, callable, receiver,
524 argc, argv));
525}
526
527// static
528MaybeHandle<Object> Execution::CallScript(Isolate* isolate,
529 Handle<JSFunction> script_function,
530 Handle<Object> receiver,
531 Handle<Object> host_defined_options) {
532 DCHECK(script_function->shared().is_script())((void) 0);
533 DCHECK(receiver->IsJSGlobalProxy() || receiver->IsJSGlobalObject())((void) 0);
534 return Invoke(
535 isolate, InvokeParams::SetUpForCall(isolate, script_function, receiver, 1,
536 &host_defined_options));
537}
538
539MaybeHandle<Object> Execution::CallBuiltin(Isolate* isolate,
540 Handle<JSFunction> builtin,
541 Handle<Object> receiver, int argc,
542 Handle<Object> argv[]) {
543 DCHECK(builtin->code().is_builtin())((void) 0);
544 DisableBreak no_break(isolate->debug());
545 return Invoke(isolate, InvokeParams::SetUpForCall(isolate, builtin, receiver,
546 argc, argv));
547}
548
549// static
550MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
551 int argc, Handle<Object> argv[]) {
552 return New(isolate, constructor, constructor, argc, argv);
553}
554
555// static
556MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
557 Handle<Object> new_target, int argc,
558 Handle<Object> argv[]) {
559 return Invoke(isolate, InvokeParams::SetUpForNew(isolate, constructor,
560 new_target, argc, argv));
561}
562
563// static
564MaybeHandle<Object> Execution::TryCallScript(
565 Isolate* isolate, Handle<JSFunction> script_function,
566 Handle<Object> receiver, Handle<FixedArray> host_defined_options,
567 MessageHandling message_handling, MaybeHandle<Object>* exception_out,
568 bool reschedule_terminate) {
569 DCHECK(script_function->shared().is_script())((void) 0);
570 DCHECK(receiver->IsJSGlobalProxy() || receiver->IsJSGlobalObject())((void) 0);
571 Handle<Object> argument = host_defined_options;
572 return InvokeWithTryCatch(
573 isolate, InvokeParams::SetUpForTryCall(
574 isolate, script_function, receiver, 1, &argument,
575 message_handling, exception_out, reschedule_terminate));
576}
577
578// static
579MaybeHandle<Object> Execution::TryCall(
580 Isolate* isolate, Handle<Object> callable, Handle<Object> receiver,
581 int argc, Handle<Object> argv[], MessageHandling message_handling,
582 MaybeHandle<Object>* exception_out, bool reschedule_terminate) {
583 // Use Execution::TryCallScript instead for scripts:
584 DCHECK_IMPLIES(callable->IsJSFunction(),((void) 0)
585 !JSFunction::cast(*callable).shared().is_script())((void) 0);
586 return InvokeWithTryCatch(
587 isolate, InvokeParams::SetUpForTryCall(
588 isolate, callable, receiver, argc, argv, message_handling,
589 exception_out, reschedule_terminate));
590}
591
592// static
593MaybeHandle<Object> Execution::TryRunMicrotasks(
594 Isolate* isolate, MicrotaskQueue* microtask_queue,
595 MaybeHandle<Object>* exception_out) {
596 return InvokeWithTryCatch(
4
Calling 'InvokeWithTryCatch'
597 isolate, InvokeParams::SetUpForRunMicrotasks(isolate, microtask_queue,
1
Calling 'InvokeParams::SetUpForRunMicrotasks'
3
Returning from 'InvokeParams::SetUpForRunMicrotasks'
598 exception_out));
599}
600
601struct StackHandlerMarker {
602 Address next;
603 Address padding;
604};
605STATIC_ASSERT(offsetof(StackHandlerMarker, next) ==static_assert(__builtin_offsetof(StackHandlerMarker, next) ==
StackHandlerConstants::kNextOffset, "offsetof(StackHandlerMarker, next) == StackHandlerConstants::kNextOffset"
)
606 StackHandlerConstants::kNextOffset)static_assert(__builtin_offsetof(StackHandlerMarker, next) ==
StackHandlerConstants::kNextOffset, "offsetof(StackHandlerMarker, next) == StackHandlerConstants::kNextOffset"
)
;
607STATIC_ASSERT(offsetof(StackHandlerMarker, padding) ==static_assert(__builtin_offsetof(StackHandlerMarker, padding)
== StackHandlerConstants::kPaddingOffset, "offsetof(StackHandlerMarker, padding) == StackHandlerConstants::kPaddingOffset"
)
608 StackHandlerConstants::kPaddingOffset)static_assert(__builtin_offsetof(StackHandlerMarker, padding)
== StackHandlerConstants::kPaddingOffset, "offsetof(StackHandlerMarker, padding) == StackHandlerConstants::kPaddingOffset"
)
;
609STATIC_ASSERT(sizeof(StackHandlerMarker) == StackHandlerConstants::kSize)static_assert(sizeof(StackHandlerMarker) == StackHandlerConstants
::kSize, "sizeof(StackHandlerMarker) == StackHandlerConstants::kSize"
)
;
610
611#if V8_ENABLE_WEBASSEMBLY1
612void Execution::CallWasm(Isolate* isolate, Handle<CodeT> wrapper_code,
613 Address wasm_call_target, Handle<Object> object_ref,
614 Address packed_args) {
615 using WasmEntryStub = GeneratedCode<Address(
616 Address target, Address object_ref, Address argv, Address c_entry_fp)>;
617 WasmEntryStub stub_entry =
618 WasmEntryStub::FromAddress(isolate, wrapper_code->InstructionStart());
619
620 // Save and restore context around invocation and block the
621 // allocation of handles without explicit handle scopes.
622 SaveContext save(isolate);
623 SealHandleScope shs(isolate);
624
625 Address saved_c_entry_fp = *isolate->c_entry_fp_address();
626 Address saved_js_entry_sp = *isolate->js_entry_sp_address();
627 if (saved_js_entry_sp == kNullAddress) {
628 *isolate->js_entry_sp_address() = GetCurrentStackPosition();
629 }
630 StackHandlerMarker stack_handler;
631 stack_handler.next = isolate->thread_local_top()->handler_;
632#ifdef V8_USE_ADDRESS_SANITIZER
633 stack_handler.padding = GetCurrentStackPosition();
634#else
635 stack_handler.padding = 0;
636#endif
637 isolate->thread_local_top()->handler_ =
638 reinterpret_cast<Address>(&stack_handler);
639 trap_handler::SetThreadInWasm();
640
641 {
642 RCS_SCOPE(isolate, RuntimeCallCounterId::kJS_Execution);
643 STATIC_ASSERT(compiler::CWasmEntryParameters::kCodeEntry == 0)static_assert(compiler::CWasmEntryParameters::kCodeEntry == 0
, "compiler::CWasmEntryParameters::kCodeEntry == 0")
;
644 STATIC_ASSERT(compiler::CWasmEntryParameters::kObjectRef == 1)static_assert(compiler::CWasmEntryParameters::kObjectRef == 1
, "compiler::CWasmEntryParameters::kObjectRef == 1")
;
645 STATIC_ASSERT(compiler::CWasmEntryParameters::kArgumentsBuffer == 2)static_assert(compiler::CWasmEntryParameters::kArgumentsBuffer
== 2, "compiler::CWasmEntryParameters::kArgumentsBuffer == 2"
)
;
646 STATIC_ASSERT(compiler::CWasmEntryParameters::kCEntryFp == 3)static_assert(compiler::CWasmEntryParameters::kCEntryFp == 3,
"compiler::CWasmEntryParameters::kCEntryFp == 3")
;
647 Address result = stub_entry.Call(wasm_call_target, object_ref->ptr(),
648 packed_args, saved_c_entry_fp);
649 if (result != kNullAddress) {
650 isolate->set_pending_exception(Object(result));
651 }
652 }
653
654 // If there was an exception, then the thread-in-wasm flag is cleared
655 // already.
656 if (trap_handler::IsThreadInWasm()) {
657 trap_handler::ClearThreadInWasm();
658 }
659 isolate->thread_local_top()->handler_ = stack_handler.next;
660 if (saved_js_entry_sp == kNullAddress) {
661 *isolate->js_entry_sp_address() = saved_js_entry_sp;
662 }
663 *isolate->c_entry_fp_address() = saved_c_entry_fp;
664}
665#endif // V8_ENABLE_WEBASSEMBLY
666
667} // namespace internal
668} // namespace v8