chromium/v8/src/execution/isolate.h

// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_EXECUTION_ISOLATE_H_
#define V8_EXECUTION_ISOLATE_H_

#include <atomic>
#include <cstddef>
#include <functional>
#include <list>
#include <memory>
#include <optional>
#include <queue>
#include <unordered_map>
#include <vector>

#include "include/v8-context.h"
#include "include/v8-internal.h"
#include "include/v8-isolate.h"
#include "include/v8-metrics.h"
#include "include/v8-snapshot.h"
#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/base/platform/platform-posix.h"
#include "src/builtins/builtins.h"
#include "src/common/globals.h"
#include "src/debug/interface-types.h"
#include "src/execution/execution.h"
#include "src/execution/futex-emulation.h"
#include "src/execution/isolate-data.h"
#include "src/execution/messages.h"
#include "src/execution/shared-mutex-guard-if-off-thread.h"
#include "src/execution/stack-guard.h"
#include "src/handles/handles.h"
#include "src/handles/traced-handles.h"
#include "src/heap/factory.h"
#include "src/heap/heap.h"
#include "src/heap/read-only-heap.h"
#include "src/init/isolate-group.h"
#include "src/objects/code.h"
#include "src/objects/contexts.h"
#include "src/objects/debug-objects.h"
#include "src/objects/js-objects.h"
#include "src/objects/tagged.h"
#include "src/runtime/runtime.h"
#include "src/sandbox/code-pointer-table.h"
#include "src/sandbox/external-pointer-table.h"
#include "src/sandbox/trusted-pointer-table.h"
#include "src/utils/allocation.h"

#ifdef DEBUG
#include "src/runtime/runtime-utils.h"
#endif

#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/stacks.h"
#endif

#ifdef V8_INTL_SUPPORT
#include "unicode/uversion.h"  // Define U_ICU_NAMESPACE.
namespace U_ICU_NAMESPACE {
class UMemory;
}  // namespace U_ICU_NAMESPACE
#endif  // V8_INTL_SUPPORT

#if USE_SIMULATOR
#include "src/execution/encoded-c-signature.h"
namespace v8 {
namespace internal {
class SimulatorData;
}
}  // namespace v8
#endif

namespace v8_inspector {
class V8Inspector;
}  // namespace v8_inspector

namespace v8 {

class EmbedderState;

namespace base {
class RandomNumberGenerator;
}  // namespace base

namespace bigint {
class Processor;
}

namespace debug {
class ConsoleDelegate;
class AsyncEventDelegate;
}  // namespace debug

namespace internal {

void DefaultWasmAsyncResolvePromiseCallback(
    v8::Isolate* isolate, v8::Local<v8::Context> context,
    v8::Local<v8::Promise::Resolver> resolver,
    v8::Local<v8::Value> compilation_result, WasmAsyncSuccess success);

namespace heap {
class HeapTester;
}  // namespace heap

namespace maglev {
class MaglevConcurrentDispatcher;
}  // namespace maglev

class AddressToIndexHashMap;
class AstStringConstants;
class Bootstrapper;
class BuiltinsConstantsTableBuilder;
class CancelableTaskManager;
class Logger;
class CodeTracer;
class CommonFrame;
class CompilationCache;
class CompilationStatistics;
class Counters;
class Debug;
class Deoptimizer;
class DescriptorLookupCache;
class EmbeddedFileWriterInterface;
class EternalHandles;
class GlobalHandles;
class GlobalSafepoint;
class HandleScopeImplementer;
class HeapObjectToIndexHashMap;
class HeapProfiler;
class InnerPointerToCodeCache;
class LazyCompileDispatcher;
class LocalIsolate;
class V8FileLogger;
class MaterializedObjectStore;
class Microtask;
class MicrotaskQueue;
class OptimizingCompileDispatcher;
class PersistentHandles;
class PersistentHandlesList;
class ReadOnlyArtifacts;
class RegExpStack;
class RootVisitor;
class SetupIsolateDelegate;
class SharedStructTypeRegistry;
class Simulator;
class SnapshotData;
class StackFrame;
class StringForwardingTable;
class StringTable;
class StubCache;
class ThreadManager;
class ThreadState;
class ThreadVisitor;  // Defined in v8threads.h
class TieringManager;
class TracingCpuProfilerImpl;
class UnicodeCache;
struct ManagedPtrDestructor;

template <StateTag Tag>
class VMState;

namespace baseline {
class BaselineBatchCompiler;
}  // namespace baseline

namespace interpreter {
class Interpreter;
}  // namespace interpreter

namespace compiler {
class NodeObserver;
class PerIsolateCompilerCache;
namespace turboshaft {
class WasmRevecVerifier;
}  // namespace turboshaft
}  // namespace compiler

namespace win64_unwindinfo {
class BuiltinUnwindInfo;
}  // namespace win64_unwindinfo

namespace metrics {
class Recorder;
}  // namespace metrics

namespace wasm {

#if V8_ENABLE_DRUMBRAKE
class WasmExecutionTimer;
#endif  // V8_ENABLE_DRUMBRAKE
class WasmCodeLookupCache;
class WasmOrphanedGlobalHandle;
}

namespace detail {
class WaiterQueueNode;
}  // namespace detail

#define RETURN_FAILURE_IF_EXCEPTION(isolate)

#define RETURN_FAILURE_IF_EXCEPTION_DETECTOR(isolate, detector)

// Macros for MaybeHandle.

#define RETURN_VALUE_IF_EXCEPTION(isolate, value)

#define RETURN_VALUE_IF_EXCEPTION_DETECTOR(isolate, detector, value)

#define RETURN_EXCEPTION_IF_EXCEPTION(isolate)

#define MAYBE_RETURN_ON_EXCEPTION_VALUE(isolate, call, value)

/**
 * RETURN_RESULT_OR_FAILURE is used in functions with return type Object (such
 * as "RUNTIME_FUNCTION(...) {...}" or "BUILTIN(...) {...}" ) to return either
 * the contents of a MaybeHandle<X>, or the "exception" sentinel value.
 * Example usage:
 *
 * RUNTIME_FUNCTION(Runtime_Func) {
 *   ...
 *   RETURN_RESULT_OR_FAILURE(
 *       isolate,
 *       FunctionWithReturnTypeMaybeHandleX(...));
 * }
 *
 * If inside a function with return type MaybeHandle<X> use RETURN_ON_EXCEPTION
 * instead.
 * If inside a function with return type Handle<X>, or Maybe<X> use
 * RETURN_ON_EXCEPTION_VALUE instead.
 */
#define RETURN_RESULT_OR_FAILURE(isolate, call)

#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)

#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)

#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)

#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)

#define THROW_NEW_ERROR_RETURN_VALUE(isolate, call, value)

#define THROW_NEW_ERROR(isolate, call)

/**
 * RETURN_ON_EXCEPTION_VALUE conditionally returns the given value when the
 * given MaybeHandle is empty. It is typically used in functions with return
 * type Maybe<X> or Handle<X>. Example usage:
 *
 * Handle<X> Func() {
 *   ...
 *   RETURN_ON_EXCEPTION_VALUE(
 *       isolate,
 *       FunctionWithReturnTypeMaybeHandleX(...),
 *       Handle<X>());
 *   // code to handle non exception
 *   ...
 * }
 *
 * Maybe<bool> Func() {
 *   ..
 *   RETURN_ON_EXCEPTION_VALUE(
 *       isolate,
 *       FunctionWithReturnTypeMaybeHandleX(...),
 *       Nothing<bool>);
 *   // code to handle non exception
 *   return Just(true);
 * }
 *
 * If inside a function with return type MaybeHandle<X>, use RETURN_ON_EXCEPTION
 * instead.
 * If inside a function with return type Object, use
 * RETURN_FAILURE_ON_EXCEPTION instead.
 */
#define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)

/**
 * RETURN_FAILURE_ON_EXCEPTION conditionally returns the "exception" sentinel if
 * the given MaybeHandle is empty; so it can only be used in functions with
 * return type Object, such as RUNTIME_FUNCTION(...) {...} or BUILTIN(...)
 * {...}. Example usage:
 *
 * RUNTIME_FUNCTION(Runtime_Func) {
 *   ...
 *   RETURN_FAILURE_ON_EXCEPTION(
 *       isolate,
 *       FunctionWithReturnTypeMaybeHandleX(...));
 *   // code to handle non exception
 *   ...
 * }
 *
 * If inside a function with return type MaybeHandle<X>, use RETURN_ON_EXCEPTION
 * instead.
 * If inside a function with return type Maybe<X> or Handle<X>, use
 * RETURN_ON_EXCEPTION_VALUE instead.
 */
#define RETURN_FAILURE_ON_EXCEPTION(isolate, call)

/**
 * RETURN_ON_EXCEPTION conditionally returns an empty MaybeHandle<T> if the
 * given MaybeHandle is empty. Use it to return immediately from a function with
 * return type MaybeHandle when an exception was thrown. Example usage:
 *
 * MaybeHandle<X> Func() {
 *   ...
 *   RETURN_ON_EXCEPTION(
 *       isolate,
 *       FunctionWithReturnTypeMaybeHandleY(...),
 *       X);
 *   // code to handle non exception
 *   ...
 * }
 *
 * If inside a function with return type Object, use
 * RETURN_FAILURE_ON_EXCEPTION instead.
 * If inside a function with return type
 * Maybe<X> or Handle<X>, use RETURN_ON_EXCEPTION_VALUE instead.
 */
#define RETURN_ON_EXCEPTION(isolate, call)

#define RETURN_FAILURE(isolate, should_throw, call)

#define MAYBE_RETURN(call, value)

#define MAYBE_RETURN_NULL(call)

#define API_ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)

#define MAYBE_RETURN_ON_EXCEPTION_VALUE(isolate, call, value)

#define MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)

#define MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)

#define FOR_WITH_HANDLE_SCOPE(isolate, loop_var_type, init, loop_var,      \
                              limit_check, increment, body)

#define WHILE_WITH_HANDLE_SCOPE(isolate, limit_check, body)

#define FIELD_ACCESSOR

// Controls for manual embedded blob lifecycle management, used by tests and
// mksnapshot.
V8_EXPORT_PRIVATE void DisableEmbeddedBlobRefcounting();
V8_EXPORT_PRIVATE void FreeCurrentEmbeddedBlob();

#ifdef DEBUG

#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
#else

#define ISOLATE_INIT_DEBUG_ARRAY_LIST

#endif

#define ISOLATE_INIT_ARRAY_LIST(V)

using DebugObjectCache = std::vector<Handle<HeapObject>>;

#define ISOLATE_INIT_LIST(V)

#define THREAD_LOCAL_TOP_ACCESSOR

#define THREAD_LOCAL_TOP_ADDRESS

// HiddenFactory exists so Isolate can privately inherit from it without making
// Factory's members available to Isolate directly.
class V8_EXPORT_PRIVATE HiddenFactory : private Factory {};

class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {}};

// The current entered Isolate and its thread data. Do not access these
// directly! Use Isolate::Current and Isolate::CurrentPerIsolateThreadData.
//
// These are outside the Isolate class with extern storage because in clang-cl,
// thread_local is incompatible with dllexport linkage caused by
// V8_EXPORT_PRIVATE being applied to Isolate.
extern thread_local Isolate::PerIsolateThreadData*
    g_current_per_isolate_thread_data_ V8_CONSTINIT;
extern thread_local Isolate* g_current_isolate_ V8_CONSTINIT;

#undef FIELD_ACCESSOR
#undef THREAD_LOCAL_TOP_ACCESSOR
#undef THREAD_LOCAL_TOP_ADDRESS

// SaveContext scopes save the current context on the Isolate on creation, and
// restore it on destruction.
class V8_EXPORT_PRIVATE SaveContext {};

// Like SaveContext, but also switches the Context to a new one in the
// constructor.
class V8_EXPORT_PRIVATE SaveAndSwitchContext : public SaveContext {};

// A scope which sets the given isolate's context to null for its lifetime to
// ensure that code does not make assumptions on a context being available.
class V8_NODISCARD NullContextScope : public SaveAndSwitchContext {};

class AssertNoContextChange {};

class ExecutionAccess {};

// Support for checking for stack-overflows.
class StackLimitCheck {};

// This macro may be used in context that disallows JS execution.
// That is why it checks only for a stack overflow and termination.
#define STACK_CHECK(isolate, result_value)

class StackTraceFailureMessage {};

SharedMutexGuardIfOffThread<Isolate, kIsShared>;

}  // namespace internal
}  // namespace v8

#endif  // V8_EXECUTION_ISOLATE_H_