• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3  // found in the LICENSE file.
4  
5  #include "src/api/api.h"
6  
7  #include <algorithm>  // For min
8  #include <cmath>      // For isnan.
9  #include <limits>
10  #include <sstream>
11  #include <string>
12  #include <utility>  // For move
13  #include <vector>
14  
15  #include "include/v8-callbacks.h"
16  #include "include/v8-cppgc.h"
17  #include "include/v8-date.h"
18  #include "include/v8-embedder-state-scope.h"
19  #include "include/v8-extension.h"
20  #include "include/v8-fast-api-calls.h"
21  #include "include/v8-function.h"
22  #include "include/v8-json.h"
23  #include "include/v8-locker.h"
24  #include "include/v8-primitive-object.h"
25  #include "include/v8-profiler.h"
26  #include "include/v8-unwinder-state.h"
27  #include "include/v8-util.h"
28  #include "include/v8-wasm.h"
29  #include "src/api/api-inl.h"
30  #include "src/api/api-natives.h"
31  #include "src/base/functional.h"
32  #include "src/base/logging.h"
33  #include "src/base/platform/platform.h"
34  #include "src/base/platform/time.h"
35  #include "src/base/safe_conversions.h"
36  #include "src/base/utils/random-number-generator.h"
37  #include "src/baseline/baseline-batch-compiler.h"
38  #include "src/builtins/accessors.h"
39  #include "src/builtins/builtins-utils.h"
40  #include "src/codegen/compiler.h"
41  #include "src/codegen/cpu-features.h"
42  #include "src/codegen/script-details.h"
43  #include "src/common/assert-scope.h"
44  #include "src/common/globals.h"
45  #include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
46  #include "src/date/date.h"
47  #include "src/objects/primitive-heap-object.h"
48  #if V8_ENABLE_WEBASSEMBLY
49  #include "src/debug/debug-wasm-objects.h"
50  #endif  // V8_ENABLE_WEBASSEMBLY
51  #include "src/debug/liveedit.h"
52  #include "src/deoptimizer/deoptimizer.h"
53  #include "src/execution/embedder-state.h"
54  #include "src/execution/execution.h"
55  #include "src/execution/frames-inl.h"
56  #include "src/execution/isolate-inl.h"
57  #include "src/execution/messages.h"
58  #include "src/execution/microtask-queue.h"
59  #include "src/execution/simulator.h"
60  #include "src/execution/v8threads.h"
61  #include "src/execution/vm-state-inl.h"
62  #include "src/handles/global-handles.h"
63  #include "src/handles/persistent-handles.h"
64  #include "src/heap/embedder-tracing.h"
65  #include "src/heap/heap-inl.h"
66  #include "src/heap/heap-write-barrier.h"
67  #include "src/heap/safepoint.h"
68  #include "src/init/bootstrapper.h"
69  #include "src/init/icu_util.h"
70  #include "src/init/startup-data-util.h"
71  #include "src/init/v8.h"
72  #include "src/json/json-parser.h"
73  #include "src/json/json-stringifier.h"
74  #include "src/logging/counters-scopes.h"
75  #include "src/logging/metrics.h"
76  #include "src/logging/runtime-call-stats-scope.h"
77  #include "src/logging/tracing-flags.h"
78  #include "src/numbers/conversions-inl.h"
79  #include "src/objects/api-callbacks.h"
80  #include "src/objects/contexts.h"
81  #include "src/objects/embedder-data-array-inl.h"
82  #include "src/objects/embedder-data-slot-inl.h"
83  #include "src/objects/hash-table-inl.h"
84  #include "src/objects/heap-object.h"
85  #include "src/objects/js-array-buffer-inl.h"
86  #include "src/objects/js-array-inl.h"
87  #include "src/objects/js-collection-inl.h"
88  #include "src/objects/js-promise-inl.h"
89  #include "src/objects/js-regexp-inl.h"
90  #include "src/objects/js-weak-refs-inl.h"
91  #include "src/objects/module-inl.h"
92  #include "src/objects/objects-inl.h"
93  #include "src/objects/oddball.h"
94  #include "src/objects/ordered-hash-table-inl.h"
95  #include "src/objects/property-descriptor.h"
96  #include "src/objects/property-details.h"
97  #include "src/objects/property.h"
98  #include "src/objects/prototype.h"
99  #include "src/objects/shared-function-info.h"
100  #include "src/objects/slots.h"
101  #include "src/objects/smi.h"
102  #include "src/objects/synthetic-module-inl.h"
103  #include "src/objects/templates.h"
104  #include "src/objects/value-serializer.h"
105  #include "src/parsing/parse-info.h"
106  #include "src/parsing/parser.h"
107  #include "src/parsing/pending-compilation-error-handler.h"
108  #include "src/parsing/scanner-character-streams.h"
109  #include "src/profiler/cpu-profiler.h"
110  #include "src/profiler/heap-profiler.h"
111  #include "src/profiler/heap-snapshot-generator-inl.h"
112  #include "src/profiler/profile-generator-inl.h"
113  #include "src/profiler/tick-sample.h"
114  #include "src/regexp/regexp-utils.h"
115  #include "src/runtime/runtime.h"
116  #include "src/sandbox/external-pointer.h"
117  #include "src/sandbox/sandbox.h"
118  #include "src/snapshot/code-serializer.h"
119  #include "src/snapshot/embedded/embedded-data.h"
120  #include "src/snapshot/snapshot.h"
121  #include "src/snapshot/startup-serializer.h"  // For SerializedHandleChecker.
122  #include "src/strings/char-predicates-inl.h"
123  #include "src/strings/string-hasher.h"
124  #include "src/strings/unicode-inl.h"
125  #include "src/tracing/trace-event.h"
126  #include "src/utils/detachable-vector.h"
127  #include "src/utils/version.h"
128  #include "src/web-snapshot/web-snapshot.h"
129  
130  #if V8_ENABLE_WEBASSEMBLY
131  #include "src/trap-handler/trap-handler.h"
132  #include "src/wasm/streaming-decoder.h"
133  #include "src/wasm/value-type.h"
134  #include "src/wasm/wasm-engine.h"
135  #include "src/wasm/wasm-js.h"
136  #include "src/wasm/wasm-objects-inl.h"
137  #include "src/wasm/wasm-result.h"
138  #include "src/wasm/wasm-serialization.h"
139  #endif  // V8_ENABLE_WEBASSEMBLY
140  
141  #if V8_OS_LINUX || V8_OS_DARWIN || V8_OS_FREEBSD
142  #include <signal.h>
143  #include "include/v8-wasm-trap-handler-posix.h"
144  #include "src/trap-handler/handler-inside-posix.h"
145  #endif
146  
147  #if V8_OS_WIN
148  #include <windows.h>
149  
150  // This has to come after windows.h.
151  #include <versionhelpers.h>
152  
153  #include "include/v8-wasm-trap-handler-win.h"
154  #include "src/trap-handler/handler-inside-win.h"
155  #if defined(V8_OS_WIN64)
156  #include "src/base/platform/wrappers.h"
157  #include "src/diagnostics/unwinding-info-win64.h"
158  #endif  // V8_OS_WIN64
159  #endif  // V8_OS_WIN
160  
161  // Has to be the last include (doesn't have include guards):
162  #include "src/api/api-macros.h"
163  
164  #define TRACE_BS(...)                                     \
165    do {                                                    \
166      if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \
167    } while (false)
168  
169  namespace v8 {
170  
171  static OOMErrorCallback g_oom_error_callback = nullptr;
172  
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)173  static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
174                                               i::Handle<i::Script> script) {
175    i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
176    i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
177    i::Handle<i::Object> host_defined_options(script->host_defined_options(),
178                                              isolate);
179    ScriptOriginOptions options(script->origin_options());
180    bool is_wasm = false;
181  #if V8_ENABLE_WEBASSEMBLY
182    is_wasm = script->type() == i::Script::TYPE_WASM;
183  #endif  // V8_ENABLE_WEBASSEMBLY
184    v8::ScriptOrigin origin(
185        reinterpret_cast<v8::Isolate*>(isolate), Utils::ToLocal(scriptName),
186        script->line_offset(), script->column_offset(),
187        options.IsSharedCrossOrigin(), script->id(),
188        Utils::ToLocal(source_map_url), options.IsOpaque(), is_wasm,
189        options.IsModule(), Utils::ToLocal(host_defined_options));
190    return origin;
191  }
192  
HostDefinedOptions() const193  Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
194    // TODO(cbruni, chromium:1244145): remove once migrated to the context.
195    Utils::ApiCheck(!host_defined_options_->IsFixedArray(),
196                    "ScriptOrigin::HostDefinedOptions",
197                    "HostDefinedOptions is not a PrimitiveArray, please use "
198                    "ScriptOrigin::GetHostDefinedOptions()");
199    i::Handle<i::FixedArray> options =
200        Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
201    return Utils::PrimitiveArrayToLocal(options);
202  }
203  
204  // --- E x c e p t i o n   B e h a v i o r ---
205  
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location)206  void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
207    i::V8::FatalProcessOutOfMemory(isolate, location, false);
208  }
209  
210  // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
211  // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location,bool is_heap_oom)212  void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
213                                      bool is_heap_oom) {
214    char last_few_messages[Heap::kTraceRingBufferSize + 1];
215    char js_stacktrace[Heap::kStacktraceBufferSize + 1];
216    i::HeapStats heap_stats;
217  
218    if (isolate == nullptr) {
219      isolate = Isolate::TryGetCurrent();
220    }
221  
222    if (isolate == nullptr) {
223      // If the Isolate is not available for the current thread we cannot retrieve
224      // memory information from the Isolate. Write easy-to-recognize values on
225      // the stack.
226      memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
227      memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
228      memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
229      // Give the embedder a chance to handle the condition. If it doesn't,
230      // just crash.
231      if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
232      FATAL("Fatal process out of memory: %s", location);
233      UNREACHABLE();
234    }
235  
236    memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
237    memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
238  
239    intptr_t start_marker;
240    heap_stats.start_marker = &start_marker;
241    size_t ro_space_size;
242    heap_stats.ro_space_size = &ro_space_size;
243    size_t ro_space_capacity;
244    heap_stats.ro_space_capacity = &ro_space_capacity;
245    size_t new_space_size;
246    heap_stats.new_space_size = &new_space_size;
247    size_t new_space_capacity;
248    heap_stats.new_space_capacity = &new_space_capacity;
249    size_t old_space_size;
250    heap_stats.old_space_size = &old_space_size;
251    size_t old_space_capacity;
252    heap_stats.old_space_capacity = &old_space_capacity;
253    size_t code_space_size;
254    heap_stats.code_space_size = &code_space_size;
255    size_t code_space_capacity;
256    heap_stats.code_space_capacity = &code_space_capacity;
257    size_t map_space_size;
258    heap_stats.map_space_size = &map_space_size;
259    size_t map_space_capacity;
260    heap_stats.map_space_capacity = &map_space_capacity;
261    size_t lo_space_size;
262    heap_stats.lo_space_size = &lo_space_size;
263    size_t code_lo_space_size;
264    heap_stats.code_lo_space_size = &code_lo_space_size;
265    size_t global_handle_count;
266    heap_stats.global_handle_count = &global_handle_count;
267    size_t weak_global_handle_count;
268    heap_stats.weak_global_handle_count = &weak_global_handle_count;
269    size_t pending_global_handle_count;
270    heap_stats.pending_global_handle_count = &pending_global_handle_count;
271    size_t near_death_global_handle_count;
272    heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
273    size_t free_global_handle_count;
274    heap_stats.free_global_handle_count = &free_global_handle_count;
275    size_t memory_allocator_size;
276    heap_stats.memory_allocator_size = &memory_allocator_size;
277    size_t memory_allocator_capacity;
278    heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
279    size_t malloced_memory;
280    heap_stats.malloced_memory = &malloced_memory;
281    size_t malloced_peak_memory;
282    heap_stats.malloced_peak_memory = &malloced_peak_memory;
283    size_t objects_per_type[LAST_TYPE + 1] = {0};
284    heap_stats.objects_per_type = objects_per_type;
285    size_t size_per_type[LAST_TYPE + 1] = {0};
286    heap_stats.size_per_type = size_per_type;
287    int os_error;
288    heap_stats.os_error = &os_error;
289    heap_stats.last_few_messages = last_few_messages;
290    heap_stats.js_stacktrace = js_stacktrace;
291    intptr_t end_marker;
292    heap_stats.end_marker = &end_marker;
293    if (isolate->heap()->HasBeenSetUp()) {
294      // BUG(1718): Don't use the take_snapshot since we don't support
295      // HeapObjectIterator here without doing a special GC.
296      isolate->heap()->RecordStats(&heap_stats, false);
297      if (!FLAG_correctness_fuzzer_suppressions) {
298        char* first_newline = strchr(last_few_messages, '\n');
299        if (first_newline == nullptr || first_newline[1] == '\0')
300          first_newline = last_few_messages;
301        base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline);
302        base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
303      }
304    }
305    Utils::ReportOOMFailure(isolate, location, is_heap_oom);
306    if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
307    // If the fatal error handler returns, we stop execution.
308    FATAL("API fatal error handler returned after process out of memory");
309  }
310  
ReportApiFailure(const char * location,const char * message)311  void Utils::ReportApiFailure(const char* location, const char* message) {
312    i::Isolate* isolate = i::Isolate::TryGetCurrent();
313    FatalErrorCallback callback = nullptr;
314    if (isolate != nullptr) {
315      callback = isolate->exception_behavior();
316    }
317    if (callback == nullptr) {
318      base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
319                           message);
320      base::OS::Abort();
321    } else {
322      callback(location, message);
323    }
324    isolate->SignalFatalError();
325  }
326  
ReportOOMFailure(i::Isolate * isolate,const char * location,bool is_heap_oom)327  void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location,
328                               bool is_heap_oom) {
329    OOMErrorCallback oom_callback = isolate->oom_behavior();
330    if (oom_callback == nullptr) {
331      // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
332      // crbug.com/614440.
333      FatalErrorCallback fatal_callback = isolate->exception_behavior();
334      if (fatal_callback == nullptr) {
335        base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
336                             is_heap_oom ? "javascript" : "process", location);
337  #ifdef V8_FUZZILLI
338        exit(0);
339  #else
340        base::OS::Abort();
341  #endif  // V8_FUZZILLI
342      } else {
343        fatal_callback(location,
344                       is_heap_oom
345                           ? "Allocation failed - JavaScript heap out of memory"
346                           : "Allocation failed - process out of memory");
347      }
348    } else {
349      oom_callback(location, is_heap_oom);
350    }
351    isolate->SignalFatalError();
352  }
353  
SetSnapshotDataBlob(StartupData * snapshot_blob)354  void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
355    i::V8::SetSnapshotBlob(snapshot_blob);
356  }
357  
358  namespace {
359  
360  #ifdef V8_SANDBOXED_POINTERS
361  // ArrayBufferAllocator to use when sandboxed pointers are used in which case
362  // all ArrayBuffer backing stores need to be allocated inside the sandbox.
363  // Note, the current implementation is extremely inefficient as it uses the
364  // BoundedPageAllocator. In the future, we'll need a proper allocator
365  // implementation.
366  class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
367   public:
ArrayBufferAllocator()368    ArrayBufferAllocator() { CHECK(page_allocator_); }
369  
Allocate(size_t length)370    void* Allocate(size_t length) override {
371      return page_allocator_->AllocatePages(nullptr, RoundUp(length, page_size_),
372                                            page_size_,
373                                            PageAllocator::kReadWrite);
374    }
375  
AllocateUninitialized(size_t length)376    void* AllocateUninitialized(size_t length) override {
377      return Allocate(length);
378    }
379  
Free(void * data,size_t length)380    void Free(void* data, size_t length) override {
381      page_allocator_->FreePages(data, RoundUp(length, page_size_));
382    }
383  
384   private:
385    PageAllocator* page_allocator_ = internal::GetArrayBufferPageAllocator();
386    const size_t page_size_ = page_allocator_->AllocatePageSize();
387  };
388  
389  #else
390  
391  class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
392   public:
393    void* Allocate(size_t length) override {
394  #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
395      // Work around for GCC bug on AIX
396      // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
397      void* data = __linux_calloc(length, 1);
398  #else
399      void* data = base::Calloc(length, 1);
400  #endif
401      return data;
402    }
403  
404    void* AllocateUninitialized(size_t length) override {
405  #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
406      // Work around for GCC bug on AIX
407      // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
408      void* data = __linux_malloc(length);
409  #else
410      void* data = base::Malloc(length);
411  #endif
412      return data;
413    }
414  
415    void Free(void* data, size_t) override { base::Free(data); }
416  
417    void* Reallocate(void* data, size_t old_length, size_t new_length) override {
418  #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
419      // Work around for GCC bug on AIX
420      // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
421      void* new_data = __linux_realloc(data, new_length);
422  #else
423      void* new_data = base::Realloc(data, new_length);
424  #endif
425      if (new_length > old_length) {
426        memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0,
427               new_length - old_length);
428      }
429      return new_data;
430    }
431  };
432  #endif  // V8_SANDBOXED_POINTERS
433  
434  struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anon1d4f464a0111::SnapshotCreatorData435    explicit SnapshotCreatorData(Isolate* isolate)
436        : isolate_(isolate),
437          default_context_(),
438          contexts_(isolate),
439          created_(false) {}
440  
castv8::__anon1d4f464a0111::SnapshotCreatorData441    static SnapshotCreatorData* cast(void* data) {
442      return reinterpret_cast<SnapshotCreatorData*>(data);
443    }
444  
445    ArrayBufferAllocator allocator_;
446    Isolate* isolate_;
447    Persistent<Context> default_context_;
448    SerializeInternalFieldsCallback default_embedder_fields_serializer_;
449    PersistentValueVector<Context> contexts_;
450    std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
451    bool created_;
452  };
453  
454  }  // namespace
455  
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)456  SnapshotCreator::SnapshotCreator(Isolate* isolate,
457                                   const intptr_t* external_references,
458                                   StartupData* existing_snapshot) {
459    SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
460    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
461    internal_isolate->set_array_buffer_allocator(&data->allocator_);
462    internal_isolate->set_api_external_references(external_references);
463    internal_isolate->enable_serializer();
464    isolate->Enter();
465    const StartupData* blob = existing_snapshot
466                                  ? existing_snapshot
467                                  : i::Snapshot::DefaultSnapshotBlob();
468    if (blob && blob->raw_size > 0) {
469      internal_isolate->set_snapshot_blob(blob);
470      i::Snapshot::Initialize(internal_isolate);
471    } else {
472      internal_isolate->InitWithoutSnapshot();
473    }
474    data_ = data;
475    // Disable batch compilation during snapshot creation.
476    internal_isolate->baseline_batch_compiler()->set_enabled(false);
477  }
478  
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)479  SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
480                                   StartupData* existing_snapshot)
481      : SnapshotCreator(Isolate::Allocate(), external_references,
482                        existing_snapshot) {}
483  
~SnapshotCreator()484  SnapshotCreator::~SnapshotCreator() {
485    SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
486    Isolate* isolate = data->isolate_;
487    isolate->Exit();
488    isolate->Dispose();
489    delete data;
490  }
491  
GetIsolate()492  Isolate* SnapshotCreator::GetIsolate() {
493    return SnapshotCreatorData::cast(data_)->isolate_;
494  }
495  
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)496  void SnapshotCreator::SetDefaultContext(
497      Local<Context> context, SerializeInternalFieldsCallback callback) {
498    DCHECK(!context.IsEmpty());
499    SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
500    DCHECK(!data->created_);
501    DCHECK(data->default_context_.IsEmpty());
502    Isolate* isolate = data->isolate_;
503    CHECK_EQ(isolate, context->GetIsolate());
504    data->default_context_.Reset(isolate, context);
505    data->default_embedder_fields_serializer_ = callback;
506  }
507  
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)508  size_t SnapshotCreator::AddContext(Local<Context> context,
509                                     SerializeInternalFieldsCallback callback) {
510    DCHECK(!context.IsEmpty());
511    SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
512    DCHECK(!data->created_);
513    Isolate* isolate = data->isolate_;
514    CHECK_EQ(isolate, context->GetIsolate());
515    size_t index = data->contexts_.Size();
516    data->contexts_.Append(context);
517    data->embedder_fields_serializers_.push_back(callback);
518    return index;
519  }
520  
AddData(i::Address object)521  size_t SnapshotCreator::AddData(i::Address object) {
522    DCHECK_NE(object, i::kNullAddress);
523    SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
524    DCHECK(!data->created_);
525    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
526    i::HandleScope scope(isolate);
527    i::Handle<i::Object> obj(i::Object(object), isolate);
528    i::Handle<i::ArrayList> list;
529    if (!isolate->heap()->serialized_objects().IsArrayList()) {
530      list = i::ArrayList::New(isolate, 1);
531    } else {
532      list = i::Handle<i::ArrayList>(
533          i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
534    }
535    size_t index = static_cast<size_t>(list->Length());
536    list = i::ArrayList::Add(isolate, list, obj);
537    isolate->heap()->SetSerializedObjects(*list);
538    return index;
539  }
540  
AddData(Local<Context> context,i::Address object)541  size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
542    DCHECK_NE(object, i::kNullAddress);
543    DCHECK(!SnapshotCreatorData::cast(data_)->created_);
544    i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
545    i::Isolate* isolate = ctx->GetIsolate();
546    i::HandleScope scope(isolate);
547    i::Handle<i::Object> obj(i::Object(object), isolate);
548    i::Handle<i::ArrayList> list;
549    if (!ctx->serialized_objects().IsArrayList()) {
550      list = i::ArrayList::New(isolate, 1);
551    } else {
552      list = i::Handle<i::ArrayList>(
553          i::ArrayList::cast(ctx->serialized_objects()), isolate);
554    }
555    size_t index = static_cast<size_t>(list->Length());
556    list = i::ArrayList::Add(isolate, list, obj);
557    ctx->set_serialized_objects(*list);
558    return index;
559  }
560  
561  namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)562  void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
563    i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
564    i::Isolate* isolate = ctx->GetIsolate();
565    if (!ctx->serialized_objects().IsArrayList()) {
566      ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
567    } else {
568      i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
569                                   isolate);
570      i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
571      ctx->set_serialized_objects(*elements);
572    }
573  }
574  
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)575  void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
576    if (!isolate->heap()->serialized_objects().IsArrayList()) {
577      isolate->heap()->SetSerializedObjects(
578          i::ReadOnlyRoots(isolate).empty_fixed_array());
579    } else {
580      i::Handle<i::ArrayList> list(
581          i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
582      i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
583      isolate->heap()->SetSerializedObjects(*elements);
584    }
585  }
586  }  // anonymous namespace
587  
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)588  StartupData SnapshotCreator::CreateBlob(
589      SnapshotCreator::FunctionCodeHandling function_code_handling) {
590    SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
591    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
592    Utils::ApiCheck(!data->created_, "v8::SnapshotCreator::CreateBlob",
593                    "CreateBlob() cannot be called more than once on the same "
594                    "SnapshotCreator.");
595    Utils::ApiCheck(
596        !data->default_context_.IsEmpty(), "v8::SnapshotCreator::CreateBlob",
597        "CreateBlob() cannot be called before the default context is set.");
598  
599    const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
600    const int num_contexts = num_additional_contexts + 1;  // The default context.
601  
602    // Create and store lists of embedder-provided data needed during
603    // serialization.
604    {
605      i::HandleScope scope(isolate);
606      // Convert list of context-independent data to FixedArray.
607      ConvertSerializedObjectsToFixedArray(isolate);
608  
609      // Convert lists of context-dependent data to FixedArray.
610      ConvertSerializedObjectsToFixedArray(
611          data->default_context_.Get(data->isolate_));
612      for (int i = 0; i < num_additional_contexts; i++) {
613        ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
614      }
615  
616      // We need to store the global proxy size upfront in case we need the
617      // bootstrapper to create a global proxy before we deserialize the context.
618      i::Handle<i::FixedArray> global_proxy_sizes =
619          isolate->factory()->NewFixedArray(num_additional_contexts,
620                                            i::AllocationType::kOld);
621      for (int i = 0; i < num_additional_contexts; i++) {
622        i::Handle<i::Context> context =
623            v8::Utils::OpenHandle(*data->contexts_.Get(i));
624        global_proxy_sizes->set(i,
625                                i::Smi::FromInt(context->global_proxy().Size()));
626      }
627      isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
628    }
629  
630    // We might rehash strings and re-sort descriptors. Clear the lookup cache.
631    isolate->descriptor_lookup_cache()->Clear();
632  
633    // If we don't do this then we end up with a stray root pointing at the
634    // context even after we have disposed of the context.
635    isolate->heap()->CollectAllAvailableGarbage(
636        i::GarbageCollectionReason::kSnapshotCreator);
637    {
638      i::HandleScope scope(isolate);
639      isolate->heap()->CompactWeakArrayLists();
640    }
641  
642    i::Snapshot::ClearReconstructableDataForSerialization(
643        isolate, function_code_handling == FunctionCodeHandling::kClear);
644  
645    i::GlobalSafepointScope global_safepoint(isolate);
646    i::DisallowGarbageCollection no_gc_from_here_on;
647  
648    // Create a vector with all contexts and clear associated Persistent fields.
649    // Note these contexts may be dead after calling Clear(), but will not be
650    // collected until serialization completes and the DisallowGarbageCollection
651    // scope above goes out of scope.
652    std::vector<i::Context> contexts;
653    contexts.reserve(num_contexts);
654    {
655      i::HandleScope scope(isolate);
656      contexts.push_back(
657          *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
658      data->default_context_.Reset();
659      for (int i = 0; i < num_additional_contexts; i++) {
660        i::Handle<i::Context> context =
661            v8::Utils::OpenHandle(*data->contexts_.Get(i));
662        contexts.push_back(*context);
663      }
664      data->contexts_.Clear();
665    }
666  
667    // Check that values referenced by global/eternal handles are accounted for.
668    i::SerializedHandleChecker handle_checker(isolate, &contexts);
669    CHECK(handle_checker.CheckGlobalAndEternalHandles());
670  
671    // Create a vector with all embedder fields serializers.
672    std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
673    embedder_fields_serializers.reserve(num_contexts);
674    embedder_fields_serializers.push_back(
675        data->default_embedder_fields_serializer_);
676    for (int i = 0; i < num_additional_contexts; i++) {
677      embedder_fields_serializers.push_back(
678          data->embedder_fields_serializers_[i]);
679    }
680  
681    data->created_ = true;
682    return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
683                               global_safepoint, no_gc_from_here_on);
684  }
685  
CanBeRehashed() const686  bool StartupData::CanBeRehashed() const {
687    DCHECK(i::Snapshot::VerifyChecksum(this));
688    return i::Snapshot::ExtractRehashability(this);
689  }
690  
IsValid() const691  bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
692  
SetDcheckErrorHandler(DcheckErrorCallback that)693  void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
694    v8::base::SetDcheckFunction(that);
695  }
696  
SetFlagsFromString(const char * str)697  void V8::SetFlagsFromString(const char* str) {
698    SetFlagsFromString(str, strlen(str));
699  }
700  
SetFlagsFromString(const char * str,size_t length)701  void V8::SetFlagsFromString(const char* str, size_t length) {
702    i::FlagList::SetFlagsFromString(str, length);
703    i::FlagList::EnforceFlagImplications();
704  }
705  
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)706  void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
707    using HelpOptions = i::FlagList::HelpOptions;
708    i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
709                                         HelpOptions(HelpOptions::kDontExit));
710  }
711  
712  RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
713  
RegisteredExtension(std::unique_ptr<Extension> extension)714  RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
715      : extension_(std::move(extension)) {}
716  
717  // static
Register(std::unique_ptr<Extension> extension)718  void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
719    RegisteredExtension* new_extension =
720        new RegisteredExtension(std::move(extension));
721    new_extension->next_ = first_extension_;
722    first_extension_ = new_extension;
723  }
724  
725  // static
UnregisterAll()726  void RegisteredExtension::UnregisterAll() {
727    RegisteredExtension* re = first_extension_;
728    while (re != nullptr) {
729      RegisteredExtension* next = re->next();
730      delete re;
731      re = next;
732    }
733    first_extension_ = nullptr;
734  }
735  
736  namespace {
737  class ExtensionResource : public String::ExternalOneByteStringResource {
738   public:
ExtensionResource()739    ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)740    ExtensionResource(const char* data, size_t length)
741        : data_(data), length_(length) {}
data() const742    const char* data() const override { return data_; }
length() const743    size_t length() const override { return length_; }
Dispose()744    void Dispose() override {}
745  
746   private:
747    const char* data_;
748    size_t length_;
749  };
750  }  // anonymous namespace
751  
RegisterExtension(std::unique_ptr<Extension> extension)752  void RegisterExtension(std::unique_ptr<Extension> extension) {
753    RegisteredExtension::Register(std::move(extension));
754  }
755  
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)756  Extension::Extension(const char* name, const char* source, int dep_count,
757                       const char** deps, int source_length)
758      : name_(name),
759        source_length_(source_length >= 0
760                           ? source_length
761                           : (source ? static_cast<int>(strlen(source)) : 0)),
762        dep_count_(dep_count),
763        deps_(deps),
764        auto_enable_(false) {
765    source_ = new ExtensionResource(source, source_length_);
766    CHECK(source != nullptr || source_length_ == 0);
767  }
768  
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)769  void ResourceConstraints::ConfigureDefaultsFromHeapSize(
770      size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
771    CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
772    if (maximum_heap_size_in_bytes == 0) {
773      return;
774    }
775    size_t young_generation, old_generation;
776    i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
777                                         &young_generation, &old_generation);
778    set_max_young_generation_size_in_bytes(
779        std::max(young_generation, i::Heap::MinYoungGenerationSize()));
780    set_max_old_generation_size_in_bytes(
781        std::max(old_generation, i::Heap::MinOldGenerationSize()));
782    if (initial_heap_size_in_bytes > 0) {
783      i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
784                                           &young_generation, &old_generation);
785      // We do not set lower bounds for the initial sizes.
786      set_initial_young_generation_size_in_bytes(young_generation);
787      set_initial_old_generation_size_in_bytes(old_generation);
788    }
789    if (i::kPlatformRequiresCodeRange) {
790      set_code_range_size_in_bytes(
791          std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
792    }
793  }
794  
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)795  void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
796                                              uint64_t virtual_memory_limit) {
797    size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
798    size_t young_generation, old_generation;
799    i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
800                                         &old_generation);
801    set_max_young_generation_size_in_bytes(young_generation);
802    set_max_old_generation_size_in_bytes(old_generation);
803  
804    if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
805      set_code_range_size_in_bytes(
806          std::min(i::kMaximalCodeRangeSize,
807                   static_cast<size_t>(virtual_memory_limit / 8)));
808    }
809  }
810  
811  namespace internal {
812  
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,GlobalHandleStoreMode store_mode)813  i::Address* GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
814                                       internal::Address* slot,
815                                       GlobalHandleStoreMode store_mode) {
816    API_RCS_SCOPE(isolate, TracedGlobal, New);
817  #ifdef DEBUG
818    Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
819                    "the address slot must be not null");
820  #endif
821    i::Handle<i::Object> result =
822        isolate->global_handles()->CreateTraced(*obj, slot, store_mode);
823  #ifdef VERIFY_HEAP
824    if (i::FLAG_verify_heap) {
825      i::Object(*obj).ObjectVerify(isolate);
826    }
827  #endif  // VERIFY_HEAP
828    return result.location();
829  }
830  
MoveTracedReference(internal::Address ** from,internal::Address ** to)831  void MoveTracedReference(internal::Address** from, internal::Address** to) {
832    GlobalHandles::MoveTracedReference(from, to);
833  }
834  
CopyTracedReference(const internal::Address * const * from,internal::Address ** to)835  void CopyTracedReference(const internal::Address* const* from,
836                           internal::Address** to) {
837    GlobalHandles::CopyTracedReference(from, to);
838  }
839  
DisposeTracedReference(internal::Address * location)840  void DisposeTracedReference(internal::Address* location) {
841    GlobalHandles::DestroyTracedReference(location);
842  }
843  
844  }  // namespace internal
845  
846  namespace api_internal {
847  
GlobalizeReference(i::Isolate * isolate,i::Address * obj)848  i::Address* GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
849    API_RCS_SCOPE(isolate, Persistent, New);
850    i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
851  #ifdef VERIFY_HEAP
852    if (i::FLAG_verify_heap) {
853      i::Object(*obj).ObjectVerify(isolate);
854    }
855  #endif  // VERIFY_HEAP
856    return result.location();
857  }
858  
CopyGlobalReference(i::Address * from)859  i::Address* CopyGlobalReference(i::Address* from) {
860    i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
861    return result.location();
862  }
863  
MoveGlobalReference(internal::Address ** from,internal::Address ** to)864  void MoveGlobalReference(internal::Address** from, internal::Address** to) {
865    i::GlobalHandles::MoveGlobal(from, to);
866  }
867  
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)868  void MakeWeak(i::Address* location, void* parameter,
869                WeakCallbackInfo<void>::Callback weak_callback,
870                WeakCallbackType type) {
871    i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
872  }
873  
MakeWeak(i::Address ** location_addr)874  void MakeWeak(i::Address** location_addr) {
875    i::GlobalHandles::MakeWeak(location_addr);
876  }
877  
ClearWeak(i::Address * location)878  void* ClearWeak(i::Address* location) {
879    return i::GlobalHandles::ClearWeakness(location);
880  }
881  
AnnotateStrongRetainer(i::Address * location,const char * label)882  void AnnotateStrongRetainer(i::Address* location, const char* label) {
883    i::GlobalHandles::AnnotateStrongRetainer(location, label);
884  }
885  
DisposeGlobal(i::Address * location)886  void DisposeGlobal(i::Address* location) {
887    i::GlobalHandles::Destroy(location);
888  }
889  
Eternalize(Isolate * v8_isolate,Value * value)890  Value* Eternalize(Isolate* v8_isolate, Value* value) {
891    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
892    i::Object object = *Utils::OpenHandle(value);
893    int index = -1;
894    isolate->eternal_handles()->Create(isolate, object, &index);
895    return reinterpret_cast<Value*>(
896        isolate->eternal_handles()->Get(index).location());
897  }
898  
FromJustIsNothing()899  void FromJustIsNothing() {
900    Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
901  }
902  
ToLocalEmpty()903  void ToLocalEmpty() {
904    Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
905  }
906  
InternalFieldOutOfBounds(int index)907  void InternalFieldOutOfBounds(int index) {
908    Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
909                    "WeakCallbackInfo::GetInternalField",
910                    "Internal field out of bounds.");
911  }
912  
913  }  // namespace api_internal
914  
915  // --- H a n d l e s ---
916  
HandleScope(Isolate * isolate)917  HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
918  
Initialize(Isolate * isolate)919  void HandleScope::Initialize(Isolate* isolate) {
920    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
921    // We do not want to check the correct usage of the Locker class all over the
922    // place, so we do it only here: Without a HandleScope, an embedder can do
923    // almost nothing, so it is enough to check in this central place.
924    // We make an exception if the serializer is enabled, which means that the
925    // Isolate is exclusively used to create a snapshot.
926    Utils::ApiCheck(
927        !internal_isolate->was_locker_ever_used() ||
928            internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
929            internal_isolate->serializer_enabled(),
930        "HandleScope::HandleScope",
931        "Entering the V8 API without proper locking in place");
932    i::HandleScopeData* current = internal_isolate->handle_scope_data();
933    isolate_ = internal_isolate;
934    prev_next_ = current->next;
935    prev_limit_ = current->limit;
936    current->level++;
937  }
938  
~HandleScope()939  HandleScope::~HandleScope() {
940    i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
941  }
942  
operator new(size_t)943  void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)944  void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)945  void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)946  void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
947  
NumberOfHandles(Isolate * isolate)948  int HandleScope::NumberOfHandles(Isolate* isolate) {
949    return i::HandleScope::NumberOfHandles(
950        reinterpret_cast<i::Isolate*>(isolate));
951  }
952  
CreateHandle(i::Isolate * isolate,i::Address value)953  i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
954    return i::HandleScope::CreateHandle(isolate, value);
955  }
956  
EscapableHandleScope(Isolate * v8_isolate)957  EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
958    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
959    escape_slot_ =
960        CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
961    Initialize(v8_isolate);
962  }
963  
Escape(i::Address * escape_value)964  i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
965    i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
966    Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
967                    "EscapableHandleScope::Escape", "Escape value set twice");
968    if (escape_value == nullptr) {
969      *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
970      return nullptr;
971    }
972    *escape_slot_ = *escape_value;
973    return escape_slot_;
974  }
975  
operator new(size_t)976  void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)977  void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)978  void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)979  void EscapableHandleScope::operator delete[](void*, size_t) {
980    base::OS::Abort();
981  }
982  
SealHandleScope(Isolate * isolate)983  SealHandleScope::SealHandleScope(Isolate* isolate)
984      : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
985    i::HandleScopeData* current = isolate_->handle_scope_data();
986    prev_limit_ = current->limit;
987    current->limit = current->next;
988    prev_sealed_level_ = current->sealed_level;
989    current->sealed_level = current->level;
990  }
991  
~SealHandleScope()992  SealHandleScope::~SealHandleScope() {
993    i::HandleScopeData* current = isolate_->handle_scope_data();
994    DCHECK_EQ(current->next, current->limit);
995    current->limit = prev_limit_;
996    DCHECK_EQ(current->level, current->sealed_level);
997    current->sealed_level = prev_sealed_level_;
998  }
999  
operator new(size_t)1000  void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1001  void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1002  void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1003  void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1004  
IsModule() const1005  bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
IsFixedArray() const1006  bool Data::IsFixedArray() const {
1007    return Utils::OpenHandle(this)->IsFixedArray();
1008  }
1009  
IsValue() const1010  bool Data::IsValue() const {
1011    i::DisallowGarbageCollection no_gc;
1012    i::Object self = *Utils::OpenHandle(this);
1013    if (self.IsSmi()) return true;
1014    i::HeapObject heap_object = i::HeapObject::cast(self);
1015    DCHECK(!heap_object.IsTheHole());
1016    if (heap_object.IsSymbol()) {
1017      return !i::Symbol::cast(heap_object).is_private();
1018    }
1019    return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1020  }
1021  
IsPrivate() const1022  bool Data::IsPrivate() const {
1023    return Utils::OpenHandle(this)->IsPrivateSymbol();
1024  }
1025  
IsObjectTemplate() const1026  bool Data::IsObjectTemplate() const {
1027    return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1028  }
1029  
IsFunctionTemplate() const1030  bool Data::IsFunctionTemplate() const {
1031    return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1032  }
1033  
IsContext() const1034  bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1035  
Enter()1036  void Context::Enter() {
1037    i::Handle<i::Context> env = Utils::OpenHandle(this);
1038    i::Isolate* isolate = env->GetIsolate();
1039    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1040    i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1041    impl->EnterContext(*env);
1042    impl->SaveContext(isolate->context());
1043    isolate->set_context(*env);
1044  }
1045  
Exit()1046  void Context::Exit() {
1047    i::Handle<i::Context> env = Utils::OpenHandle(this);
1048    i::Isolate* isolate = env->GetIsolate();
1049    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1050    i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1051    if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1052                         "Cannot exit non-entered context")) {
1053      return;
1054    }
1055    impl->LeaveContext();
1056    isolate->set_context(impl->RestoreContext());
1057  }
1058  
BackupIncumbentScope(Local<Context> backup_incumbent_context)1059  Context::BackupIncumbentScope::BackupIncumbentScope(
1060      Local<Context> backup_incumbent_context)
1061      : backup_incumbent_context_(backup_incumbent_context) {
1062    DCHECK(!backup_incumbent_context_.IsEmpty());
1063  
1064    i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1065    i::Isolate* isolate = env->GetIsolate();
1066  
1067    js_stack_comparable_address_ =
1068        i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1069  
1070    prev_ = isolate->top_backup_incumbent_scope();
1071    isolate->set_top_backup_incumbent_scope(this);
1072  }
1073  
~BackupIncumbentScope()1074  Context::BackupIncumbentScope::~BackupIncumbentScope() {
1075    i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1076    i::Isolate* isolate = env->GetIsolate();
1077  
1078    i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1079  
1080    isolate->set_top_backup_incumbent_scope(prev_);
1081  }
1082  
1083  STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1084  
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1085  static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1086                                                         int index, bool can_grow,
1087                                                         const char* location) {
1088    i::Handle<i::Context> env = Utils::OpenHandle(context);
1089    i::Isolate* isolate = env->GetIsolate();
1090    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
1091    bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1092                              "Not a native context") &&
1093              Utils::ApiCheck(index >= 0, location, "Negative index");
1094    if (!ok) return i::Handle<i::EmbedderDataArray>();
1095    // TODO(ishell): remove cast once embedder_data slot has a proper type.
1096    i::Handle<i::EmbedderDataArray> data(
1097        i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1098    if (index < data->length()) return data;
1099    if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1100                         location, "Index too large")) {
1101      return i::Handle<i::EmbedderDataArray>();
1102    }
1103    data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1104    env->set_embedder_data(*data);
1105    return data;
1106  }
1107  
GetNumberOfEmbedderDataFields()1108  uint32_t Context::GetNumberOfEmbedderDataFields() {
1109    i::Handle<i::Context> context = Utils::OpenHandle(this);
1110    ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate());
1111    Utils::ApiCheck(context->IsNativeContext(),
1112                    "Context::GetNumberOfEmbedderDataFields",
1113                    "Not a native context");
1114    // TODO(ishell): remove cast once embedder_data slot has a proper type.
1115    return static_cast<uint32_t>(
1116        i::EmbedderDataArray::cast(context->embedder_data()).length());
1117  }
1118  
SlowGetEmbedderData(int index)1119  v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1120    const char* location = "v8::Context::GetEmbedderData()";
1121    i::Handle<i::EmbedderDataArray> data =
1122        EmbedderDataFor(this, index, false, location);
1123    if (data.is_null()) return Local<Value>();
1124    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1125    i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1126                                isolate);
1127    return Utils::ToLocal(result);
1128  }
1129  
SetEmbedderData(int index,v8::Local<Value> value)1130  void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1131    const char* location = "v8::Context::SetEmbedderData()";
1132    i::Handle<i::EmbedderDataArray> data =
1133        EmbedderDataFor(this, index, true, location);
1134    if (data.is_null()) return;
1135    i::Handle<i::Object> val = Utils::OpenHandle(*value);
1136    i::EmbedderDataSlot::store_tagged(*data, index, *val);
1137    DCHECK_EQ(*Utils::OpenHandle(*value),
1138              *Utils::OpenHandle(*GetEmbedderData(index)));
1139  }
1140  
SlowGetAlignedPointerFromEmbedderData(int index)1141  void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1142    const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1143    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1144    i::HandleScope handle_scope(isolate);
1145    i::Handle<i::EmbedderDataArray> data =
1146        EmbedderDataFor(this, index, false, location);
1147    if (data.is_null()) return nullptr;
1148    void* result;
1149    Utils::ApiCheck(
1150        i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1151        location, "Pointer is not aligned");
1152    return result;
1153  }
1154  
SetAlignedPointerInEmbedderData(int index,void * value)1155  void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1156    const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1157    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1158    i::Handle<i::EmbedderDataArray> data =
1159        EmbedderDataFor(this, index, true, location);
1160    bool ok =
1161        i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1162    Utils::ApiCheck(ok, location, "Pointer is not aligned");
1163    DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1164  }
1165  
1166  // --- T e m p l a t e ---
1167  
InitializeTemplate(i::TemplateInfo that,int type,bool do_not_cache)1168  static void InitializeTemplate(i::TemplateInfo that, int type,
1169                                 bool do_not_cache) {
1170    that.set_number_of_properties(0);
1171    that.set_tag(type);
1172    int serial_number =
1173        do_not_cache ? i::TemplateInfo::kDoNotCache : i::TemplateInfo::kUncached;
1174    that.set_serial_number(serial_number);
1175  }
1176  
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1177  void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1178                     v8::PropertyAttribute attribute) {
1179    auto templ = Utils::OpenHandle(this);
1180    i::Isolate* isolate = templ->GetIsolate();
1181    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1182    i::HandleScope scope(isolate);
1183    auto value_obj = Utils::OpenHandle(*value);
1184  
1185    Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(),
1186                    "v8::Template::Set",
1187                    "Invalid value, must be a primitive or a Template");
1188  
1189    // The template cache only performs shallow clones, if we set an
1190    // ObjectTemplate as a property value then we can not cache the receiver
1191    // template.
1192    if (value_obj->IsObjectTemplateInfo()) {
1193      templ->set_serial_number(i::TemplateInfo::kDoNotCache);
1194    }
1195  
1196    i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1197                                   value_obj,
1198                                   static_cast<i::PropertyAttributes>(attribute));
1199  }
1200  
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1201  void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1202                            v8::PropertyAttribute attribute) {
1203    Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1204        attribute);
1205  }
1206  
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1207  void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1208                                     v8::Local<FunctionTemplate> getter,
1209                                     v8::Local<FunctionTemplate> setter,
1210                                     v8::PropertyAttribute attribute,
1211                                     v8::AccessControl access_control) {
1212    // TODO(verwaest): Remove |access_control|.
1213    DCHECK_EQ(v8::DEFAULT, access_control);
1214    auto templ = Utils::OpenHandle(this);
1215    auto isolate = templ->GetIsolate();
1216    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1217    DCHECK(!name.IsEmpty());
1218    DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1219    i::HandleScope scope(isolate);
1220    i::ApiNatives::AddAccessorProperty(
1221        isolate, templ, Utils::OpenHandle(*name),
1222        Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1223        static_cast<i::PropertyAttributes>(attribute));
1224  }
1225  
1226  // --- F u n c t i o n   T e m p l a t e ---
InitializeFunctionTemplate(i::FunctionTemplateInfo info,bool do_not_cache)1227  static void InitializeFunctionTemplate(i::FunctionTemplateInfo info,
1228                                         bool do_not_cache) {
1229    InitializeTemplate(info, Consts::FUNCTION_TEMPLATE, do_not_cache);
1230    info.set_flag(0);
1231  }
1232  
1233  static Local<ObjectTemplate> ObjectTemplateNew(
1234      i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1235      bool do_not_cache);
1236  
PrototypeTemplate()1237  Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1238    auto self = Utils::OpenHandle(this);
1239    i::Isolate* i_isolate = self->GetIsolate();
1240    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1241    i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1242    if (result->IsUndefined(i_isolate)) {
1243      // Do not cache prototype objects.
1244      result = Utils::OpenHandle(
1245          *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1246      i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1247    }
1248    return ToApiHandle<ObjectTemplate>(result);
1249  }
1250  
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1251  void FunctionTemplate::SetPrototypeProviderTemplate(
1252      Local<FunctionTemplate> prototype_provider) {
1253    auto self = Utils::OpenHandle(this);
1254    i::Isolate* i_isolate = self->GetIsolate();
1255    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1256    i::Handle<i::FunctionTemplateInfo> result =
1257        Utils::OpenHandle(*prototype_provider);
1258    Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
1259                    "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1260                    "Protoype must be undefined");
1261    Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
1262                    "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1263                    "Prototype provider must be empty");
1264    i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1265                                                          result);
1266  }
1267  
EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,const char * func)1268  static void EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,
1269                                 const char* func) {
1270    DCHECK_IMPLIES(info->instantiated(), info->published());
1271    Utils::ApiCheck(!info->published(), func,
1272                    "FunctionTemplate already instantiated");
1273  }
1274  
Inherit(v8::Local<FunctionTemplate> value)1275  void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1276    auto info = Utils::OpenHandle(this);
1277    EnsureNotPublished(info, "v8::FunctionTemplate::Inherit");
1278    i::Isolate* i_isolate = info->GetIsolate();
1279    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1280    Utils::ApiCheck(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate),
1281                    "v8::FunctionTemplate::Inherit",
1282                    "Protoype provider must be empty");
1283    i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1284                                               Utils::OpenHandle(*value));
1285  }
1286  
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> (),SideEffectType side_effect_type=SideEffectType::kHasSideEffect,const MemorySpan<const CFunction> & c_function_overloads={},uint8_t instance_type=0,uint8_t allowed_receiver_instance_type_range_start=0,uint8_t allowed_receiver_instance_type_range_end=0)1287  static Local<FunctionTemplate> FunctionTemplateNew(
1288      i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1289      v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1290      bool do_not_cache,
1291      v8::Local<Private> cached_property_name = v8::Local<Private>(),
1292      SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1293      const MemorySpan<const CFunction>& c_function_overloads = {},
1294      uint8_t instance_type = 0,
1295      uint8_t allowed_receiver_instance_type_range_start = 0,
1296      uint8_t allowed_receiver_instance_type_range_end = 0) {
1297    i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1298        i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1299    i::Handle<i::FunctionTemplateInfo> obj =
1300        i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1301    {
1302      // Disallow GC until all fields of obj have acceptable types.
1303      i::DisallowGarbageCollection no_gc;
1304      i::FunctionTemplateInfo raw = *obj;
1305      InitializeFunctionTemplate(raw, do_not_cache);
1306      raw.set_length(length);
1307      raw.set_undetectable(false);
1308      raw.set_needs_access_check(false);
1309      raw.set_accept_any_receiver(true);
1310      if (!signature.IsEmpty()) {
1311        raw.set_signature(*Utils::OpenHandle(*signature));
1312      }
1313      raw.set_cached_property_name(
1314          cached_property_name.IsEmpty()
1315              ? i::ReadOnlyRoots(isolate).the_hole_value()
1316              : *Utils::OpenHandle(*cached_property_name));
1317      if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
1318      raw.SetInstanceType(instance_type);
1319      raw.set_allowed_receiver_instance_type_range_start(
1320          allowed_receiver_instance_type_range_start);
1321      raw.set_allowed_receiver_instance_type_range_end(
1322          allowed_receiver_instance_type_range_end);
1323    }
1324    if (callback != nullptr) {
1325      Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1326                                          c_function_overloads);
1327    }
1328    return Utils::ToLocal(obj);
1329  }
1330  
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const CFunction * c_function,uint16_t instance_type,uint16_t allowed_receiver_instance_type_range_start,uint16_t allowed_receiver_instance_type_range_end)1331  Local<FunctionTemplate> FunctionTemplate::New(
1332      Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1333      v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1334      SideEffectType side_effect_type, const CFunction* c_function,
1335      uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
1336      uint16_t allowed_receiver_instance_type_range_end) {
1337    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1338    // Changes to the environment cannot be captured in the snapshot. Expect no
1339    // function templates when the isolate is created for serialization.
1340    API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1341  
1342    if (!Utils::ApiCheck(
1343            !c_function || behavior == ConstructorBehavior::kThrow,
1344            "FunctionTemplate::New",
1345            "Fast API calls are not supported for constructor functions.")) {
1346      return Local<FunctionTemplate>();
1347    }
1348  
1349    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1350    return FunctionTemplateNew(
1351        i_isolate, callback, data, signature, length, behavior, false,
1352        Local<Private>(), side_effect_type,
1353        c_function ? MemorySpan<const CFunction>{c_function, 1}
1354                   : MemorySpan<const CFunction>{},
1355        instance_type, allowed_receiver_instance_type_range_start,
1356        allowed_receiver_instance_type_range_end);
1357  }
1358  
NewWithCFunctionOverloads(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1359  Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1360      Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1361      v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1362      SideEffectType side_effect_type,
1363      const MemorySpan<const CFunction>& c_function_overloads) {
1364    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1365    API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1366  
1367    if (!Utils::ApiCheck(
1368            c_function_overloads.size() == 0 ||
1369                behavior == ConstructorBehavior::kThrow,
1370            "FunctionTemplate::NewWithCFunctionOverloads",
1371            "Fast API calls are not supported for constructor functions.")) {
1372      return Local<FunctionTemplate>();
1373    }
1374  
1375    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1376    return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1377                               behavior, false, Local<Private>(),
1378                               side_effect_type, c_function_overloads);
1379  }
1380  
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1381  Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1382      Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1383      Local<Value> data, Local<Signature> signature, int length,
1384      SideEffectType side_effect_type) {
1385    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1386    API_RCS_SCOPE(i_isolate, FunctionTemplate, NewWithCache);
1387    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1388    return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1389                               ConstructorBehavior::kAllow, false, cache_property,
1390                               side_effect_type);
1391  }
1392  
New(Isolate * isolate,Local<FunctionTemplate> receiver)1393  Local<Signature> Signature::New(Isolate* isolate,
1394                                  Local<FunctionTemplate> receiver) {
1395    return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1396  }
1397  
New(Isolate * isolate,Local<FunctionTemplate> receiver)1398  Local<AccessorSignature> AccessorSignature::New(
1399      Isolate* isolate, Local<FunctionTemplate> receiver) {
1400    return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1401  }
1402  
1403  #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata)        \
1404    do {                                                        \
1405      i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1406      (obj)->setter(*foreign);                                  \
1407    } while (false)
1408  
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1409  void FunctionTemplate::SetCallHandler(
1410      FunctionCallback callback, v8::Local<Value> data,
1411      SideEffectType side_effect_type,
1412      const MemorySpan<const CFunction>& c_function_overloads) {
1413    auto info = Utils::OpenHandle(this);
1414    EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
1415    i::Isolate* isolate = info->GetIsolate();
1416    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1417    i::HandleScope scope(isolate);
1418    i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1419        side_effect_type == SideEffectType::kHasNoSideEffect);
1420    SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1421    SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1422    if (data.IsEmpty()) {
1423      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424    }
1425    obj->set_data(*Utils::OpenHandle(*data));
1426    if (c_function_overloads.size() > 0) {
1427      // Stores the data for a sequence of CFunction overloads into a single
1428      // FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
1429      i::Handle<i::FixedArray> function_overloads =
1430          isolate->factory()->NewFixedArray(static_cast<int>(
1431              c_function_overloads.size() *
1432              i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
1433      int function_count = static_cast<int>(c_function_overloads.size());
1434      for (int i = 0; i < function_count; i++) {
1435        const CFunction& c_function = c_function_overloads.data()[i];
1436        i::Handle<i::Object> address =
1437            FromCData(isolate, c_function.GetAddress());
1438        function_overloads->set(
1439            i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
1440        i::Handle<i::Object> signature =
1441            FromCData(isolate, c_function.GetTypeInfo());
1442        function_overloads->set(
1443            i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
1444            *signature);
1445      }
1446      i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
1447                                                     function_overloads);
1448    }
1449    info->set_call_code(*obj, kReleaseStore);
1450  }
1451  
1452  namespace {
1453  
1454  template <typename Getter, typename Setter>
MakeAccessorInfo(i::Isolate * isolate,v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1455  i::Handle<i::AccessorInfo> MakeAccessorInfo(
1456      i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1457      v8::Local<Value> data, v8::AccessControl settings,
1458      v8::Local<AccessorSignature> signature, bool is_special_data_property,
1459      bool replace_on_access) {
1460    i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1461    SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1462    DCHECK_IMPLIES(replace_on_access,
1463                   is_special_data_property && setter == nullptr);
1464    if (is_special_data_property && setter == nullptr) {
1465      setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1466    }
1467    SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1468    i::Address redirected = obj->redirected_getter();
1469    if (redirected != i::kNullAddress) {
1470      SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1471    }
1472  
1473    i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1474    if (!accessor_name->IsUniqueName()) {
1475      accessor_name = isolate->factory()->InternalizeString(
1476          i::Handle<i::String>::cast(accessor_name));
1477    }
1478    i::DisallowGarbageCollection no_gc;
1479    i::AccessorInfo raw_obj = *obj;
1480    if (data.IsEmpty()) {
1481      raw_obj.set_data(i::ReadOnlyRoots(isolate).undefined_value());
1482    } else {
1483      raw_obj.set_data(*Utils::OpenHandle(*data));
1484    }
1485    raw_obj.set_name(*accessor_name);
1486    raw_obj.set_is_special_data_property(is_special_data_property);
1487    raw_obj.set_replace_on_access(replace_on_access);
1488    if (settings & ALL_CAN_READ) raw_obj.set_all_can_read(true);
1489    if (settings & ALL_CAN_WRITE) raw_obj.set_all_can_write(true);
1490    raw_obj.set_initial_property_attributes(i::NONE);
1491    if (!signature.IsEmpty()) {
1492      raw_obj.set_expected_receiver_type(*Utils::OpenHandle(*signature));
1493    }
1494    return obj;
1495  }
1496  
1497  }  // namespace
1498  
InstanceTemplate()1499  Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1500    i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1501    if (!Utils::ApiCheck(!handle.is_null(),
1502                         "v8::FunctionTemplate::InstanceTemplate()",
1503                         "Reading from empty handle")) {
1504      return Local<ObjectTemplate>();
1505    }
1506    i::Isolate* isolate = handle->GetIsolate();
1507    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1508    if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1509      Local<ObjectTemplate> templ =
1510          ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1511      i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1512                                                   Utils::OpenHandle(*templ));
1513    }
1514    i::Handle<i::ObjectTemplateInfo> result(
1515        i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1516    return Utils::ToLocal(result);
1517  }
1518  
SetLength(int length)1519  void FunctionTemplate::SetLength(int length) {
1520    auto info = Utils::OpenHandle(this);
1521    EnsureNotPublished(info, "v8::FunctionTemplate::SetLength");
1522    auto isolate = info->GetIsolate();
1523    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1524    info->set_length(length);
1525  }
1526  
SetClassName(Local<String> name)1527  void FunctionTemplate::SetClassName(Local<String> name) {
1528    auto info = Utils::OpenHandle(this);
1529    EnsureNotPublished(info, "v8::FunctionTemplate::SetClassName");
1530    auto isolate = info->GetIsolate();
1531    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1532    info->set_class_name(*Utils::OpenHandle(*name));
1533  }
1534  
SetAcceptAnyReceiver(bool value)1535  void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1536    auto info = Utils::OpenHandle(this);
1537    EnsureNotPublished(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1538    auto isolate = info->GetIsolate();
1539    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1540    info->set_accept_any_receiver(value);
1541  }
1542  
ReadOnlyPrototype()1543  void FunctionTemplate::ReadOnlyPrototype() {
1544    auto info = Utils::OpenHandle(this);
1545    EnsureNotPublished(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1546    auto isolate = info->GetIsolate();
1547    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548    info->set_read_only_prototype(true);
1549  }
1550  
RemovePrototype()1551  void FunctionTemplate::RemovePrototype() {
1552    auto info = Utils::OpenHandle(this);
1553    EnsureNotPublished(info, "v8::FunctionTemplate::RemovePrototype");
1554    auto isolate = info->GetIsolate();
1555    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1556    info->set_remove_prototype(true);
1557  }
1558  
1559  // --- O b j e c t T e m p l a t e ---
1560  
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1561  Local<ObjectTemplate> ObjectTemplate::New(
1562      Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1563    return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1564  }
1565  
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1566  static Local<ObjectTemplate> ObjectTemplateNew(
1567      i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1568      bool do_not_cache) {
1569    API_RCS_SCOPE(isolate, ObjectTemplate, New);
1570    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1571    i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1572        i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1573    i::Handle<i::ObjectTemplateInfo> obj =
1574        i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1575    {
1576      // Disallow GC until all fields of obj have acceptable types.
1577      i::DisallowGarbageCollection no_gc;
1578      i::ObjectTemplateInfo raw = *obj;
1579      InitializeTemplate(raw, Consts::OBJECT_TEMPLATE, do_not_cache);
1580      raw.set_data(0);
1581      if (!constructor.IsEmpty()) {
1582        raw.set_constructor(*Utils::OpenHandle(*constructor));
1583      }
1584    }
1585    return Utils::ToLocal(obj);
1586  }
1587  
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1588  Local<ObjectTemplate> ObjectTemplate::New(
1589      i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1590    return ObjectTemplateNew(isolate, constructor, false);
1591  }
1592  
1593  // Ensure that the object template has a constructor.  If no
1594  // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1595  static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1596      i::Isolate* isolate, ObjectTemplate* object_template) {
1597    i::Object obj = Utils::OpenHandle(object_template)->constructor();
1598    if (!obj.IsUndefined(isolate)) {
1599      i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1600      return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1601    }
1602    Local<FunctionTemplate> templ =
1603        FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1604    i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1605    i::FunctionTemplateInfo::SetInstanceTemplate(
1606        isolate, constructor, Utils::OpenHandle(object_template));
1607    Utils::OpenHandle(object_template)->set_constructor(*constructor);
1608    return constructor;
1609  }
1610  
1611  template <typename Getter, typename Setter, typename Data, typename Template>
TemplateSetAccessor(Template * template_obj,v8::Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1612  static void TemplateSetAccessor(
1613      Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1614      Data data, AccessControl settings, PropertyAttribute attribute,
1615      v8::Local<AccessorSignature> signature, bool is_special_data_property,
1616      bool replace_on_access, SideEffectType getter_side_effect_type,
1617      SideEffectType setter_side_effect_type) {
1618    auto info = Utils::OpenHandle(template_obj);
1619    auto isolate = info->GetIsolate();
1620    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1621    i::HandleScope scope(isolate);
1622    i::Handle<i::AccessorInfo> accessor_info =
1623        MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1624                         is_special_data_property, replace_on_access);
1625    {
1626      i::DisallowGarbageCollection no_gc;
1627      i::AccessorInfo raw = *accessor_info;
1628      raw.set_initial_property_attributes(
1629          static_cast<i::PropertyAttributes>(attribute));
1630      raw.set_getter_side_effect_type(getter_side_effect_type);
1631      raw.set_setter_side_effect_type(setter_side_effect_type);
1632    }
1633    i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1634  }
1635  
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1636  void Template::SetNativeDataProperty(v8::Local<String> name,
1637                                       AccessorGetterCallback getter,
1638                                       AccessorSetterCallback setter,
1639                                       v8::Local<Value> data,
1640                                       PropertyAttribute attribute,
1641                                       AccessControl settings,
1642                                       SideEffectType getter_side_effect_type,
1643                                       SideEffectType setter_side_effect_type) {
1644    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1645                        Local<AccessorSignature>(), true, false,
1646                        getter_side_effect_type, setter_side_effect_type);
1647  }
1648  
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1649  void Template::SetNativeDataProperty(
1650      v8::Local<String> name, AccessorGetterCallback getter,
1651      AccessorSetterCallback setter, v8::Local<Value> data,
1652      PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1653      AccessControl settings, SideEffectType getter_side_effect_type,
1654      SideEffectType setter_side_effect_type) {
1655    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1656                        signature, true, false, getter_side_effect_type,
1657                        setter_side_effect_type);
1658  }
1659  
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1660  void Template::SetNativeDataProperty(v8::Local<Name> name,
1661                                       AccessorNameGetterCallback getter,
1662                                       AccessorNameSetterCallback setter,
1663                                       v8::Local<Value> data,
1664                                       PropertyAttribute attribute,
1665                                       AccessControl settings,
1666                                       SideEffectType getter_side_effect_type,
1667                                       SideEffectType setter_side_effect_type) {
1668    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1669                        Local<AccessorSignature>(), true, false,
1670                        getter_side_effect_type, setter_side_effect_type);
1671  }
1672  
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1673  void Template::SetNativeDataProperty(
1674      v8::Local<Name> name, AccessorNameGetterCallback getter,
1675      AccessorNameSetterCallback setter, v8::Local<Value> data,
1676      PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1677      AccessControl settings, SideEffectType getter_side_effect_type,
1678      SideEffectType setter_side_effect_type) {
1679    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1680                        signature, true, false, getter_side_effect_type,
1681                        setter_side_effect_type);
1682  }
1683  
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1684  void Template::SetLazyDataProperty(v8::Local<Name> name,
1685                                     AccessorNameGetterCallback getter,
1686                                     v8::Local<Value> data,
1687                                     PropertyAttribute attribute,
1688                                     SideEffectType getter_side_effect_type,
1689                                     SideEffectType setter_side_effect_type) {
1690    TemplateSetAccessor(this, name, getter,
1691                        static_cast<AccessorNameSetterCallback>(nullptr), data,
1692                        DEFAULT, attribute, Local<AccessorSignature>(), true,
1693                        true, getter_side_effect_type, setter_side_effect_type);
1694  }
1695  
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1696  void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1697                                          PropertyAttribute attribute) {
1698    auto templ = Utils::OpenHandle(this);
1699    i::Isolate* isolate = templ->GetIsolate();
1700    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1701    i::HandleScope scope(isolate);
1702    i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1703                                   intrinsic,
1704                                   static_cast<i::PropertyAttributes>(attribute));
1705  }
1706  
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1707  void ObjectTemplate::SetAccessor(v8::Local<String> name,
1708                                   AccessorGetterCallback getter,
1709                                   AccessorSetterCallback setter,
1710                                   v8::Local<Value> data, AccessControl settings,
1711                                   PropertyAttribute attribute,
1712                                   SideEffectType getter_side_effect_type,
1713                                   SideEffectType setter_side_effect_type) {
1714    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1715                        Local<AccessorSignature>(),
1716                        i::FLAG_disable_old_api_accessors, false,
1717                        getter_side_effect_type, setter_side_effect_type);
1718  }
1719  
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1720  void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1721                                   AccessorNameGetterCallback getter,
1722                                   AccessorNameSetterCallback setter,
1723                                   v8::Local<Value> data, AccessControl settings,
1724                                   PropertyAttribute attribute,
1725                                   SideEffectType getter_side_effect_type,
1726                                   SideEffectType setter_side_effect_type) {
1727    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1728                        Local<AccessorSignature>(),
1729                        i::FLAG_disable_old_api_accessors, false,
1730                        getter_side_effect_type, setter_side_effect_type);
1731  }
1732  
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1733  void ObjectTemplate::SetAccessor(v8::Local<String> name,
1734                                   AccessorGetterCallback getter,
1735                                   AccessorSetterCallback setter,
1736                                   v8::Local<Value> data, AccessControl settings,
1737                                   PropertyAttribute attribute,
1738                                   v8::Local<AccessorSignature> signature,
1739                                   SideEffectType getter_side_effect_type,
1740                                   SideEffectType setter_side_effect_type) {
1741    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1742                        signature, i::FLAG_disable_old_api_accessors, false,
1743                        getter_side_effect_type, setter_side_effect_type);
1744  }
1745  
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1746  void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1747                                   AccessorNameGetterCallback getter,
1748                                   AccessorNameSetterCallback setter,
1749                                   v8::Local<Value> data, AccessControl settings,
1750                                   PropertyAttribute attribute,
1751                                   v8::Local<AccessorSignature> signature,
1752                                   SideEffectType getter_side_effect_type,
1753                                   SideEffectType setter_side_effect_type) {
1754    TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1755                        signature, i::FLAG_disable_old_api_accessors, false,
1756                        getter_side_effect_type, setter_side_effect_type);
1757  }
1758  
1759  template <typename Getter, typename Setter, typename Query, typename Descriptor,
1760            typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1761  static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1762      i::Isolate* isolate, Getter getter, Setter setter, Query query,
1763      Descriptor descriptor, Deleter remover, Enumerator enumerator,
1764      Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1765    auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1766        i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1767    obj->set_flags(0);
1768  
1769    if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1770    if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1771    if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1772    if (descriptor != nullptr)
1773      SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1774    if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1775    if (enumerator != nullptr)
1776      SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1777    if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1778    obj->set_can_intercept_symbols(
1779        !(static_cast<int>(flags) &
1780          static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1781    obj->set_all_can_read(static_cast<int>(flags) &
1782                          static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1783    obj->set_non_masking(static_cast<int>(flags) &
1784                         static_cast<int>(PropertyHandlerFlags::kNonMasking));
1785    obj->set_has_no_side_effect(
1786        static_cast<int>(flags) &
1787        static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1788  
1789    if (data.IsEmpty()) {
1790      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1791    }
1792    obj->set_data(*Utils::OpenHandle(*data));
1793    return obj;
1794  }
1795  
1796  template <typename Getter, typename Setter, typename Query, typename Descriptor,
1797            typename Deleter, typename Enumerator, typename Definer>
CreateNamedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1798  static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1799      i::Isolate* isolate, Getter getter, Setter setter, Query query,
1800      Descriptor descriptor, Deleter remover, Enumerator enumerator,
1801      Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1802    auto interceptor =
1803        CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1804                              enumerator, definer, data, flags);
1805    interceptor->set_is_named(true);
1806    return interceptor;
1807  }
1808  
1809  template <typename Getter, typename Setter, typename Query, typename Descriptor,
1810            typename Deleter, typename Enumerator, typename Definer>
CreateIndexedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1811  static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1812      i::Isolate* isolate, Getter getter, Setter setter, Query query,
1813      Descriptor descriptor, Deleter remover, Enumerator enumerator,
1814      Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1815    auto interceptor =
1816        CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1817                              enumerator, definer, data, flags);
1818    interceptor->set_is_named(false);
1819    return interceptor;
1820  }
1821  
1822  template <typename Getter, typename Setter, typename Query, typename Descriptor,
1823            typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1824  static void ObjectTemplateSetNamedPropertyHandler(
1825      ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1826      Descriptor descriptor, Deleter remover, Enumerator enumerator,
1827      Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1828    i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1829    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1830    i::HandleScope scope(isolate);
1831    auto cons = EnsureConstructor(isolate, templ);
1832    EnsureNotPublished(cons, "ObjectTemplateSetNamedPropertyHandler");
1833    auto obj =
1834        CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1835                                   remover, enumerator, definer, data, flags);
1836    i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1837  }
1838  
SetHandler(const NamedPropertyHandlerConfiguration & config)1839  void ObjectTemplate::SetHandler(
1840      const NamedPropertyHandlerConfiguration& config) {
1841    ObjectTemplateSetNamedPropertyHandler(
1842        this, config.getter, config.setter, config.query, config.descriptor,
1843        config.deleter, config.enumerator, config.definer, config.data,
1844        config.flags);
1845  }
1846  
MarkAsUndetectable()1847  void ObjectTemplate::MarkAsUndetectable() {
1848    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1849    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1850    i::HandleScope scope(isolate);
1851    auto cons = EnsureConstructor(isolate, this);
1852    EnsureNotPublished(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1853    cons->set_undetectable(true);
1854  }
1855  
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1856  void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1857                                              Local<Value> data) {
1858    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1859    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1860    i::HandleScope scope(isolate);
1861    auto cons = EnsureConstructor(isolate, this);
1862    EnsureNotPublished(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1863  
1864    i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1865        i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1866    i::Handle<i::AccessCheckInfo> info =
1867        i::Handle<i::AccessCheckInfo>::cast(struct_info);
1868  
1869    SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1870    info->set_named_interceptor(i::Object());
1871    info->set_indexed_interceptor(i::Object());
1872  
1873    if (data.IsEmpty()) {
1874      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1875    }
1876    info->set_data(*Utils::OpenHandle(*data));
1877  
1878    i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1879    cons->set_needs_access_check(true);
1880  }
1881  
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1882  void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1883      AccessCheckCallback callback,
1884      const NamedPropertyHandlerConfiguration& named_handler,
1885      const IndexedPropertyHandlerConfiguration& indexed_handler,
1886      Local<Value> data) {
1887    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1888    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1889    i::HandleScope scope(isolate);
1890    auto cons = EnsureConstructor(isolate, this);
1891    EnsureNotPublished(cons,
1892                       "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1893  
1894    i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1895        i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1896    i::Handle<i::AccessCheckInfo> info =
1897        i::Handle<i::AccessCheckInfo>::cast(struct_info);
1898  
1899    SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1900    auto named_interceptor = CreateNamedInterceptorInfo(
1901        isolate, named_handler.getter, named_handler.setter, named_handler.query,
1902        named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1903        named_handler.definer, named_handler.data, named_handler.flags);
1904    info->set_named_interceptor(*named_interceptor);
1905    auto indexed_interceptor = CreateIndexedInterceptorInfo(
1906        isolate, indexed_handler.getter, indexed_handler.setter,
1907        indexed_handler.query, indexed_handler.descriptor,
1908        indexed_handler.deleter, indexed_handler.enumerator,
1909        indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1910    info->set_indexed_interceptor(*indexed_interceptor);
1911  
1912    if (data.IsEmpty()) {
1913      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1914    }
1915    info->set_data(*Utils::OpenHandle(*data));
1916  
1917    i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1918    cons->set_needs_access_check(true);
1919  }
1920  
SetHandler(const IndexedPropertyHandlerConfiguration & config)1921  void ObjectTemplate::SetHandler(
1922      const IndexedPropertyHandlerConfiguration& config) {
1923    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1924    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1925    i::HandleScope scope(isolate);
1926    auto cons = EnsureConstructor(isolate, this);
1927    EnsureNotPublished(cons, "v8::ObjectTemplate::SetHandler");
1928    auto obj = CreateIndexedInterceptorInfo(
1929        isolate, config.getter, config.setter, config.query, config.descriptor,
1930        config.deleter, config.enumerator, config.definer, config.data,
1931        config.flags);
1932    i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1933  }
1934  
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1935  void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1936                                                Local<Value> data) {
1937    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1938    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1939    i::HandleScope scope(isolate);
1940    auto cons = EnsureConstructor(isolate, this);
1941    EnsureNotPublished(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1942    i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1943    SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1944    SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1945    if (data.IsEmpty()) {
1946      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1947    }
1948    obj->set_data(*Utils::OpenHandle(*data));
1949    i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1950  }
1951  
InternalFieldCount() const1952  int ObjectTemplate::InternalFieldCount() const {
1953    return Utils::OpenHandle(this)->embedder_field_count();
1954  }
1955  
SetInternalFieldCount(int value)1956  void ObjectTemplate::SetInternalFieldCount(int value) {
1957    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1958    if (!Utils::ApiCheck(i::Smi::IsValid(value),
1959                         "v8::ObjectTemplate::SetInternalFieldCount()",
1960                         "Invalid embedder field count")) {
1961      return;
1962    }
1963    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1964    if (value > 0) {
1965      // The embedder field count is set by the constructor function's
1966      // construct code, so we ensure that there is a constructor
1967      // function to do the setting.
1968      EnsureConstructor(isolate, this);
1969    }
1970    Utils::OpenHandle(this)->set_embedder_field_count(value);
1971  }
1972  
IsImmutableProto() const1973  bool ObjectTemplate::IsImmutableProto() const {
1974    return Utils::OpenHandle(this)->immutable_proto();
1975  }
1976  
SetImmutableProto()1977  void ObjectTemplate::SetImmutableProto() {
1978    auto self = Utils::OpenHandle(this);
1979    i::Isolate* isolate = self->GetIsolate();
1980    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1981    self->set_immutable_proto(true);
1982  }
1983  
IsCodeLike() const1984  bool ObjectTemplate::IsCodeLike() const {
1985    return Utils::OpenHandle(this)->code_like();
1986  }
1987  
SetCodeLike()1988  void ObjectTemplate::SetCodeLike() {
1989    auto self = Utils::OpenHandle(this);
1990    i::Isolate* isolate = self->GetIsolate();
1991    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1992    self->set_code_like(true);
1993  }
1994  
1995  // --- S c r i p t s ---
1996  
1997  // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1998  // JSFunction.
1999  
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)2000  ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
2001                                         BufferPolicy buffer_policy_)
2002      : data(data_),
2003        length(length_),
2004        rejected(false),
2005        buffer_policy(buffer_policy_) {}
2006  
~CachedData()2007  ScriptCompiler::CachedData::~CachedData() {
2008    if (buffer_policy == BufferOwned) {
2009      delete[] data;
2010    }
2011  }
2012  
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)2013  ScriptCompiler::StreamedSource::StreamedSource(
2014      std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2015      : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2016  
2017  ScriptCompiler::StreamedSource::~StreamedSource() = default;
2018  
BindToCurrentContext()2019  Local<Script> UnboundScript::BindToCurrentContext() {
2020    auto function_info =
2021        i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2022    i::Isolate* isolate = function_info->GetIsolate();
2023    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2024    i::Handle<i::JSFunction> function =
2025        i::Factory::JSFunctionBuilder{isolate, function_info,
2026                                      isolate->native_context()}
2027            .Build();
2028    return ToApiHandle<Script>(function);
2029  }
2030  
GetId() const2031  int UnboundScript::GetId() const {
2032    auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
2033    API_RCS_SCOPE(function_info.GetIsolate(), UnboundScript, GetId);
2034    return i::Script::cast(function_info.script()).id();
2035  }
2036  
GetLineNumber(int code_pos)2037  int UnboundScript::GetLineNumber(int code_pos) {
2038    i::Handle<i::SharedFunctionInfo> obj =
2039        i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2040    i::Isolate* isolate = obj->GetIsolate();
2041    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2042    API_RCS_SCOPE(isolate, UnboundScript, GetLineNumber);
2043    if (obj->script().IsScript()) {
2044      i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2045      return i::Script::GetLineNumber(script, code_pos);
2046    } else {
2047      return -1;
2048    }
2049  }
2050  
GetScriptName()2051  Local<Value> UnboundScript::GetScriptName() {
2052    i::Handle<i::SharedFunctionInfo> obj =
2053        i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2054    i::Isolate* isolate = obj->GetIsolate();
2055    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2056    API_RCS_SCOPE(isolate, UnboundScript, GetName);
2057    if (obj->script().IsScript()) {
2058      i::Object name = i::Script::cast(obj->script()).name();
2059      return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2060    } else {
2061      return Local<String>();
2062    }
2063  }
2064  
GetSourceURL()2065  Local<Value> UnboundScript::GetSourceURL() {
2066    i::Handle<i::SharedFunctionInfo> obj =
2067        i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2068    i::Isolate* isolate = obj->GetIsolate();
2069    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2070    API_RCS_SCOPE(isolate, UnboundScript, GetSourceURL);
2071    if (obj->script().IsScript()) {
2072      i::Object url = i::Script::cast(obj->script()).source_url();
2073      return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2074    } else {
2075      return Local<String>();
2076    }
2077  }
2078  
GetSourceMappingURL()2079  Local<Value> UnboundScript::GetSourceMappingURL() {
2080    i::Handle<i::SharedFunctionInfo> obj =
2081        i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2082    i::Isolate* isolate = obj->GetIsolate();
2083    API_RCS_SCOPE(isolate, UnboundScript, GetSourceMappingURL);
2084    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2085    if (obj->script().IsScript()) {
2086      i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2087      return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2088    } else {
2089      return Local<String>();
2090    }
2091  }
2092  
Run(Local<Context> context)2093  MaybeLocal<Value> Script::Run(Local<Context> context) {
2094    return Run(context, Local<Data>());
2095  }
2096  
Run(Local<Context> context,Local<Data> host_defined_options)2097  MaybeLocal<Value> Script::Run(Local<Context> context,
2098                                Local<Data> host_defined_options) {
2099    auto v8_isolate = context->GetIsolate();
2100    auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2101    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2102    ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2103             InternalEscapableScope);
2104    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2105    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2106                                               isolate);
2107    i::AggregatingHistogramTimerScope histogram_timer(
2108        isolate->counters()->compile_lazy());
2109    auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2110  
2111    // TODO(crbug.com/1193459): remove once ablation study is completed
2112    base::ElapsedTimer timer;
2113    base::TimeDelta delta;
2114    if (i::FLAG_script_delay > 0) {
2115      delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay);
2116    }
2117    if (i::FLAG_script_delay_once > 0 && !isolate->did_run_script_delay()) {
2118      delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay_once);
2119      isolate->set_did_run_script_delay(true);
2120    }
2121    if (i::FLAG_script_delay_fraction > 0.0) {
2122      timer.Start();
2123    } else if (delta.InMicroseconds() > 0) {
2124      timer.Start();
2125      while (timer.Elapsed() < delta) {
2126        // Busy wait.
2127      }
2128    }
2129  
2130    if (V8_UNLIKELY(i::FLAG_experimental_web_snapshots)) {
2131      i::Handle<i::HeapObject> maybe_script =
2132          handle(fun->shared().script(), isolate);
2133      if (maybe_script->IsScript() &&
2134          i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
2135        i::WebSnapshotDeserializer deserializer(
2136            reinterpret_cast<i::Isolate*>(v8_isolate),
2137            i::Handle<i::Script>::cast(maybe_script));
2138        deserializer.Deserialize();
2139        RETURN_ON_FAILED_EXECUTION(Value);
2140        Local<Value> result = v8::Undefined(v8_isolate);
2141        RETURN_ESCAPED(result);
2142      }
2143    }
2144  
2145    i::Handle<i::Object> receiver = isolate->global_proxy();
2146    // TODO(cbruni, chromium:1244145): Remove once migrated to the context.
2147    i::Handle<i::Object> options(
2148        i::Script::cast(fun->shared().script()).host_defined_options(), isolate);
2149    Local<Value> result;
2150    has_pending_exception = !ToLocal<Value>(
2151        i::Execution::CallScript(isolate, fun, receiver, options), &result);
2152  
2153    if (i::FLAG_script_delay_fraction > 0.0) {
2154      delta = v8::base::TimeDelta::FromMillisecondsD(
2155          timer.Elapsed().InMillisecondsF() * i::FLAG_script_delay_fraction);
2156      timer.Restart();
2157      while (timer.Elapsed() < delta) {
2158        // Busy wait.
2159      }
2160    }
2161  
2162    RETURN_ON_FAILED_EXECUTION(Value);
2163    RETURN_ESCAPED(result);
2164  }
2165  
GetResourceName()2166  Local<Value> ScriptOrModule::GetResourceName() {
2167    i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2168    i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2169    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2170    i::Handle<i::Object> val(obj->resource_name(), isolate);
2171    return ToApiHandle<Value>(val);
2172  }
2173  
GetHostDefinedOptions()2174  Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2175    return HostDefinedOptions().As<PrimitiveArray>();
2176  }
2177  
HostDefinedOptions()2178  Local<Data> ScriptOrModule::HostDefinedOptions() {
2179    i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2180    i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2181    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2182    i::Handle<i::Object> val(obj->host_defined_options(), isolate);
2183    return ToApiHandle<Data>(val);
2184  }
2185  
GetUnboundScript()2186  Local<UnboundScript> Script::GetUnboundScript() {
2187    i::DisallowGarbageCollection no_gc;
2188    i::Handle<i::JSFunction> obj = Utils::OpenHandle(this);
2189    i::SharedFunctionInfo sfi = (*obj).shared();
2190    i::Isolate* isolate = sfi.GetIsolate();
2191    return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2192  }
2193  
GetResourceName()2194  Local<Value> Script::GetResourceName() {
2195    i::DisallowGarbageCollection no_gc;
2196    i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2197    i::SharedFunctionInfo sfi = (*func).shared();
2198    i::Isolate* isolate = func->GetIsolate();
2199    CHECK(sfi.script().IsScript());
2200    return ToApiHandle<Value>(
2201        i::handle(i::Script::cast(sfi.script()).name(), isolate));
2202  }
2203  
2204  // static
New(Isolate * v8_isolate,int length)2205  Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2206    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2207    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2208    Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2209                    "length must be equal or greater than zero");
2210    i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2211    return ToApiHandle<PrimitiveArray>(array);
2212  }
2213  
Length() const2214  int PrimitiveArray::Length() const {
2215    i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2216    return array->length();
2217  }
2218  
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2219  void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2220                           Local<Primitive> item) {
2221    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2222    i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2223    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2224    Utils::ApiCheck(index >= 0 && index < array->length(),
2225                    "v8::PrimitiveArray::Set",
2226                    "index must be greater than or equal to 0 and less than the "
2227                    "array length");
2228    i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2229    array->set(index, *i_item);
2230  }
2231  
Get(Isolate * v8_isolate,int index)2232  Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2233    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2234    i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2235    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2236    Utils::ApiCheck(index >= 0 && index < array->length(),
2237                    "v8::PrimitiveArray::Get",
2238                    "index must be greater than or equal to 0 and less than the "
2239                    "array length");
2240    i::Handle<i::Object> i_item(array->get(index), isolate);
2241    return ToApiHandle<Primitive>(i_item);
2242  }
2243  
CheckCast(v8::Data * that)2244  void v8::PrimitiveArray::CheckCast(v8::Data* that) {
2245    i::Handle<i::Object> obj = Utils::OpenHandle(that);
2246    Utils::ApiCheck(
2247        obj->IsFixedArray(), "v8::PrimitiveArray::Cast",
2248        "Value is not a PrimitiveArray. This is a temporary issue, v8::Data and "
2249        "v8::PrimitiveArray will not be compatible in the future.");
2250  }
2251  
Length() const2252  int FixedArray::Length() const {
2253    i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2254    return self->length();
2255  }
2256  
Get(Local<Context> context,int i) const2257  Local<Data> FixedArray::Get(Local<Context> context, int i) const {
2258    i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2259    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2260    CHECK_LT(i, self->length());
2261    i::Handle<i::Object> entry(self->get(i), isolate);
2262    return ToApiHandle<Data>(entry);
2263  }
2264  
GetSpecifier() const2265  Local<String> ModuleRequest::GetSpecifier() const {
2266    i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2267    i::Isolate* isolate = self->GetIsolate();
2268    return ToApiHandle<String>(i::handle(self->specifier(), isolate));
2269  }
2270  
GetSourceOffset() const2271  int ModuleRequest::GetSourceOffset() const {
2272    return Utils::OpenHandle(this)->position();
2273  }
2274  
GetImportAssertions() const2275  Local<FixedArray> ModuleRequest::GetImportAssertions() const {
2276    i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2277    i::Isolate* isolate = self->GetIsolate();
2278    return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate));
2279  }
2280  
GetStatus() const2281  Module::Status Module::GetStatus() const {
2282    i::Handle<i::Module> self = Utils::OpenHandle(this);
2283    switch (self->status()) {
2284      case i::Module::kUnlinked:
2285      case i::Module::kPreLinking:
2286        return kUninstantiated;
2287      case i::Module::kLinking:
2288        return kInstantiating;
2289      case i::Module::kLinked:
2290        return kInstantiated;
2291      case i::Module::kEvaluating:
2292      case i::Module::kEvaluatingAsync:
2293        return kEvaluating;
2294      case i::Module::kEvaluated:
2295        return kEvaluated;
2296      case i::Module::kErrored:
2297        return kErrored;
2298    }
2299    UNREACHABLE();
2300  }
2301  
GetException() const2302  Local<Value> Module::GetException() const {
2303    Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2304                    "Module status must be kErrored");
2305    i::Handle<i::Module> self = Utils::OpenHandle(this);
2306    i::Isolate* isolate = self->GetIsolate();
2307    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2308    return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2309  }
2310  
GetModuleRequests() const2311  Local<FixedArray> Module::GetModuleRequests() const {
2312    i::Handle<i::Module> self = Utils::OpenHandle(this);
2313    if (self->IsSyntheticModule()) {
2314      // Synthetic modules are leaf nodes in the module graph. They have no
2315      // ModuleRequests.
2316      return ToApiHandle<FixedArray>(
2317          self->GetReadOnlyRoots().empty_fixed_array_handle());
2318    } else {
2319      i::Isolate* isolate = self->GetIsolate();
2320      i::Handle<i::FixedArray> module_requests(
2321          i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2322          isolate);
2323      return ToApiHandle<FixedArray>(module_requests);
2324    }
2325  }
2326  
SourceOffsetToLocation(int offset) const2327  Location Module::SourceOffsetToLocation(int offset) const {
2328    i::Handle<i::Module> self = Utils::OpenHandle(this);
2329    i::Isolate* isolate = self->GetIsolate();
2330    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2331    i::HandleScope scope(isolate);
2332    Utils::ApiCheck(
2333        self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation",
2334        "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule");
2335    i::Handle<i::Script> script(
2336        i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2337    i::Script::PositionInfo info;
2338    i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
2339    return v8::Location(info.line, info.column);
2340  }
2341  
GetModuleNamespace()2342  Local<Value> Module::GetModuleNamespace() {
2343    Utils::ApiCheck(
2344        GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2345        "v8::Module::GetModuleNamespace must be used on an instantiated module");
2346    i::Handle<i::Module> self = Utils::OpenHandle(this);
2347    auto isolate = self->GetIsolate();
2348    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2349    i::Handle<i::JSModuleNamespace> module_namespace =
2350        i::Module::GetModuleNamespace(isolate, self);
2351    return ToApiHandle<Value>(module_namespace);
2352  }
2353  
GetUnboundModuleScript()2354  Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2355    i::Handle<i::Module> self = Utils::OpenHandle(this);
2356    Utils::ApiCheck(
2357        self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript",
2358        "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule");
2359    auto isolate = self->GetIsolate();
2360    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2361    return ToApiHandle<UnboundModuleScript>(i::handle(
2362        i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2363        isolate));
2364  }
2365  
ScriptId() const2366  int Module::ScriptId() const {
2367    i::Module self = *Utils::OpenHandle(this);
2368    Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
2369                    "v8::Module::ScriptId must be used on an SourceTextModule");
2370    ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2371    return i::SourceTextModule::cast(self).GetScript().id();
2372  }
2373  
IsGraphAsync() const2374  bool Module::IsGraphAsync() const {
2375    Utils::ApiCheck(
2376        GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2377        "v8::Module::IsGraphAsync must be used on an instantiated module");
2378    i::Module self = *Utils::OpenHandle(this);
2379    auto isolate = self.GetIsolate();
2380    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2381    return self.IsGraphAsync(isolate);
2382  }
2383  
IsSourceTextModule() const2384  bool Module::IsSourceTextModule() const {
2385    return Utils::OpenHandle(this)->IsSourceTextModule();
2386  }
2387  
IsSyntheticModule() const2388  bool Module::IsSyntheticModule() const {
2389    return Utils::OpenHandle(this)->IsSyntheticModule();
2390  }
2391  
GetIdentityHash() const2392  int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2393  
InstantiateModule(Local<Context> context,Module::ResolveModuleCallback callback)2394  Maybe<bool> Module::InstantiateModule(Local<Context> context,
2395                                        Module::ResolveModuleCallback callback) {
2396    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2397    ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2398             i::HandleScope);
2399    has_pending_exception = !i::Module::Instantiate(
2400        isolate, Utils::OpenHandle(this), context, callback, nullptr);
2401    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2402    return Just(true);
2403  }
2404  
Evaluate(Local<Context> context)2405  MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2406    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2407    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2408    ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2409             InternalEscapableScope);
2410    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2411    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2412                                               isolate);
2413    i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2414  
2415    i::Handle<i::Module> self = Utils::OpenHandle(this);
2416    Utils::ApiCheck(self->status() >= i::Module::kLinked, "Module::Evaluate",
2417                    "Expected instantiated module");
2418  
2419    Local<Value> result;
2420    has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2421    RETURN_ON_FAILED_EXECUTION(Value);
2422    RETURN_ESCAPED(result);
2423  }
2424  
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2425  Local<Module> Module::CreateSyntheticModule(
2426      Isolate* isolate, Local<String> module_name,
2427      const std::vector<Local<v8::String>>& export_names,
2428      v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2429    auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2430    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
2431    i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2432    i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2433        static_cast<int>(export_names.size()));
2434    for (int i = 0; i < i_export_names->length(); ++i) {
2435      i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2436          Utils::OpenHandle(*export_names[i]));
2437      i_export_names->set(i, *str);
2438    }
2439    return v8::Utils::ToLocal(
2440        i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2441            i_module_name, i_export_names, evaluation_steps)));
2442  }
2443  
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2444  Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2445                                               Local<String> export_name,
2446                                               Local<v8::Value> export_value) {
2447    auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2448    i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2449    i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2450    i::Handle<i::Module> self = Utils::OpenHandle(this);
2451    Utils::ApiCheck(self->IsSyntheticModule(),
2452                    "v8::Module::SyntheticModuleSetExport",
2453                    "v8::Module::SyntheticModuleSetExport must only be called on "
2454                    "a SyntheticModule");
2455    ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2456                       SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2457    has_pending_exception =
2458        i::SyntheticModule::SetExport(i_isolate,
2459                                      i::Handle<i::SyntheticModule>::cast(self),
2460                                      i_export_name, i_export_value)
2461            .IsNothing();
2462    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2463    return Just(true);
2464  }
2465  
2466  namespace {
2467  
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,int resource_line_offset,int resource_column_offset,Local<Value> source_map_url,Local<Data> host_defined_options,ScriptOriginOptions origin_options)2468  i::ScriptDetails GetScriptDetails(
2469      i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset,
2470      int resource_column_offset, Local<Value> source_map_url,
2471      Local<Data> host_defined_options, ScriptOriginOptions origin_options) {
2472    i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
2473                                    origin_options);
2474    script_details.line_offset = resource_line_offset;
2475    script_details.column_offset = resource_column_offset;
2476    script_details.host_defined_options =
2477        host_defined_options.IsEmpty()
2478            ? isolate->factory()->empty_fixed_array()
2479            : Utils::OpenHandle(*(host_defined_options));
2480    if (!source_map_url.IsEmpty()) {
2481      script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2482    }
2483    return script_details;
2484  }
2485  
2486  }  // namespace
2487  
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2488  MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2489      Isolate* v8_isolate, Source* source, CompileOptions options,
2490      NoCacheReason no_cache_reason) {
2491    auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2492    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2493    ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2494                       CompileUnbound, MaybeLocal<UnboundScript>(),
2495                       InternalEscapableScope);
2496  
2497    i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2498  
2499    i::Handle<i::SharedFunctionInfo> result;
2500    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2501    i::ScriptDetails script_details = GetScriptDetails(
2502        isolate, source->resource_name, source->resource_line_offset,
2503        source->resource_column_offset, source->source_map_url,
2504        source->host_defined_options, source->resource_options);
2505  
2506    i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info;
2507    if (options == kConsumeCodeCache) {
2508      if (source->consume_cache_task) {
2509        // Take ownership of the internal deserialization task and clear it off
2510        // the consume task on the source.
2511        DCHECK_NOT_NULL(source->consume_cache_task->impl_);
2512        std::unique_ptr<i::BackgroundDeserializeTask> deserialize_task =
2513            std::move(source->consume_cache_task->impl_);
2514        maybe_function_info =
2515            i::Compiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
2516                isolate, str, script_details, deserialize_task.get(), options,
2517                no_cache_reason, i::NOT_NATIVES_CODE);
2518        source->cached_data->rejected = deserialize_task->rejected();
2519      } else {
2520        DCHECK(source->cached_data);
2521        // AlignedCachedData takes care of pointer-aligning the data.
2522        auto cached_data = std::make_unique<i::AlignedCachedData>(
2523            source->cached_data->data, source->cached_data->length);
2524        maybe_function_info =
2525            i::Compiler::GetSharedFunctionInfoForScriptWithCachedData(
2526                isolate, str, script_details, cached_data.get(), options,
2527                no_cache_reason, i::NOT_NATIVES_CODE);
2528        source->cached_data->rejected = cached_data->rejected();
2529      }
2530    } else {
2531      // Compile without any cache.
2532      maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript(
2533          isolate, str, script_details, options, no_cache_reason,
2534          i::NOT_NATIVES_CODE);
2535    }
2536  
2537    has_pending_exception = !maybe_function_info.ToHandle(&result);
2538    RETURN_ON_FAILED_EXECUTION(UnboundScript);
2539    RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2540  }
2541  
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2542  MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2543      Isolate* v8_isolate, Source* source, CompileOptions options,
2544      NoCacheReason no_cache_reason) {
2545    Utils::ApiCheck(
2546        !source->GetResourceOptions().IsModule(),
2547        "v8::ScriptCompiler::CompileUnboundScript",
2548        "v8::ScriptCompiler::CompileModule must be used to compile modules");
2549    return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2550  }
2551  
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2552  MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2553                                             Source* source,
2554                                             CompileOptions options,
2555                                             NoCacheReason no_cache_reason) {
2556    Utils::ApiCheck(
2557        !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2558        "v8::ScriptCompiler::CompileModule must be used to compile modules");
2559    auto isolate = context->GetIsolate();
2560    MaybeLocal<UnboundScript> maybe =
2561        CompileUnboundInternal(isolate, source, options, no_cache_reason);
2562    Local<UnboundScript> result;
2563    if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2564    v8::Context::Scope scope(context);
2565    return result->BindToCurrentContext();
2566  }
2567  
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2568  MaybeLocal<Module> ScriptCompiler::CompileModule(
2569      Isolate* isolate, Source* source, CompileOptions options,
2570      NoCacheReason no_cache_reason) {
2571    Utils::ApiCheck(options == kNoCompileOptions || options == kConsumeCodeCache,
2572                    "v8::ScriptCompiler::CompileModule",
2573                    "Invalid CompileOptions");
2574    Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2575                    "v8::ScriptCompiler::CompileModule",
2576                    "Invalid ScriptOrigin: is_module must be true");
2577    MaybeLocal<UnboundScript> maybe =
2578        CompileUnboundInternal(isolate, source, options, no_cache_reason);
2579    Local<UnboundScript> unbound;
2580    if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2581    i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2582    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2583    return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2584  }
2585  
2586  // static
CompileFunction(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason)2587  V8_WARN_UNUSED_RESULT MaybeLocal<Function> ScriptCompiler::CompileFunction(
2588      Local<Context> context, Source* source, size_t arguments_count,
2589      Local<String> arguments[], size_t context_extension_count,
2590      Local<Object> context_extensions[], CompileOptions options,
2591      NoCacheReason no_cache_reason) {
2592    return CompileFunctionInternal(context, source, arguments_count, arguments,
2593                                   context_extension_count, context_extensions,
2594                                   options, no_cache_reason, nullptr);
2595  }
2596  
2597  // static
CompileFunctionInContext(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2598  MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2599      Local<Context> context, Source* source, size_t arguments_count,
2600      Local<String> arguments[], size_t context_extension_count,
2601      Local<Object> context_extensions[], CompileOptions options,
2602      NoCacheReason no_cache_reason,
2603      Local<ScriptOrModule>* script_or_module_out) {
2604    return CompileFunctionInternal(
2605        context, source, arguments_count, arguments, context_extension_count,
2606        context_extensions, options, no_cache_reason, script_or_module_out);
2607  }
2608  
CompileFunctionInternal(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2609  MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
2610      Local<Context> v8_context, Source* source, size_t arguments_count,
2611      Local<String> arguments[], size_t context_extension_count,
2612      Local<Object> context_extensions[], CompileOptions options,
2613      NoCacheReason no_cache_reason,
2614      Local<ScriptOrModule>* script_or_module_out) {
2615    Local<Function> result;
2616  
2617    {
2618      PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunction,
2619                            Function);
2620      TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2621  
2622      DCHECK(options == CompileOptions::kConsumeCodeCache ||
2623             options == CompileOptions::kEagerCompile ||
2624             options == CompileOptions::kNoCompileOptions);
2625  
2626      i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2627  
2628      DCHECK(context->IsNativeContext());
2629  
2630      i::Handle<i::FixedArray> arguments_list =
2631          isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2632      for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2633        i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2634        if (!i::String::IsIdentifier(isolate, argument)) return Local<Function>();
2635        arguments_list->set(i, *argument);
2636      }
2637  
2638      for (size_t i = 0; i < context_extension_count; ++i) {
2639        i::Handle<i::JSReceiver> extension =
2640            Utils::OpenHandle(*context_extensions[i]);
2641        if (!extension->IsJSObject()) return Local<Function>();
2642        context = isolate->factory()->NewWithContext(
2643            context,
2644            i::ScopeInfo::CreateForWithScope(
2645                isolate,
2646                context->IsNativeContext()
2647                    ? i::Handle<i::ScopeInfo>::null()
2648                    : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2649            extension);
2650      }
2651  
2652      i::ScriptDetails script_details = GetScriptDetails(
2653          isolate, source->resource_name, source->resource_line_offset,
2654          source->resource_column_offset, source->source_map_url,
2655          source->host_defined_options, source->resource_options);
2656  
2657      std::unique_ptr<i::AlignedCachedData> cached_data;
2658      if (options == kConsumeCodeCache) {
2659        DCHECK(source->cached_data);
2660        // ScriptData takes care of pointer-aligning the data.
2661        cached_data.reset(new i::AlignedCachedData(source->cached_data->data,
2662                                                   source->cached_data->length));
2663      }
2664  
2665      i::Handle<i::JSFunction> scoped_result;
2666      has_pending_exception =
2667          !i::Compiler::GetWrappedFunction(
2668               Utils::OpenHandle(*source->source_string), arguments_list, context,
2669               script_details, cached_data.get(), options, no_cache_reason)
2670               .ToHandle(&scoped_result);
2671      if (options == kConsumeCodeCache) {
2672        source->cached_data->rejected = cached_data->rejected();
2673      }
2674      RETURN_ON_FAILED_EXECUTION(Function);
2675      result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2676    }
2677    // TODO(cbruni): remove script_or_module_out paramater
2678    if (script_or_module_out != nullptr) {
2679      i::Handle<i::JSFunction> function =
2680          i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2681      i::Isolate* isolate = function->GetIsolate();
2682      i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2683      i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2684      // TODO(cbruni, v8:12302): Avoid creating tempory ScriptOrModule objects.
2685      auto script_or_module = i::Handle<i::ScriptOrModule>::cast(
2686          isolate->factory()->NewStruct(i::SCRIPT_OR_MODULE_TYPE));
2687      script_or_module->set_resource_name(script->name());
2688      script_or_module->set_host_defined_options(script->host_defined_options());
2689  #ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
2690      i::Handle<i::ArrayList> list =
2691          i::handle(script->script_or_modules(), isolate);
2692      list = i::ArrayList::Add(isolate, list, script_or_module);
2693      script->set_script_or_modules(*list);
2694  #endif  // V8_SCRIPTORMODULE_LEGACY_LIFETIME
2695      *script_or_module_out = v8::Utils::ToLocal(script_or_module);
2696    }
2697    return result;
2698  }
2699  
Run()2700  void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2701  
StartStreaming(Isolate * v8_isolate,StreamedSource * source,v8::ScriptType type)2702  ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2703      Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) {
2704    if (!i::FLAG_script_streaming) return nullptr;
2705    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2706    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2707    i::ScriptStreamingData* data = source->impl();
2708    std::unique_ptr<i::BackgroundCompileTask> task =
2709        std::make_unique<i::BackgroundCompileTask>(data, isolate, type);
2710    data->task = std::move(task);
2711    return new ScriptCompiler::ScriptStreamingTask(data);
2712  }
2713  
ConsumeCodeCacheTask(std::unique_ptr<i::BackgroundDeserializeTask> impl)2714  ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2715      std::unique_ptr<i::BackgroundDeserializeTask> impl)
2716      : impl_(std::move(impl)) {}
2717  
2718  ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2719  
Run()2720  void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2721  
StartConsumingCodeCache(Isolate * v8_isolate,std::unique_ptr<CachedData> cached_data)2722  ScriptCompiler::ConsumeCodeCacheTask* ScriptCompiler::StartConsumingCodeCache(
2723      Isolate* v8_isolate, std::unique_ptr<CachedData> cached_data) {
2724    if (!i::FLAG_concurrent_cache_deserialization) return nullptr;
2725    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2726    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2727    return new ScriptCompiler::ConsumeCodeCacheTask(
2728        std::make_unique<i::BackgroundDeserializeTask>(isolate,
2729                                                       std::move(cached_data)));
2730  }
2731  
2732  namespace {
CompileStreamedSource(i::Isolate * isolate,ScriptCompiler::StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2733  i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
2734      i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source,
2735      Local<String> full_source_string, const ScriptOrigin& origin) {
2736    i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2737    i::ScriptDetails script_details =
2738        GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
2739                         origin.ColumnOffset(), origin.SourceMapUrl(),
2740                         origin.GetHostDefinedOptions(), origin.Options());
2741    i::ScriptStreamingData* data = v8_source->impl();
2742    return i::Compiler::GetSharedFunctionInfoForStreamedScript(
2743        isolate, str, script_details, data);
2744  }
2745  
2746  }  // namespace
2747  
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2748  MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2749                                             StreamedSource* v8_source,
2750                                             Local<String> full_source_string,
2751                                             const ScriptOrigin& origin) {
2752    PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2753    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2754    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2755                 "V8.CompileStreamedScript");
2756    i::Handle<i::SharedFunctionInfo> sfi;
2757    i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2758        CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2759    has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2760    if (has_pending_exception) isolate->ReportPendingMessages();
2761    RETURN_ON_FAILED_EXECUTION(Script);
2762    Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi);
2763    if (generic.IsEmpty()) return Local<Script>();
2764    Local<Script> bound = generic->BindToCurrentContext();
2765    if (bound.IsEmpty()) return Local<Script>();
2766    RETURN_ESCAPED(bound);
2767  }
2768  
CompileModule(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2769  MaybeLocal<Module> ScriptCompiler::CompileModule(
2770      Local<Context> context, StreamedSource* v8_source,
2771      Local<String> full_source_string, const ScriptOrigin& origin) {
2772    PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module);
2773    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2774    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2775                 "V8.CompileStreamedModule");
2776    i::Handle<i::SharedFunctionInfo> sfi;
2777    i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2778        CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2779    has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2780    if (has_pending_exception) isolate->ReportPendingMessages();
2781    RETURN_ON_FAILED_EXECUTION(Module);
2782    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2783    RETURN_ESCAPED(
2784        ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi)));
2785  }
2786  
CachedDataVersionTag()2787  uint32_t ScriptCompiler::CachedDataVersionTag() {
2788    return static_cast<uint32_t>(base::hash_combine(
2789        internal::Version::Hash(), internal::FlagList::Hash(),
2790        static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2791  }
2792  
CreateCodeCache(Local<UnboundScript> unbound_script)2793  ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2794      Local<UnboundScript> unbound_script) {
2795    i::Handle<i::SharedFunctionInfo> shared =
2796        i::Handle<i::SharedFunctionInfo>::cast(
2797            Utils::OpenHandle(*unbound_script));
2798    ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2799    DCHECK(shared->is_toplevel());
2800    return i::CodeSerializer::Serialize(shared);
2801  }
2802  
2803  // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2804  ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2805      Local<UnboundModuleScript> unbound_module_script) {
2806    i::Handle<i::SharedFunctionInfo> shared =
2807        i::Handle<i::SharedFunctionInfo>::cast(
2808            Utils::OpenHandle(*unbound_module_script));
2809    ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2810    DCHECK(shared->is_toplevel());
2811    return i::CodeSerializer::Serialize(shared);
2812  }
2813  
CreateCodeCacheForFunction(Local<Function> function)2814  ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2815      Local<Function> function) {
2816    auto js_function =
2817        i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2818    i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2819                                            js_function->GetIsolate());
2820    ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2821    Utils::ApiCheck(shared->is_wrapped(),
2822                    "v8::ScriptCompiler::CreateCodeCacheForFunction",
2823                    "Expected SharedFunctionInfo with wrapped source code.");
2824    return i::CodeSerializer::Serialize(shared);
2825  }
2826  
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2827  MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2828                                     ScriptOrigin* origin) {
2829    if (origin) {
2830      ScriptCompiler::Source script_source(source, *origin);
2831      return ScriptCompiler::Compile(context, &script_source);
2832    }
2833    ScriptCompiler::Source script_source(source);
2834    return ScriptCompiler::Compile(context, &script_source);
2835  }
2836  
2837  // --- E x c e p t i o n s ---
2838  
TryCatch(v8::Isolate * isolate)2839  v8::TryCatch::TryCatch(v8::Isolate* isolate)
2840      : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2841        next_(isolate_->try_catch_handler()),
2842        is_verbose_(false),
2843        can_continue_(true),
2844        capture_message_(true),
2845        rethrow_(false),
2846        has_terminated_(false) {
2847    ResetInternal();
2848    // Special handling for simulators which have a separate JS stack.
2849    js_stack_comparable_address_ = static_cast<internal::Address>(
2850        i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2851    isolate_->RegisterTryCatchHandler(this);
2852  }
2853  
~TryCatch()2854  v8::TryCatch::~TryCatch() {
2855    if (rethrow_) {
2856      v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2857      v8::HandleScope scope(isolate);
2858      v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2859      if (HasCaught() && capture_message_) {
2860        // If an exception was caught and rethrow_ is indicated, the saved
2861        // message, script, and location need to be restored to Isolate TLS
2862        // for reuse.  capture_message_ needs to be disabled so that Throw()
2863        // does not create a new message.
2864        isolate_->thread_local_top()->rethrowing_message_ = true;
2865        isolate_->RestorePendingMessageFromTryCatch(this);
2866      }
2867      isolate_->UnregisterTryCatchHandler(this);
2868      i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2869      reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2870      DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2871    } else {
2872      if (HasCaught() && isolate_->has_scheduled_exception()) {
2873        // If an exception was caught but is still scheduled because no API call
2874        // promoted it, then it is canceled to prevent it from being propagated.
2875        // Note that this will not cancel termination exceptions.
2876        isolate_->CancelScheduledExceptionFromTryCatch(this);
2877      }
2878      isolate_->UnregisterTryCatchHandler(this);
2879      i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2880    }
2881  }
2882  
operator new(size_t)2883  void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2884  void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2885  void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2886  void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2887  
HasCaught() const2888  bool v8::TryCatch::HasCaught() const {
2889    return !i::Object(reinterpret_cast<i::Address>(exception_))
2890                .IsTheHole(isolate_);
2891  }
2892  
CanContinue() const2893  bool v8::TryCatch::CanContinue() const { return can_continue_; }
2894  
HasTerminated() const2895  bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2896  
ReThrow()2897  v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2898    if (!HasCaught()) return v8::Local<v8::Value>();
2899    rethrow_ = true;
2900    return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2901  }
2902  
Exception() const2903  v8::Local<Value> v8::TryCatch::Exception() const {
2904    if (HasCaught()) {
2905      // Check for out of memory exception.
2906      i::Object exception(reinterpret_cast<i::Address>(exception_));
2907      return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2908    } else {
2909      return v8::Local<Value>();
2910    }
2911  }
2912  
StackTrace(Local<Context> context,Local<Value> exception)2913  MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2914                                             Local<Value> exception) {
2915    i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2916    if (!i_exception->IsJSObject()) return v8::Local<Value>();
2917    PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2918    auto obj = i::Handle<i::JSObject>::cast(i_exception);
2919    i::Handle<i::String> name = isolate->factory()->stack_string();
2920    Maybe<bool> maybe = i::JSReceiver::HasProperty(isolate, obj, name);
2921    has_pending_exception = maybe.IsNothing();
2922    RETURN_ON_FAILED_EXECUTION(Value);
2923    if (!maybe.FromJust()) return v8::Local<Value>();
2924    Local<Value> result;
2925    has_pending_exception =
2926        !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2927    RETURN_ON_FAILED_EXECUTION(Value);
2928    RETURN_ESCAPED(result);
2929  }
2930  
StackTrace(Local<Context> context) const2931  MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2932    if (!HasCaught()) return v8::Local<Value>();
2933    return StackTrace(context, Exception());
2934  }
2935  
Message() const2936  v8::Local<v8::Message> v8::TryCatch::Message() const {
2937    i::Object message(reinterpret_cast<i::Address>(message_obj_));
2938    DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2939    if (HasCaught() && !message.IsTheHole(isolate_)) {
2940      return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2941    } else {
2942      return v8::Local<v8::Message>();
2943    }
2944  }
2945  
Reset()2946  void v8::TryCatch::Reset() {
2947    if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2948      // If an exception was caught but is still scheduled because no API call
2949      // promoted it, then it is canceled to prevent it from being propagated.
2950      // Note that this will not cancel termination exceptions.
2951      isolate_->CancelScheduledExceptionFromTryCatch(this);
2952    }
2953    ResetInternal();
2954  }
2955  
ResetInternal()2956  void v8::TryCatch::ResetInternal() {
2957    i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2958    exception_ = reinterpret_cast<void*>(the_hole.ptr());
2959    message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2960  }
2961  
SetVerbose(bool value)2962  void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2963  
IsVerbose() const2964  bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2965  
SetCaptureMessage(bool value)2966  void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2967  
2968  // --- M e s s a g e ---
2969  
Get() const2970  Local<String> Message::Get() const {
2971    auto self = Utils::OpenHandle(this);
2972    i::Isolate* isolate = self->GetIsolate();
2973    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974    EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2975    i::Handle<i::String> raw_result =
2976        i::MessageHandler::GetMessage(isolate, self);
2977    Local<String> result = Utils::ToLocal(raw_result);
2978    return scope.Escape(result);
2979  }
2980  
GetIsolate() const2981  v8::Isolate* Message::GetIsolate() const {
2982    i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983    return reinterpret_cast<Isolate*>(isolate);
2984  }
2985  
GetScriptOrigin() const2986  ScriptOrigin Message::GetScriptOrigin() const {
2987    auto self = Utils::OpenHandle(this);
2988    i::Isolate* isolate = self->GetIsolate();
2989    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2990    i::Handle<i::Script> script(self->script(), isolate);
2991    return GetScriptOriginForScript(isolate, script);
2992  }
2993  
VerifyHostDefinedOptions() const2994  void ScriptOrigin::VerifyHostDefinedOptions() const {
2995    // TODO(cbruni, chromium:1244145): Remove checks once we allow arbitrary
2996    // host-defined options.
2997    USE(isolate_);
2998    if (host_defined_options_.IsEmpty()) return;
2999    Utils::ApiCheck(host_defined_options_->IsFixedArray(), "ScriptOrigin()",
3000                    "Host-defined options has to be a PrimitiveArray");
3001    i::Handle<i::FixedArray> options =
3002        Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
3003    for (int i = 0; i < options->length(); i++) {
3004      Utils::ApiCheck(options->get(i).IsPrimitive(), "ScriptOrigin()",
3005                      "PrimitiveArray can only contain primtive values");
3006    }
3007  }
3008  
GetScriptResourceName() const3009  v8::Local<Value> Message::GetScriptResourceName() const {
3010    ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
3011    return GetScriptOrigin().ResourceName();
3012  }
3013  
GetStackTrace() const3014  v8::Local<v8::StackTrace> Message::GetStackTrace() const {
3015    auto self = Utils::OpenHandle(this);
3016    i::Isolate* isolate = self->GetIsolate();
3017    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3018    EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3019    i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
3020    if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
3021    auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
3022    return scope.Escape(Utils::StackTraceToLocal(stackTrace));
3023  }
3024  
GetLineNumber(Local<Context> context) const3025  Maybe<int> Message::GetLineNumber(Local<Context> context) const {
3026    auto self = Utils::OpenHandle(this);
3027    i::Isolate* isolate = self->GetIsolate();
3028    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3029    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3030    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3031    return Just(self->GetLineNumber());
3032  }
3033  
GetStartPosition() const3034  int Message::GetStartPosition() const {
3035    auto self = Utils::OpenHandle(this);
3036    i::Isolate* isolate = self->GetIsolate();
3037    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3038    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3039    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3040    return self->GetStartPosition();
3041  }
3042  
GetEndPosition() const3043  int Message::GetEndPosition() const {
3044    auto self = Utils::OpenHandle(this);
3045    i::Isolate* isolate = self->GetIsolate();
3046    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3047    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3048    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3049    return self->GetEndPosition();
3050  }
3051  
ErrorLevel() const3052  int Message::ErrorLevel() const {
3053    auto self = Utils::OpenHandle(this);
3054    ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3055    return self->error_level();
3056  }
3057  
GetStartColumn() const3058  int Message::GetStartColumn() const {
3059    auto self = Utils::OpenHandle(this);
3060    i::Isolate* isolate = self->GetIsolate();
3061    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3062    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3063    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3064    return self->GetColumnNumber();
3065  }
3066  
GetWasmFunctionIndex() const3067  int Message::GetWasmFunctionIndex() const {
3068  #if V8_ENABLE_WEBASSEMBLY
3069    auto self = Utils::OpenHandle(this);
3070    i::Isolate* isolate = self->GetIsolate();
3071    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3072    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3073    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3074    int start_position = self->GetColumnNumber();
3075    if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
3076  
3077    i::Handle<i::Script> script(self->script(), isolate);
3078  
3079    if (script->type() != i::Script::TYPE_WASM) {
3080      return Message::kNoWasmFunctionIndexInfo;
3081    }
3082  
3083    auto debug_script = ToApiHandle<debug::Script>(script);
3084    return Local<debug::WasmScript>::Cast(debug_script)
3085        ->GetContainingFunction(start_position);
3086  #else
3087    return Message::kNoWasmFunctionIndexInfo;
3088  #endif  // V8_ENABLE_WEBASSEMBLY
3089  }
3090  
GetStartColumn(Local<Context> context) const3091  Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3092    return Just(GetStartColumn());
3093  }
3094  
GetEndColumn() const3095  int Message::GetEndColumn() const {
3096    auto self = Utils::OpenHandle(this);
3097    i::Isolate* isolate = self->GetIsolate();
3098    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3099    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3100    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3101    const int column_number = self->GetColumnNumber();
3102    if (column_number == -1) return -1;
3103    const int start = self->GetStartPosition();
3104    const int end = self->GetEndPosition();
3105    return column_number + (end - start);
3106  }
3107  
GetEndColumn(Local<Context> context) const3108  Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3109    return Just(GetEndColumn());
3110  }
3111  
IsSharedCrossOrigin() const3112  bool Message::IsSharedCrossOrigin() const {
3113    auto self = Utils::OpenHandle(this);
3114    i::Isolate* isolate = self->GetIsolate();
3115    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3116    return self->script().origin_options().IsSharedCrossOrigin();
3117  }
3118  
IsOpaque() const3119  bool Message::IsOpaque() const {
3120    auto self = Utils::OpenHandle(this);
3121    i::Isolate* isolate = self->GetIsolate();
3122    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3123    return self->script().origin_options().IsOpaque();
3124  }
3125  
GetSource(Local<Context> context) const3126  MaybeLocal<String> Message::GetSource(Local<Context> context) const {
3127    auto self = Utils::OpenHandle(this);
3128    i::Isolate* isolate = self->GetIsolate();
3129    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3130    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3131    i::Handle<i::String> source(self->GetSource(), isolate);
3132    RETURN_ESCAPED(Utils::ToLocal(source));
3133  }
3134  
GetSourceLine(Local<Context> context) const3135  MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3136    auto self = Utils::OpenHandle(this);
3137    i::Isolate* isolate = self->GetIsolate();
3138    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3139    EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3140    i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3141    RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3142  }
3143  
PrintCurrentStackTrace(Isolate * isolate,std::ostream & out)3144  void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) {
3145    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3146    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3147    i_isolate->PrintCurrentStackTrace(out);
3148  }
3149  
3150  // --- S t a c k T r a c e ---
3151  
GetFrame(Isolate * v8_isolate,uint32_t index) const3152  Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3153                                         uint32_t index) const {
3154    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3155    i::Handle<i::StackFrameInfo> info(
3156        i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate);
3157    return Utils::StackFrameToLocal(info);
3158  }
3159  
GetFrameCount() const3160  int StackTrace::GetFrameCount() const {
3161    return Utils::OpenHandle(this)->length();
3162  }
3163  
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3164  Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3165                                                  int frame_limit,
3166                                                  StackTraceOptions options) {
3167    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3168    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3169    i::Handle<i::FixedArray> stackTrace =
3170        i_isolate->CaptureDetailedStackTrace(frame_limit, options);
3171    return Utils::StackTraceToLocal(stackTrace);
3172  }
3173  
CurrentScriptNameOrSourceURL(Isolate * v8_isolate)3174  Local<String> StackTrace::CurrentScriptNameOrSourceURL(Isolate* v8_isolate) {
3175    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3176    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3177    i::Handle<i::String> name_or_source_url =
3178        isolate->CurrentScriptNameOrSourceURL();
3179    return Utils::ToLocal(name_or_source_url);
3180  }
3181  
3182  // --- S t a c k F r a m e ---
3183  
GetLocation() const3184  Location StackFrame::GetLocation() const {
3185    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3186    i::Isolate* isolate = self->GetIsolate();
3187    i::Handle<i::Script> script(self->script(), isolate);
3188    i::Script::PositionInfo info;
3189    CHECK(i::Script::GetPositionInfo(script,
3190                                     i::StackFrameInfo::GetSourcePosition(self),
3191                                     &info, i::Script::WITH_OFFSET));
3192    if (script->HasSourceURLComment()) {
3193      info.line -= script->line_offset();
3194      if (info.line == 0) {
3195        info.column -= script->column_offset();
3196      }
3197    }
3198    return {info.line, info.column};
3199  }
3200  
GetScriptId() const3201  int StackFrame::GetScriptId() const {
3202    return Utils::OpenHandle(this)->script().id();
3203  }
3204  
GetScriptName() const3205  Local<String> StackFrame::GetScriptName() const {
3206    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3207    i::Isolate* isolate = self->GetIsolate();
3208    i::Handle<i::Object> name(self->script().name(), isolate);
3209    if (!name->IsString()) return {};
3210    return Utils::ToLocal(i::Handle<i::String>::cast(name));
3211  }
3212  
GetScriptNameOrSourceURL() const3213  Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3214    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3215    i::Isolate* isolate = self->GetIsolate();
3216    i::Handle<i::Object> name_or_source_url(self->script().GetNameOrSourceURL(),
3217                                            isolate);
3218    if (!name_or_source_url->IsString()) return {};
3219    return Utils::ToLocal(i::Handle<i::String>::cast(name_or_source_url));
3220  }
3221  
GetScriptSource() const3222  Local<String> StackFrame::GetScriptSource() const {
3223    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3224    i::Isolate* isolate = self->GetIsolate();
3225    if (!self->script().HasValidSource()) return {};
3226    i::Handle<i::PrimitiveHeapObject> source(self->script().source(), isolate);
3227    if (!source->IsString()) return {};
3228    return Utils::ToLocal(i::Handle<i::String>::cast(source));
3229  }
3230  
GetScriptSourceMappingURL() const3231  Local<String> StackFrame::GetScriptSourceMappingURL() const {
3232    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3233    i::Isolate* isolate = self->GetIsolate();
3234    i::Handle<i::Object> source_mapping_url(self->script().source_mapping_url(),
3235                                            isolate);
3236    if (!source_mapping_url->IsString()) return {};
3237    return Utils::ToLocal(i::Handle<i::String>::cast(source_mapping_url));
3238  }
3239  
GetFunctionName() const3240  Local<String> StackFrame::GetFunctionName() const {
3241    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3242    i::Isolate* isolate = self->GetIsolate();
3243    i::Handle<i::String> name(self->function_name(), isolate);
3244    if (name->length() == 0) return {};
3245    return Utils::ToLocal(name);
3246  }
3247  
IsEval() const3248  bool StackFrame::IsEval() const {
3249    i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3250    return self->script().compilation_type() == i::Script::COMPILATION_TYPE_EVAL;
3251  }
3252  
IsConstructor() const3253  bool StackFrame::IsConstructor() const {
3254    return Utils::OpenHandle(this)->is_constructor();
3255  }
3256  
IsWasm() const3257  bool StackFrame::IsWasm() const { return !IsUserJavaScript(); }
3258  
IsUserJavaScript() const3259  bool StackFrame::IsUserJavaScript() const {
3260    return Utils::OpenHandle(this)->script().IsUserJavaScript();
3261  }
3262  
3263  // --- J S O N ---
3264  
Parse(Local<Context> context,Local<String> json_string)3265  MaybeLocal<Value> JSON::Parse(Local<Context> context,
3266                                Local<String> json_string) {
3267    PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3268    i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3269    i::Handle<i::String> source = i::String::Flatten(isolate, string);
3270    i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3271    auto maybe = source->IsOneByteRepresentation()
3272                     ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3273                     : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3274    Local<Value> result;
3275    has_pending_exception = !ToLocal<Value>(maybe, &result);
3276    RETURN_ON_FAILED_EXECUTION(Value);
3277    RETURN_ESCAPED(result);
3278  }
3279  
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3280  MaybeLocal<String> JSON::Stringify(Local<Context> context,
3281                                     Local<Value> json_object,
3282                                     Local<String> gap) {
3283    PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3284    i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3285    i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3286    i::Handle<i::String> gap_string = gap.IsEmpty()
3287                                          ? isolate->factory()->empty_string()
3288                                          : Utils::OpenHandle(*gap);
3289    i::Handle<i::Object> maybe;
3290    has_pending_exception =
3291        !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3292    RETURN_ON_FAILED_EXECUTION(String);
3293    Local<String> result;
3294    has_pending_exception =
3295        !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3296    RETURN_ON_FAILED_EXECUTION(String);
3297    RETURN_ESCAPED(result);
3298  }
3299  
3300  // --- V a l u e   S e r i a l i z a t i o n ---
3301  
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3302  Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3303                                                         Local<Object> object) {
3304    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3305    isolate->ScheduleThrow(*isolate->factory()->NewError(
3306        isolate->error_function(), i::MessageTemplate::kDataCloneError,
3307        Utils::OpenHandle(*object)));
3308    return Nothing<bool>();
3309  }
3310  
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3311  Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3312      Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3313    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3314    isolate->ScheduleThrow(*isolate->factory()->NewError(
3315        isolate->error_function(), i::MessageTemplate::kDataCloneError,
3316        Utils::OpenHandle(*shared_array_buffer)));
3317    return Nothing<uint32_t>();
3318  }
3319  
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3320  Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3321      Isolate* v8_isolate, Local<WasmModuleObject> module) {
3322    return Nothing<uint32_t>();
3323  }
3324  
SupportsSharedValues() const3325  bool ValueSerializer::Delegate::SupportsSharedValues() const { return false; }
3326  
GetSharedValueId(Isolate * v8_isolate,Local<Value> shared_value)3327  Maybe<uint32_t> ValueSerializer::Delegate::GetSharedValueId(
3328      Isolate* v8_isolate, Local<Value> shared_value) {
3329    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3330    isolate->ScheduleThrow(*isolate->factory()->NewError(
3331        isolate->error_function(), i::MessageTemplate::kDataCloneError,
3332        Utils::OpenHandle(*shared_value)));
3333    return Nothing<uint32_t>();
3334  }
3335  
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3336  void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3337                                                          size_t size,
3338                                                          size_t* actual_size) {
3339    *actual_size = size;
3340    return base::Realloc(old_buffer, size);
3341  }
3342  
FreeBufferMemory(void * buffer)3343  void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3344    return base::Free(buffer);
3345  }
3346  
3347  struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3348    explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3349        : isolate(i), serializer(i, delegate) {}
3350    i::Isolate* isolate;
3351    i::ValueSerializer serializer;
3352  };
3353  
ValueSerializer(Isolate * isolate)3354  ValueSerializer::ValueSerializer(Isolate* isolate)
3355      : ValueSerializer(isolate, nullptr) {}
3356  
ValueSerializer(Isolate * isolate,Delegate * delegate)3357  ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3358      : private_(
3359            new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3360  
~ValueSerializer()3361  ValueSerializer::~ValueSerializer() { delete private_; }
3362  
WriteHeader()3363  void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3364  
SetTreatArrayBufferViewsAsHostObjects(bool mode)3365  void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3366    private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3367  }
3368  
WriteValue(Local<Context> context,Local<Value> value)3369  Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3370                                          Local<Value> value) {
3371    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3372    ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3373             i::HandleScope);
3374    i::Handle<i::Object> object = Utils::OpenHandle(*value);
3375    Maybe<bool> result = private_->serializer.WriteObject(object);
3376    has_pending_exception = result.IsNothing();
3377    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3378    return result;
3379  }
3380  
Release()3381  std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3382    return private_->serializer.Release();
3383  }
3384  
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3385  void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3386                                            Local<ArrayBuffer> array_buffer) {
3387    private_->serializer.TransferArrayBuffer(transfer_id,
3388                                             Utils::OpenHandle(*array_buffer));
3389  }
3390  
WriteUint32(uint32_t value)3391  void ValueSerializer::WriteUint32(uint32_t value) {
3392    private_->serializer.WriteUint32(value);
3393  }
3394  
WriteUint64(uint64_t value)3395  void ValueSerializer::WriteUint64(uint64_t value) {
3396    private_->serializer.WriteUint64(value);
3397  }
3398  
WriteDouble(double value)3399  void ValueSerializer::WriteDouble(double value) {
3400    private_->serializer.WriteDouble(value);
3401  }
3402  
WriteRawBytes(const void * source,size_t length)3403  void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3404    private_->serializer.WriteRawBytes(source, length);
3405  }
3406  
ReadHostObject(Isolate * v8_isolate)3407  MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3408      Isolate* v8_isolate) {
3409    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3410    isolate->ScheduleThrow(*isolate->factory()->NewError(
3411        isolate->error_function(),
3412        i::MessageTemplate::kDataCloneDeserializationError));
3413    return MaybeLocal<Object>();
3414  }
3415  
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3416  MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3417      Isolate* v8_isolate, uint32_t id) {
3418    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3419    isolate->ScheduleThrow(*isolate->factory()->NewError(
3420        isolate->error_function(),
3421        i::MessageTemplate::kDataCloneDeserializationError));
3422    return MaybeLocal<WasmModuleObject>();
3423  }
3424  
SupportsSharedValues() const3425  bool ValueDeserializer::Delegate::SupportsSharedValues() const { return false; }
3426  
GetSharedValueFromId(Isolate * v8_isolate,uint32_t shared_value_id)3427  MaybeLocal<Value> ValueDeserializer::Delegate::GetSharedValueFromId(
3428      Isolate* v8_isolate, uint32_t shared_value_id) {
3429    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3430    isolate->ScheduleThrow(*isolate->factory()->NewError(
3431        isolate->error_function(),
3432        i::MessageTemplate::kDataCloneDeserializationError));
3433    return MaybeLocal<Value>();
3434  }
3435  
3436  MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3437  ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3438                                                          uint32_t id) {
3439    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3440    isolate->ScheduleThrow(*isolate->factory()->NewError(
3441        isolate->error_function(),
3442        i::MessageTemplate::kDataCloneDeserializationError));
3443    return MaybeLocal<SharedArrayBuffer>();
3444  }
3445  
3446  struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3447    PrivateData(i::Isolate* i, base::Vector<const uint8_t> data,
3448                Delegate* delegate)
3449        : isolate(i), deserializer(i, data, delegate) {}
3450    i::Isolate* isolate;
3451    i::ValueDeserializer deserializer;
3452    bool supports_legacy_wire_format = false;
3453  };
3454  
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3455  ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3456                                       size_t size)
3457      : ValueDeserializer(isolate, data, size, nullptr) {}
3458  
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3459  ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3460                                       size_t size, Delegate* delegate) {
3461    private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3462                               base::Vector<const uint8_t>(data, size), delegate);
3463  }
3464  
~ValueDeserializer()3465  ValueDeserializer::~ValueDeserializer() { delete private_; }
3466  
ReadHeader(Local<Context> context)3467  Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3468    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3469    ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3470                       Nothing<bool>(), i::HandleScope);
3471  
3472    bool read_header = false;
3473    has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3474    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3475    DCHECK(read_header);
3476  
3477    static const uint32_t kMinimumNonLegacyVersion = 13;
3478    if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3479        !private_->supports_legacy_wire_format) {
3480      isolate->Throw(*isolate->factory()->NewError(
3481          i::MessageTemplate::kDataCloneDeserializationVersionError));
3482      has_pending_exception = true;
3483      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3484    }
3485  
3486    return Just(true);
3487  }
3488  
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3489  void ValueDeserializer::SetSupportsLegacyWireFormat(
3490      bool supports_legacy_wire_format) {
3491    private_->supports_legacy_wire_format = supports_legacy_wire_format;
3492  }
3493  
GetWireFormatVersion() const3494  uint32_t ValueDeserializer::GetWireFormatVersion() const {
3495    return private_->deserializer.GetWireFormatVersion();
3496  }
3497  
ReadValue(Local<Context> context)3498  MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3499    PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3500    i::MaybeHandle<i::Object> result;
3501    if (GetWireFormatVersion() > 0) {
3502      result = private_->deserializer.ReadObjectWrapper();
3503    } else {
3504      result =
3505          private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3506    }
3507    Local<Value> value;
3508    has_pending_exception = !ToLocal(result, &value);
3509    RETURN_ON_FAILED_EXECUTION(Value);
3510    RETURN_ESCAPED(value);
3511  }
3512  
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3513  void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3514                                              Local<ArrayBuffer> array_buffer) {
3515    private_->deserializer.TransferArrayBuffer(transfer_id,
3516                                               Utils::OpenHandle(*array_buffer));
3517  }
3518  
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3519  void ValueDeserializer::TransferSharedArrayBuffer(
3520      uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3521    private_->deserializer.TransferArrayBuffer(
3522        transfer_id, Utils::OpenHandle(*shared_array_buffer));
3523  }
3524  
ReadUint32(uint32_t * value)3525  bool ValueDeserializer::ReadUint32(uint32_t* value) {
3526    return private_->deserializer.ReadUint32(value);
3527  }
3528  
ReadUint64(uint64_t * value)3529  bool ValueDeserializer::ReadUint64(uint64_t* value) {
3530    return private_->deserializer.ReadUint64(value);
3531  }
3532  
ReadDouble(double * value)3533  bool ValueDeserializer::ReadDouble(double* value) {
3534    return private_->deserializer.ReadDouble(value);
3535  }
3536  
ReadRawBytes(size_t length,const void ** data)3537  bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3538    return private_->deserializer.ReadRawBytes(length, data);
3539  }
3540  
3541  // --- D a t a ---
3542  
FullIsUndefined() const3543  bool Value::FullIsUndefined() const {
3544    i::Handle<i::Object> object = Utils::OpenHandle(this);
3545    bool result = object->IsUndefined();
3546    DCHECK_EQ(result, QuickIsUndefined());
3547    return result;
3548  }
3549  
FullIsNull() const3550  bool Value::FullIsNull() const {
3551    i::Handle<i::Object> object = Utils::OpenHandle(this);
3552    bool result = object->IsNull();
3553    DCHECK_EQ(result, QuickIsNull());
3554    return result;
3555  }
3556  
IsTrue() const3557  bool Value::IsTrue() const {
3558    i::Object object = *Utils::OpenHandle(this);
3559    if (object.IsSmi()) return false;
3560    return object.IsTrue();
3561  }
3562  
IsFalse() const3563  bool Value::IsFalse() const {
3564    i::Object object = *Utils::OpenHandle(this);
3565    if (object.IsSmi()) return false;
3566    return object.IsFalse();
3567  }
3568  
IsFunction() const3569  bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3570  
IsName() const3571  bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3572  
FullIsString() const3573  bool Value::FullIsString() const {
3574    bool result = Utils::OpenHandle(this)->IsString();
3575    DCHECK_EQ(result, QuickIsString());
3576    return result;
3577  }
3578  
IsSymbol() const3579  bool Value::IsSymbol() const {
3580    return Utils::OpenHandle(this)->IsPublicSymbol();
3581  }
3582  
IsArray() const3583  bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3584  
IsArrayBuffer() const3585  bool Value::IsArrayBuffer() const {
3586    i::Object obj = *Utils::OpenHandle(this);
3587    if (!obj.IsJSArrayBuffer()) return false;
3588    return !i::JSArrayBuffer::cast(obj).is_shared();
3589  }
3590  
IsArrayBufferView() const3591  bool Value::IsArrayBufferView() const {
3592    return Utils::OpenHandle(this)->IsJSArrayBufferView();
3593  }
3594  
IsTypedArray() const3595  bool Value::IsTypedArray() const {
3596    return Utils::OpenHandle(this)->IsJSTypedArray();
3597  }
3598  
3599  #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype)                   \
3600    bool Value::Is##Type##Array() const {                                     \
3601      i::Handle<i::Object> obj = Utils::OpenHandle(this);                     \
3602      return obj->IsJSTypedArray() &&                                         \
3603             i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3604    }
3605  
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3606  TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3607  
3608  #undef VALUE_IS_TYPED_ARRAY
3609  
3610  bool Value::IsDataView() const {
3611    return Utils::OpenHandle(this)->IsJSDataView();
3612  }
3613  
IsSharedArrayBuffer() const3614  bool Value::IsSharedArrayBuffer() const {
3615    i::Object obj = *Utils::OpenHandle(this);
3616    if (!obj.IsJSArrayBuffer()) return false;
3617    return i::JSArrayBuffer::cast(obj).is_shared();
3618  }
3619  
IsObject() const3620  bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3621  
IsNumber() const3622  bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3623  
IsBigInt() const3624  bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3625  
IsProxy() const3626  bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3627  
3628  #define VALUE_IS_SPECIFIC_TYPE(Type, Check)             \
3629    bool Value::Is##Type() const {                        \
3630      i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3631      return obj->Is##Check();                            \
3632    }
3633  
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3634  VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3635  VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3636  VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3637  VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3638  VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3639  VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3640  VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3641  VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3642  VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3643  #if V8_ENABLE_WEBASSEMBLY
3644  VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3645  VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3646  #else
3647  bool Value::IsWasmMemoryObject() const { return false; }
3648  bool Value::IsWasmModuleObject() const { return false; }
3649  #endif  // V8_ENABLE_WEBASSEMBLY
3650  VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3651  VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3652  
3653  #undef VALUE_IS_SPECIFIC_TYPE
3654  
3655  bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3656  
IsExternal() const3657  bool Value::IsExternal() const {
3658    i::Object obj = *Utils::OpenHandle(this);
3659    return obj.IsJSExternalObject();
3660  }
3661  
IsInt32() const3662  bool Value::IsInt32() const {
3663    i::Object obj = *Utils::OpenHandle(this);
3664    if (obj.IsSmi()) return true;
3665    if (obj.IsNumber()) {
3666      return i::IsInt32Double(obj.Number());
3667    }
3668    return false;
3669  }
3670  
IsUint32() const3671  bool Value::IsUint32() const {
3672    i::Handle<i::Object> obj = Utils::OpenHandle(this);
3673    if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3674    if (obj->IsNumber()) {
3675      double value = obj->Number();
3676      return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3677             value == i::FastUI2D(i::FastD2UI(value));
3678    }
3679    return false;
3680  }
3681  
IsNativeError() const3682  bool Value::IsNativeError() const {
3683    return Utils::OpenHandle(this)->IsJSError();
3684  }
3685  
IsRegExp() const3686  bool Value::IsRegExp() const {
3687    i::Handle<i::Object> obj = Utils::OpenHandle(this);
3688    return obj->IsJSRegExp();
3689  }
3690  
IsAsyncFunction() const3691  bool Value::IsAsyncFunction() const {
3692    i::Object obj = *Utils::OpenHandle(this);
3693    if (!obj.IsJSFunction()) return false;
3694    i::JSFunction func = i::JSFunction::cast(obj);
3695    return i::IsAsyncFunction(func.shared().kind());
3696  }
3697  
IsGeneratorFunction() const3698  bool Value::IsGeneratorFunction() const {
3699    i::Object obj = *Utils::OpenHandle(this);
3700    if (!obj.IsJSFunction()) return false;
3701    i::JSFunction func = i::JSFunction::cast(obj);
3702    ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
3703    return i::IsGeneratorFunction(func.shared().kind());
3704  }
3705  
IsGeneratorObject() const3706  bool Value::IsGeneratorObject() const {
3707    return Utils::OpenHandle(this)->IsJSGeneratorObject();
3708  }
3709  
IsMapIterator() const3710  bool Value::IsMapIterator() const {
3711    return Utils::OpenHandle(this)->IsJSMapIterator();
3712  }
3713  
IsSetIterator() const3714  bool Value::IsSetIterator() const {
3715    return Utils::OpenHandle(this)->IsJSSetIterator();
3716  }
3717  
IsPromise() const3718  bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3719  
IsModuleNamespaceObject() const3720  bool Value::IsModuleNamespaceObject() const {
3721    return Utils::OpenHandle(this)->IsJSModuleNamespace();
3722  }
3723  
ToString(Local<Context> context) const3724  MaybeLocal<String> Value::ToString(Local<Context> context) const {
3725    auto obj = Utils::OpenHandle(this);
3726    if (obj->IsString()) return ToApiHandle<String>(obj);
3727    PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3728    Local<String> result;
3729    has_pending_exception =
3730        !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3731    RETURN_ON_FAILED_EXECUTION(String);
3732    RETURN_ESCAPED(result);
3733  }
3734  
ToDetailString(Local<Context> context) const3735  MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3736    i::Handle<i::Object> obj = Utils::OpenHandle(this);
3737    if (obj->IsString()) return ToApiHandle<String>(obj);
3738    PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3739    Local<String> result =
3740        Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3741    RETURN_ON_FAILED_EXECUTION(String);
3742    RETURN_ESCAPED(result);
3743  }
3744  
ToObject(Local<Context> context) const3745  MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3746    auto obj = Utils::OpenHandle(this);
3747    if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3748    PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3749    Local<Object> result;
3750    has_pending_exception =
3751        !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3752    RETURN_ON_FAILED_EXECUTION(Object);
3753    RETURN_ESCAPED(result);
3754  }
3755  
ToBigInt(Local<Context> context) const3756  MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3757    i::Handle<i::Object> obj = Utils::OpenHandle(this);
3758    if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3759    PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3760    Local<BigInt> result;
3761    has_pending_exception =
3762        !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3763    RETURN_ON_FAILED_EXECUTION(BigInt);
3764    RETURN_ESCAPED(result);
3765  }
3766  
BooleanValue(Isolate * v8_isolate) const3767  bool Value::BooleanValue(Isolate* v8_isolate) const {
3768    return Utils::OpenHandle(this)->BooleanValue(
3769        reinterpret_cast<i::Isolate*>(v8_isolate));
3770  }
3771  
ToBoolean(Isolate * v8_isolate) const3772  Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3773    auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3774    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3775    return ToApiHandle<Boolean>(
3776        isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3777  }
3778  
ToNumber(Local<Context> context) const3779  MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3780    auto obj = Utils::OpenHandle(this);
3781    if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3782    PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3783    Local<Number> result;
3784    has_pending_exception =
3785        !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3786    RETURN_ON_FAILED_EXECUTION(Number);
3787    RETURN_ESCAPED(result);
3788  }
3789  
ToInteger(Local<Context> context) const3790  MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3791    auto obj = Utils::OpenHandle(this);
3792    if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3793    PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3794    Local<Integer> result;
3795    has_pending_exception =
3796        !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3797    RETURN_ON_FAILED_EXECUTION(Integer);
3798    RETURN_ESCAPED(result);
3799  }
3800  
ToInt32(Local<Context> context) const3801  MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3802    auto obj = Utils::OpenHandle(this);
3803    if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3804    Local<Int32> result;
3805    PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3806    has_pending_exception =
3807        !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3808    RETURN_ON_FAILED_EXECUTION(Int32);
3809    RETURN_ESCAPED(result);
3810  }
3811  
ToUint32(Local<Context> context) const3812  MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3813    auto obj = Utils::OpenHandle(this);
3814    if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3815    Local<Uint32> result;
3816    PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3817    has_pending_exception =
3818        !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3819    RETURN_ON_FAILED_EXECUTION(Uint32);
3820    RETURN_ESCAPED(result);
3821  }
3822  
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3823  i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3824                                          i::ExternalPointer_t encoded_pointer,
3825                                          ExternalPointerTag tag) {
3826    return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3827  }
3828  
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3829  i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3830    return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3831  }
3832  
ShouldThrowOnError(i::Isolate * isolate)3833  bool i::ShouldThrowOnError(i::Isolate* isolate) {
3834    return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3835           i::ShouldThrow::kThrowOnError;
3836  }
3837  
CanHaveInternalField(int instance_type)3838  bool i::CanHaveInternalField(int instance_type) {
3839    return instance_type == i::Internals::kJSObjectType ||
3840           instance_type == i::Internals::kJSSpecialApiObjectType ||
3841           v8::internal::InstanceTypeChecker::IsJSApiObject(
3842               static_cast<v8::internal::InstanceType>(instance_type));
3843  }
3844  
CheckInitializedImpl(v8::Isolate * external_isolate)3845  void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3846    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3847    Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3848                    "v8::internal::Internals::CheckInitialized",
3849                    "Isolate is not initialized or V8 has died");
3850  }
3851  
CheckCast(Data * that)3852  void v8::Value::CheckCast(Data* that) {
3853    Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3854  }
3855  
CheckCast(v8::Value * that)3856  void External::CheckCast(v8::Value* that) {
3857    Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3858                    "Value is not an External");
3859  }
3860  
CheckCast(Value * that)3861  void v8::Object::CheckCast(Value* that) {
3862    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3863    Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3864                    "Value is not an Object");
3865  }
3866  
CheckCast(Value * that)3867  void v8::Function::CheckCast(Value* that) {
3868    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3869    Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3870                    "Value is not a Function");
3871  }
3872  
CheckCast(v8::Data * that)3873  void v8::Boolean::CheckCast(v8::Data* that) {
3874    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3875    Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3876                    "Value is not a Boolean");
3877  }
3878  
CheckCast(v8::Data * that)3879  void v8::Name::CheckCast(v8::Data* that) {
3880    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3881    Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3882  }
3883  
CheckCast(v8::Data * that)3884  void v8::String::CheckCast(v8::Data* that) {
3885    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3886    Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3887  }
3888  
CheckCast(v8::Data * that)3889  void v8::Symbol::CheckCast(v8::Data* that) {
3890    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3891    Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3892  }
3893  
CheckCast(v8::Data * that)3894  void v8::Private::CheckCast(v8::Data* that) {
3895    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3896    Utils::ApiCheck(
3897        obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3898        "v8::Private::Cast", "Value is not a Private");
3899  }
3900  
CheckCast(v8::Data * that)3901  void v8::FixedArray::CheckCast(v8::Data* that) {
3902    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3903    Utils::ApiCheck(obj->IsFixedArray(), "v8::FixedArray::Cast",
3904                    "Value is not a FixedArray");
3905  }
3906  
CheckCast(v8::Data * that)3907  void v8::ModuleRequest::CheckCast(v8::Data* that) {
3908    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3909    Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast",
3910                    "Value is not a ModuleRequest");
3911  }
3912  
CheckCast(v8::Data * that)3913  void v8::Module::CheckCast(v8::Data* that) {
3914    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3915    Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3916  }
3917  
CheckCast(v8::Data * that)3918  void v8::Number::CheckCast(v8::Data* that) {
3919    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3920    Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3921                    "Value is not a Number");
3922  }
3923  
CheckCast(v8::Data * that)3924  void v8::Integer::CheckCast(v8::Data* that) {
3925    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3926    Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3927                    "Value is not an Integer");
3928  }
3929  
CheckCast(v8::Data * that)3930  void v8::Int32::CheckCast(v8::Data* that) {
3931    Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast",
3932                    "Value is not a 32-bit signed integer");
3933  }
3934  
CheckCast(v8::Data * that)3935  void v8::Uint32::CheckCast(v8::Data* that) {
3936    Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast",
3937                    "Value is not a 32-bit unsigned integer");
3938  }
3939  
CheckCast(v8::Data * that)3940  void v8::BigInt::CheckCast(v8::Data* that) {
3941    Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3942                    "Value is not a BigInt");
3943  }
3944  
CheckCast(v8::Data * that)3945  void v8::Context::CheckCast(v8::Data* that) {
3946    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3947    Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast",
3948                    "Value is not a Context");
3949  }
3950  
CheckCast(Value * that)3951  void v8::Array::CheckCast(Value* that) {
3952    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3953    Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3954  }
3955  
CheckCast(Value * that)3956  void v8::Map::CheckCast(Value* that) {
3957    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3958    Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3959  }
3960  
CheckCast(Value * that)3961  void v8::Set::CheckCast(Value* that) {
3962    i::Handle<i::Object> obj = Utils::OpenHandle(that);
3963    Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3964  }
3965  
CheckCast(Value * that)3966  void v8::Promise::CheckCast(Value* that) {
3967    Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3968                    "Value is not a Promise");
3969  }
3970  
CheckCast(Value * that)3971  void v8::Promise::Resolver::CheckCast(Value* that) {
3972    Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3973                    "Value is not a Promise::Resolver");
3974  }
3975  
CheckCast(Value * that)3976  void v8::Proxy::CheckCast(Value* that) {
3977    Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3978  }
3979  
CheckCast(Value * that)3980  void v8::WasmMemoryObject::CheckCast(Value* that) {
3981    Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3982                    "Value is not a WasmMemoryObject");
3983  }
3984  
CheckCast(Value * that)3985  void v8::WasmModuleObject::CheckCast(Value* that) {
3986    Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3987                    "Value is not a WasmModuleObject");
3988  }
3989  
~BackingStore()3990  v8::BackingStore::~BackingStore() {
3991    auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3992    i_this->~BackingStore();  // manually call internal destructor
3993  }
3994  
Data() const3995  void* v8::BackingStore::Data() const {
3996    return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3997  }
3998  
ByteLength() const3999  size_t v8::BackingStore::ByteLength() const {
4000    return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
4001  }
4002  
IsShared() const4003  bool v8::BackingStore::IsShared() const {
4004    return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
4005  }
4006  
4007  // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)4008  std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
4009      v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
4010      size_t byte_length) {
4011    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
4012    API_RCS_SCOPE(i_isolate, ArrayBuffer, BackingStore_Reallocate);
4013    Utils::ApiCheck(byte_length <= i::JSArrayBuffer::kMaxByteLength,
4014                    "v8::BackingStore::Reallocate", "byte_lenght is too large");
4015    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
4016    i::BackingStore* i_backing_store =
4017        reinterpret_cast<i::BackingStore*>(backing_store.get());
4018    if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
4019      i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
4020    }
4021    return backing_store;
4022  }
4023  
4024  // static
EmptyDeleter(void * data,size_t length,void * deleter_data)4025  void v8::BackingStore::EmptyDeleter(void* data, size_t length,
4026                                      void* deleter_data) {
4027    DCHECK_NULL(deleter_data);
4028  }
4029  
GetBackingStore()4030  std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
4031    i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4032    std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4033    if (!backing_store) {
4034      backing_store =
4035          i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
4036    }
4037    std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4038    return std::static_pointer_cast<v8::BackingStore>(bs_base);
4039  }
4040  
Data() const4041  void* v8::ArrayBuffer::Data() const {
4042    i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4043    return self->backing_store();
4044  }
4045  
GetBackingStore()4046  std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
4047    i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4048    std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4049    if (!backing_store) {
4050      backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
4051    }
4052    std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4053    return std::static_pointer_cast<v8::BackingStore>(bs_base);
4054  }
4055  
Data() const4056  void* v8::SharedArrayBuffer::Data() const {
4057    i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4058    return self->backing_store();
4059  }
4060  
CheckCast(Value * that)4061  void v8::ArrayBuffer::CheckCast(Value* that) {
4062    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4063    Utils::ApiCheck(
4064        obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
4065        "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
4066  }
4067  
CheckCast(Value * that)4068  void v8::ArrayBufferView::CheckCast(Value* that) {
4069    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4070    Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
4071                    "Value is not an ArrayBufferView");
4072  }
4073  
4074  constexpr size_t v8::TypedArray::kMaxLength;
4075  
CheckCast(Value * that)4076  void v8::TypedArray::CheckCast(Value* that) {
4077    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4078    Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
4079                    "Value is not a TypedArray");
4080  }
4081  
4082  #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype)                  \
4083    void v8::Type##Array::CheckCast(Value* that) {                             \
4084      i::Handle<i::Object> obj = Utils::OpenHandle(that);                      \
4085      Utils::ApiCheck(                                                         \
4086          obj->IsJSTypedArray() &&                                             \
4087              i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
4088          "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array");      \
4089    }
4090  
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)4091  TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4092  
4093  #undef CHECK_TYPED_ARRAY_CAST
4094  
4095  void v8::DataView::CheckCast(Value* that) {
4096    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4097    Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
4098                    "Value is not a DataView");
4099  }
4100  
CheckCast(Value * that)4101  void v8::SharedArrayBuffer::CheckCast(Value* that) {
4102    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4103    Utils::ApiCheck(
4104        obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
4105        "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
4106  }
4107  
CheckCast(v8::Value * that)4108  void v8::Date::CheckCast(v8::Value* that) {
4109    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4110    Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
4111  }
4112  
CheckCast(v8::Value * that)4113  void v8::StringObject::CheckCast(v8::Value* that) {
4114    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4115    Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
4116                    "Value is not a StringObject");
4117  }
4118  
CheckCast(v8::Value * that)4119  void v8::SymbolObject::CheckCast(v8::Value* that) {
4120    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4121    Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
4122                    "Value is not a SymbolObject");
4123  }
4124  
CheckCast(v8::Value * that)4125  void v8::NumberObject::CheckCast(v8::Value* that) {
4126    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4127    Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
4128                    "Value is not a NumberObject");
4129  }
4130  
CheckCast(v8::Value * that)4131  void v8::BigIntObject::CheckCast(v8::Value* that) {
4132    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4133    Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
4134                    "Value is not a BigIntObject");
4135  }
4136  
CheckCast(v8::Value * that)4137  void v8::BooleanObject::CheckCast(v8::Value* that) {
4138    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4139    Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
4140                    "Value is not a BooleanObject");
4141  }
4142  
CheckCast(v8::Value * that)4143  void v8::RegExp::CheckCast(v8::Value* that) {
4144    i::Handle<i::Object> obj = Utils::OpenHandle(that);
4145    Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
4146                    "Value is not a RegExp");
4147  }
4148  
NumberValue(Local<Context> context) const4149  Maybe<double> Value::NumberValue(Local<Context> context) const {
4150    auto obj = Utils::OpenHandle(this);
4151    if (obj->IsNumber()) return Just(obj->Number());
4152    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4153    ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4154             i::HandleScope);
4155    i::Handle<i::Object> num;
4156    has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
4157    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4158    return Just(num->Number());
4159  }
4160  
IntegerValue(Local<Context> context) const4161  Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4162    auto obj = Utils::OpenHandle(this);
4163    if (obj->IsNumber()) {
4164      return Just(NumberToInt64(*obj));
4165    }
4166    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4167    ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4168             i::HandleScope);
4169    i::Handle<i::Object> num;
4170    has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4171    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4172    return Just(NumberToInt64(*num));
4173  }
4174  
Int32Value(Local<Context> context) const4175  Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4176    auto obj = Utils::OpenHandle(this);
4177    if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4178    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4179    ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4180             i::HandleScope);
4181    i::Handle<i::Object> num;
4182    has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4183    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4184    return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4185                             : static_cast<int32_t>(num->Number()));
4186  }
4187  
Uint32Value(Local<Context> context) const4188  Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4189    auto obj = Utils::OpenHandle(this);
4190    if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4191    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4192    ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4193             i::HandleScope);
4194    i::Handle<i::Object> num;
4195    has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4196    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4197    return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4198                             : static_cast<uint32_t>(num->Number()));
4199  }
4200  
ToArrayIndex(Local<Context> context) const4201  MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4202    auto self = Utils::OpenHandle(this);
4203    if (self->IsSmi()) {
4204      if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4205      return Local<Uint32>();
4206    }
4207    PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4208    i::Handle<i::Object> string_obj;
4209    has_pending_exception =
4210        !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4211    RETURN_ON_FAILED_EXECUTION(Uint32);
4212    i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4213    uint32_t index;
4214    if (str->AsArrayIndex(&index)) {
4215      i::Handle<i::Object> value;
4216      if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4217        value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4218      } else {
4219        value = isolate->factory()->NewNumber(index);
4220      }
4221      RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4222    }
4223    return Local<Uint32>();
4224  }
4225  
Equals(Local<Context> context,Local<Value> that) const4226  Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4227    i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4228    ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope);
4229    auto self = Utils::OpenHandle(this);
4230    auto other = Utils::OpenHandle(*that);
4231    Maybe<bool> result = i::Object::Equals(isolate, self, other);
4232    has_pending_exception = result.IsNothing();
4233    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4234    return result;
4235  }
4236  
StrictEquals(Local<Value> that) const4237  bool Value::StrictEquals(Local<Value> that) const {
4238    auto self = Utils::OpenHandle(this);
4239    auto other = Utils::OpenHandle(*that);
4240    return self->StrictEquals(*other);
4241  }
4242  
SameValue(Local<Value> that) const4243  bool Value::SameValue(Local<Value> that) const {
4244    auto self = Utils::OpenHandle(this);
4245    auto other = Utils::OpenHandle(*that);
4246    return self->SameValue(*other);
4247  }
4248  
TypeOf(v8::Isolate * external_isolate)4249  Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4250    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4251    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4252    API_RCS_SCOPE(isolate, Value, TypeOf);
4253    return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4254  }
4255  
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4256  Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4257                                v8::Local<v8::Object> object) {
4258    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4259    ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4260             i::HandleScope);
4261    auto left = Utils::OpenHandle(this);
4262    auto right = Utils::OpenHandle(*object);
4263    i::Handle<i::Object> result;
4264    has_pending_exception =
4265        !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4266    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4267    return Just(result->IsTrue(isolate));
4268  }
4269  
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4270  Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4271                              v8::Local<Value> key, v8::Local<Value> value) {
4272    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4273    ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4274    auto self = Utils::OpenHandle(this);
4275    auto key_obj = Utils::OpenHandle(*key);
4276    auto value_obj = Utils::OpenHandle(*value);
4277    has_pending_exception =
4278        i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4279                                      i::StoreOrigin::kMaybeKeyed,
4280                                      Just(i::ShouldThrow::kDontThrow))
4281            .is_null();
4282    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4283    return Just(true);
4284  }
4285  
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4286  Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4287                              v8::Local<Value> value) {
4288    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4289    ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4290    auto self = Utils::OpenHandle(this);
4291    auto value_obj = Utils::OpenHandle(*value);
4292    has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4293                                                  i::ShouldThrow::kDontThrow)
4294                                .is_null();
4295    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4296    return Just(true);
4297  }
4298  
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4299  Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4300                                             v8::Local<Name> key,
4301                                             v8::Local<Value> value) {
4302    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4303    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4304    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4305    i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4306  
4307    i::PropertyKey lookup_key(isolate, key_obj);
4308    i::LookupIterator it(isolate, self, lookup_key, i::LookupIterator::OWN);
4309    if (self->IsJSProxy()) {
4310      ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4311               i::HandleScope);
4312      Maybe<bool> result =
4313          i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4314      has_pending_exception = result.IsNothing();
4315      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4316      return result;
4317    } else {
4318      ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4319                         Nothing<bool>(), i::HandleScope);
4320      Maybe<bool> result =
4321          i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4322      has_pending_exception = result.IsNothing();
4323      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4324      return result;
4325    }
4326  }
4327  
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4328  Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4329                                             uint32_t index,
4330                                             v8::Local<Value> value) {
4331    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4332    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4333    i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4334  
4335    i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4336    if (self->IsJSProxy()) {
4337      ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4338               i::HandleScope);
4339      Maybe<bool> result =
4340          i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4341      has_pending_exception = result.IsNothing();
4342      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4343      return result;
4344    } else {
4345      ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4346                         Nothing<bool>(), i::HandleScope);
4347      Maybe<bool> result =
4348          i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4349      has_pending_exception = result.IsNothing();
4350      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4351      return result;
4352    }
4353  }
4354  
4355  struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4356    PrivateData() : desc() {}
4357    i::PropertyDescriptor desc;
4358  };
4359  
PropertyDescriptor()4360  v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4361  
4362  // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4363  v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4364      : private_(new PrivateData()) {
4365    private_->desc.set_value(Utils::OpenHandle(*value, true));
4366  }
4367  
4368  // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4369  v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4370                                             bool writable)
4371      : private_(new PrivateData()) {
4372    private_->desc.set_value(Utils::OpenHandle(*value, true));
4373    private_->desc.set_writable(writable);
4374  }
4375  
4376  // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4377  v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4378                                             v8::Local<v8::Value> set)
4379      : private_(new PrivateData()) {
4380    DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4381    DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4382    private_->desc.set_get(Utils::OpenHandle(*get, true));
4383    private_->desc.set_set(Utils::OpenHandle(*set, true));
4384  }
4385  
~PropertyDescriptor()4386  v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4387  
value() const4388  v8::Local<Value> v8::PropertyDescriptor::value() const {
4389    DCHECK(private_->desc.has_value());
4390    return Utils::ToLocal(private_->desc.value());
4391  }
4392  
get() const4393  v8::Local<Value> v8::PropertyDescriptor::get() const {
4394    DCHECK(private_->desc.has_get());
4395    return Utils::ToLocal(private_->desc.get());
4396  }
4397  
set() const4398  v8::Local<Value> v8::PropertyDescriptor::set() const {
4399    DCHECK(private_->desc.has_set());
4400    return Utils::ToLocal(private_->desc.set());
4401  }
4402  
has_value() const4403  bool v8::PropertyDescriptor::has_value() const {
4404    return private_->desc.has_value();
4405  }
has_get() const4406  bool v8::PropertyDescriptor::has_get() const {
4407    return private_->desc.has_get();
4408  }
has_set() const4409  bool v8::PropertyDescriptor::has_set() const {
4410    return private_->desc.has_set();
4411  }
4412  
writable() const4413  bool v8::PropertyDescriptor::writable() const {
4414    DCHECK(private_->desc.has_writable());
4415    return private_->desc.writable();
4416  }
4417  
has_writable() const4418  bool v8::PropertyDescriptor::has_writable() const {
4419    return private_->desc.has_writable();
4420  }
4421  
set_enumerable(bool enumerable)4422  void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4423    private_->desc.set_enumerable(enumerable);
4424  }
4425  
enumerable() const4426  bool v8::PropertyDescriptor::enumerable() const {
4427    DCHECK(private_->desc.has_enumerable());
4428    return private_->desc.enumerable();
4429  }
4430  
has_enumerable() const4431  bool v8::PropertyDescriptor::has_enumerable() const {
4432    return private_->desc.has_enumerable();
4433  }
4434  
set_configurable(bool configurable)4435  void v8::PropertyDescriptor::set_configurable(bool configurable) {
4436    private_->desc.set_configurable(configurable);
4437  }
4438  
configurable() const4439  bool v8::PropertyDescriptor::configurable() const {
4440    DCHECK(private_->desc.has_configurable());
4441    return private_->desc.configurable();
4442  }
4443  
has_configurable() const4444  bool v8::PropertyDescriptor::has_configurable() const {
4445    return private_->desc.has_configurable();
4446  }
4447  
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4448  Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4449                                            v8::Local<Name> key,
4450                                            v8::Local<Value> value,
4451                                            v8::PropertyAttribute attributes) {
4452    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4453    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4454    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4455    i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4456  
4457    i::PropertyDescriptor desc;
4458    desc.set_writable(!(attributes & v8::ReadOnly));
4459    desc.set_enumerable(!(attributes & v8::DontEnum));
4460    desc.set_configurable(!(attributes & v8::DontDelete));
4461    desc.set_value(value_obj);
4462  
4463    if (self->IsJSProxy()) {
4464      ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4465               i::HandleScope);
4466      Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4467          isolate, self, key_obj, &desc, Just(i::kDontThrow));
4468      // Even though we said kDontThrow, there might be accessors that do throw.
4469      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4470      return success;
4471    } else {
4472      // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4473      // a script.
4474      ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4475                         Nothing<bool>(), i::HandleScope);
4476      Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4477          isolate, self, key_obj, &desc, Just(i::kDontThrow));
4478      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4479      return success;
4480    }
4481  }
4482  
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4483  Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4484                                         v8::Local<Name> key,
4485                                         PropertyDescriptor& descriptor) {
4486    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4487    ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4488             i::HandleScope);
4489    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4490    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4491  
4492    Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4493        isolate, self, key_obj, &descriptor.get_private()->desc,
4494        Just(i::kDontThrow));
4495    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4496    return success;
4497  }
4498  
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4499  Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4500                                     Local<Value> value) {
4501    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4502    ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4503                       i::HandleScope);
4504    auto self = Utils::OpenHandle(this);
4505    auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4506    auto value_obj = Utils::OpenHandle(*value);
4507    if (self->IsJSProxy()) {
4508      i::PropertyDescriptor desc;
4509      desc.set_writable(true);
4510      desc.set_enumerable(false);
4511      desc.set_configurable(true);
4512      desc.set_value(value_obj);
4513      return i::JSProxy::SetPrivateSymbol(
4514          isolate, i::Handle<i::JSProxy>::cast(self),
4515          i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4516    }
4517    auto js_object = i::Handle<i::JSObject>::cast(self);
4518    i::LookupIterator it(isolate, js_object, key_obj, js_object);
4519    has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4520                                &it, value_obj, i::DONT_ENUM)
4521                                .is_null();
4522    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4523    return Just(true);
4524  }
4525  
Get(Local<v8::Context> context,Local<Value> key)4526  MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4527                                    Local<Value> key) {
4528    PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4529    auto self = Utils::OpenHandle(this);
4530    auto key_obj = Utils::OpenHandle(*key);
4531    i::Handle<i::Object> result;
4532    has_pending_exception =
4533        !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4534    RETURN_ON_FAILED_EXECUTION(Value);
4535    RETURN_ESCAPED(Utils::ToLocal(result));
4536  }
4537  
Get(Local<Context> context,uint32_t index)4538  MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4539    PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4540    auto self = Utils::OpenHandle(this);
4541    i::Handle<i::Object> result;
4542    has_pending_exception =
4543        !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4544    RETURN_ON_FAILED_EXECUTION(Value);
4545    RETURN_ESCAPED(Utils::ToLocal(result));
4546  }
4547  
GetPrivate(Local<Context> context,Local<Private> key)4548  MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4549                                           Local<Private> key) {
4550    return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4551  }
4552  
GetPropertyAttributes(Local<Context> context,Local<Value> key)4553  Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4554      Local<Context> context, Local<Value> key) {
4555    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4556    ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4557             Nothing<PropertyAttribute>(), i::HandleScope);
4558    auto self = Utils::OpenHandle(this);
4559    auto key_obj = Utils::OpenHandle(*key);
4560    if (!key_obj->IsName()) {
4561      has_pending_exception =
4562          !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4563      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4564    }
4565    auto key_name = i::Handle<i::Name>::cast(key_obj);
4566    auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4567    has_pending_exception = result.IsNothing();
4568    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4569    if (result.FromJust() == i::ABSENT) {
4570      return Just(static_cast<PropertyAttribute>(i::NONE));
4571    }
4572    return Just(static_cast<PropertyAttribute>(result.FromJust()));
4573  }
4574  
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4575  MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4576                                                         Local<Name> key) {
4577    PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4578    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4579    i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4580  
4581    i::PropertyDescriptor desc;
4582    Maybe<bool> found =
4583        i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4584    has_pending_exception = found.IsNothing();
4585    RETURN_ON_FAILED_EXECUTION(Value);
4586    if (!found.FromJust()) {
4587      return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4588    }
4589    RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4590  }
4591  
GetPrototype()4592  Local<Value> v8::Object::GetPrototype() {
4593    auto self = Utils::OpenHandle(this);
4594    auto isolate = self->GetIsolate();
4595    i::PrototypeIterator iter(isolate, self);
4596    return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4597  }
4598  
SetPrototype(Local<Context> context,Local<Value> value)4599  Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4600                                       Local<Value> value) {
4601    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4602    auto self = Utils::OpenHandle(this);
4603    auto value_obj = Utils::OpenHandle(*value);
4604    if (self->IsJSProxy()) {
4605      ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4606               i::HandleScope);
4607      // We do not allow exceptions thrown while setting the prototype
4608      // to propagate outside.
4609      TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4610      auto result =
4611          i::JSProxy::SetPrototype(isolate, i::Handle<i::JSProxy>::cast(self),
4612                                   value_obj, false, i::kThrowOnError);
4613      has_pending_exception = result.IsNothing();
4614      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4615    } else {
4616      ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4617      auto result =
4618          i::JSObject::SetPrototype(isolate, i::Handle<i::JSObject>::cast(self),
4619                                    value_obj, false, i::kThrowOnError);
4620      if (result.IsNothing()) {
4621        isolate->clear_pending_exception();
4622        return Nothing<bool>();
4623      }
4624    }
4625    return Just(true);
4626  }
4627  
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4628  Local<Object> v8::Object::FindInstanceInPrototypeChain(
4629      v8::Local<FunctionTemplate> tmpl) {
4630    auto self = Utils::OpenHandle(this);
4631    auto isolate = self->GetIsolate();
4632    i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4633    auto tmpl_info = *Utils::OpenHandle(*tmpl);
4634    while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4635      iter.Advance();
4636      if (iter.IsAtEnd()) return Local<Object>();
4637      if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4638    }
4639    // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4640    return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4641  }
4642  
GetPropertyNames(Local<Context> context)4643  MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4644    return GetPropertyNames(
4645        context, v8::KeyCollectionMode::kIncludePrototypes,
4646        static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4647        v8::IndexFilter::kIncludeIndices);
4648  }
4649  
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4650  MaybeLocal<Array> v8::Object::GetPropertyNames(
4651      Local<Context> context, KeyCollectionMode mode,
4652      PropertyFilter property_filter, IndexFilter index_filter,
4653      KeyConversionMode key_conversion) {
4654    PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4655    auto self = Utils::OpenHandle(this);
4656    i::Handle<i::FixedArray> value;
4657    i::KeyAccumulator accumulator(
4658        isolate, static_cast<i::KeyCollectionMode>(mode),
4659        static_cast<i::PropertyFilter>(property_filter));
4660    accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4661    has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4662    RETURN_ON_FAILED_EXECUTION(Array);
4663    value =
4664        accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4665    DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4666           self->map().EnumLength() == 0 ||
4667           self->map().instance_descriptors(isolate).enum_cache().keys() !=
4668               *value);
4669    auto result = isolate->factory()->NewJSArrayWithElements(value);
4670    RETURN_ESCAPED(Utils::ToLocal(result));
4671  }
4672  
GetOwnPropertyNames(Local<Context> context)4673  MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4674    return GetOwnPropertyNames(
4675        context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4676  }
4677  
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4678  MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4679      Local<Context> context, PropertyFilter filter,
4680      KeyConversionMode key_conversion) {
4681    return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4682                            v8::IndexFilter::kIncludeIndices, key_conversion);
4683  }
4684  
ObjectProtoToString(Local<Context> context)4685  MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4686    PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4687    auto self = Utils::OpenHandle(this);
4688    Local<Value> result;
4689    has_pending_exception = !ToLocal<Value>(
4690        i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4691                                  nullptr),
4692        &result);
4693    RETURN_ON_FAILED_EXECUTION(String);
4694    RETURN_ESCAPED(Local<String>::Cast(result));
4695  }
4696  
GetConstructorName()4697  Local<String> v8::Object::GetConstructorName() {
4698    auto self = Utils::OpenHandle(this);
4699    // TODO(v8:12547): Support shared objects.
4700    DCHECK(!self->InSharedHeap());
4701    i::Handle<i::String> name =
4702        i::JSReceiver::GetConstructorName(self->GetIsolate(), self);
4703    return Utils::ToLocal(name);
4704  }
4705  
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4706  Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4707                                            IntegrityLevel level) {
4708    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4709    ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4710             i::HandleScope);
4711    auto self = Utils::OpenHandle(this);
4712    i::JSReceiver::IntegrityLevel i_level =
4713        level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4714    Maybe<bool> result =
4715        i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4716    has_pending_exception = result.IsNothing();
4717    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4718    return result;
4719  }
4720  
Delete(Local<Context> context,Local<Value> key)4721  Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4722    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4723    auto self = Utils::OpenHandle(this);
4724    auto key_obj = Utils::OpenHandle(*key);
4725    if (self->IsJSProxy()) {
4726      ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4727      Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4728          isolate, self, key_obj, i::LanguageMode::kSloppy);
4729      has_pending_exception = result.IsNothing();
4730      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4731      return result;
4732    } else {
4733      // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4734      // a script.
4735      ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4736                         i::HandleScope);
4737      Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4738          isolate, self, key_obj, i::LanguageMode::kSloppy);
4739      has_pending_exception = result.IsNothing();
4740      RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4741      return result;
4742    }
4743  }
4744  
DeletePrivate(Local<Context> context,Local<Private> key)4745  Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4746                                        Local<Private> key) {
4747    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4748    // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4749    // any author script.
4750    ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4751                       i::HandleScope);
4752    auto self = Utils::OpenHandle(this);
4753    auto key_obj = Utils::OpenHandle(*key);
4754    Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4755        isolate, self, key_obj, i::LanguageMode::kSloppy);
4756    has_pending_exception = result.IsNothing();
4757    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4758    return result;
4759  }
4760  
Has(Local<Context> context,Local<Value> key)4761  Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4762    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4763    ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4764    auto self = Utils::OpenHandle(this);
4765    auto key_obj = Utils::OpenHandle(*key);
4766    Maybe<bool> maybe = Nothing<bool>();
4767    // Check if the given key is an array index.
4768    uint32_t index = 0;
4769    if (key_obj->ToArrayIndex(&index)) {
4770      maybe = i::JSReceiver::HasElement(isolate, self, index);
4771    } else {
4772      // Convert the key to a name - possibly by calling back into JavaScript.
4773      i::Handle<i::Name> name;
4774      if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4775        maybe = i::JSReceiver::HasProperty(isolate, self, name);
4776      }
4777    }
4778    has_pending_exception = maybe.IsNothing();
4779    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4780    return maybe;
4781  }
4782  
HasPrivate(Local<Context> context,Local<Private> key)4783  Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4784    return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4785  }
4786  
Delete(Local<Context> context,uint32_t index)4787  Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4788    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4789    ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4790    auto self = Utils::OpenHandle(this);
4791    Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4792    has_pending_exception = result.IsNothing();
4793    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4794    return result;
4795  }
4796  
Has(Local<Context> context,uint32_t index)4797  Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4798    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4799    ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4800    auto self = Utils::OpenHandle(this);
4801    auto maybe = i::JSReceiver::HasElement(isolate, self, index);
4802    has_pending_exception = maybe.IsNothing();
4803    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4804    return maybe;
4805  }
4806  
4807  template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4808  static Maybe<bool> ObjectSetAccessor(
4809      Local<Context> context, Object* self, Local<Name> name, Getter getter,
4810      Setter setter, Data data, AccessControl settings,
4811      PropertyAttribute attributes, bool is_special_data_property,
4812      bool replace_on_access, SideEffectType getter_side_effect_type,
4813      SideEffectType setter_side_effect_type) {
4814    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4815    ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4816                       i::HandleScope);
4817    if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4818    i::Handle<i::JSObject> obj =
4819        i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4820    v8::Local<AccessorSignature> signature;
4821    i::Handle<i::AccessorInfo> info =
4822        MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4823                         is_special_data_property, replace_on_access);
4824    info->set_getter_side_effect_type(getter_side_effect_type);
4825    info->set_setter_side_effect_type(setter_side_effect_type);
4826    if (info.is_null()) return Nothing<bool>();
4827    bool fast = obj->HasFastProperties();
4828    i::Handle<i::Object> result;
4829  
4830    i::Handle<i::Name> accessor_name(info->name(), isolate);
4831    i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4832    has_pending_exception =
4833        !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4834             .ToHandle(&result);
4835    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4836    if (result->IsUndefined(isolate)) return Just(false);
4837    if (fast) {
4838      i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4839    }
4840    return Just(true);
4841  }
4842  
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4843  Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4844                                  AccessorNameGetterCallback getter,
4845                                  AccessorNameSetterCallback setter,
4846                                  MaybeLocal<Value> data, AccessControl settings,
4847                                  PropertyAttribute attribute,
4848                                  SideEffectType getter_side_effect_type,
4849                                  SideEffectType setter_side_effect_type) {
4850    return ObjectSetAccessor(context, this, name, getter, setter,
4851                             data.FromMaybe(Local<Value>()), settings, attribute,
4852                             i::FLAG_disable_old_api_accessors, false,
4853                             getter_side_effect_type, setter_side_effect_type);
4854  }
4855  
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4856  void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4857                                   Local<Function> setter,
4858                                   PropertyAttribute attribute,
4859                                   AccessControl settings) {
4860    // TODO(verwaest): Remove |settings|.
4861    DCHECK_EQ(v8::DEFAULT, settings);
4862    auto self = Utils::OpenHandle(this);
4863    i::Isolate* isolate = self->GetIsolate();
4864    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4865    i::HandleScope scope(isolate);
4866    if (!self->IsJSObject()) return;
4867    i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4868    i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4869    if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4870    i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4871                                v8::Utils::OpenHandle(*name), getter_i, setter_i,
4872                                static_cast<i::PropertyAttributes>(attribute));
4873  }
4874  
SetNativeDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4875  Maybe<bool> Object::SetNativeDataProperty(
4876      v8::Local<v8::Context> context, v8::Local<Name> name,
4877      AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4878      v8::Local<Value> data, PropertyAttribute attributes,
4879      SideEffectType getter_side_effect_type,
4880      SideEffectType setter_side_effect_type) {
4881    return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4882                             attributes, true, false, getter_side_effect_type,
4883                             setter_side_effect_type);
4884  }
4885  
SetLazyDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4886  Maybe<bool> Object::SetLazyDataProperty(
4887      v8::Local<v8::Context> context, v8::Local<Name> name,
4888      AccessorNameGetterCallback getter, v8::Local<Value> data,
4889      PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4890      SideEffectType setter_side_effect_type) {
4891    return ObjectSetAccessor(context, this, name, getter,
4892                             static_cast<AccessorNameSetterCallback>(nullptr),
4893                             data, DEFAULT, attributes, true, true,
4894                             getter_side_effect_type, setter_side_effect_type);
4895  }
4896  
HasOwnProperty(Local<Context> context,Local<Name> key)4897  Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4898                                         Local<Name> key) {
4899    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4900    ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4901             i::HandleScope);
4902    auto self = Utils::OpenHandle(this);
4903    auto key_val = Utils::OpenHandle(*key);
4904    auto result = i::JSReceiver::HasOwnProperty(isolate, self, key_val);
4905    has_pending_exception = result.IsNothing();
4906    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4907    return result;
4908  }
4909  
HasOwnProperty(Local<Context> context,uint32_t index)4910  Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4911    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4912    ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4913             i::HandleScope);
4914    auto self = Utils::OpenHandle(this);
4915    auto result = i::JSReceiver::HasOwnProperty(isolate, self, index);
4916    has_pending_exception = result.IsNothing();
4917    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4918    return result;
4919  }
4920  
HasRealNamedProperty(Local<Context> context,Local<Name> key)4921  Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4922                                               Local<Name> key) {
4923    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4924    ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4925                       Nothing<bool>(), i::HandleScope);
4926    auto self = Utils::OpenHandle(this);
4927    if (!self->IsJSObject()) return Just(false);
4928    auto key_val = Utils::OpenHandle(*key);
4929    auto result = i::JSObject::HasRealNamedProperty(
4930        isolate, i::Handle<i::JSObject>::cast(self), key_val);
4931    has_pending_exception = result.IsNothing();
4932    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4933    return result;
4934  }
4935  
HasRealIndexedProperty(Local<Context> context,uint32_t index)4936  Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4937                                                 uint32_t index) {
4938    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4939    ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4940                       Nothing<bool>(), i::HandleScope);
4941    auto self = Utils::OpenHandle(this);
4942    if (!self->IsJSObject()) return Just(false);
4943    auto result = i::JSObject::HasRealElementProperty(
4944        isolate, i::Handle<i::JSObject>::cast(self), index);
4945    has_pending_exception = result.IsNothing();
4946    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4947    return result;
4948  }
4949  
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4950  Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4951                                                       Local<Name> key) {
4952    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4953    ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
4954                       Nothing<bool>(), i::HandleScope);
4955    auto self = Utils::OpenHandle(this);
4956    if (!self->IsJSObject()) return Just(false);
4957    auto key_val = Utils::OpenHandle(*key);
4958    auto result = i::JSObject::HasRealNamedCallbackProperty(
4959        isolate, i::Handle<i::JSObject>::cast(self), key_val);
4960    has_pending_exception = result.IsNothing();
4961    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4962    return result;
4963  }
4964  
HasNamedLookupInterceptor() const4965  bool v8::Object::HasNamedLookupInterceptor() const {
4966    auto self = *Utils::OpenHandle(this);
4967    if (self.IsJSObject()) return false;
4968    return i::JSObject::cast(self).HasNamedInterceptor();
4969  }
4970  
HasIndexedLookupInterceptor() const4971  bool v8::Object::HasIndexedLookupInterceptor() const {
4972    auto self = *Utils::OpenHandle(this);
4973    if (self.IsJSObject()) return false;
4974    return i::JSObject::cast(self).HasIndexedInterceptor();
4975  }
4976  
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4977  MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4978      Local<Context> context, Local<Name> key) {
4979    PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4980                          Value);
4981    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4982    if (!self->IsJSObject()) return MaybeLocal<Value>();
4983    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4984    i::PrototypeIterator iter(isolate, self);
4985    if (iter.IsAtEnd()) return MaybeLocal<Value>();
4986    i::Handle<i::JSReceiver> proto =
4987        i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4988    i::PropertyKey lookup_key(isolate, key_obj);
4989    i::LookupIterator it(isolate, self, lookup_key, proto,
4990                         i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4991    Local<Value> result;
4992    has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4993    RETURN_ON_FAILED_EXECUTION(Value);
4994    if (!it.IsFound()) return MaybeLocal<Value>();
4995    RETURN_ESCAPED(result);
4996  }
4997  
4998  Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4999  v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
5000      Local<Context> context, Local<Name> key) {
5001    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5002    ENTER_V8(isolate, context, Object,
5003             GetRealNamedPropertyAttributesInPrototypeChain,
5004             Nothing<PropertyAttribute>(), i::HandleScope);
5005    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5006    if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
5007    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5008    i::PrototypeIterator iter(isolate, self);
5009    if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
5010    i::Handle<i::JSReceiver> proto =
5011        i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5012    i::PropertyKey lookup_key(isolate, key_obj);
5013    i::LookupIterator it(isolate, self, lookup_key, proto,
5014                         i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5015    Maybe<i::PropertyAttributes> result =
5016        i::JSReceiver::GetPropertyAttributes(&it);
5017    has_pending_exception = result.IsNothing();
5018    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5019    if (!it.IsFound()) return Nothing<PropertyAttribute>();
5020    if (result.FromJust() == i::ABSENT) return Just(None);
5021    return Just(static_cast<PropertyAttribute>(result.FromJust()));
5022  }
5023  
GetRealNamedProperty(Local<Context> context,Local<Name> key)5024  MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
5025                                                     Local<Name> key) {
5026    PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
5027    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5028    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5029    i::PropertyKey lookup_key(isolate, key_obj);
5030    i::LookupIterator it(isolate, self, lookup_key, self,
5031                         i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5032    Local<Value> result;
5033    has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5034    RETURN_ON_FAILED_EXECUTION(Value);
5035    if (!it.IsFound()) return MaybeLocal<Value>();
5036    RETURN_ESCAPED(result);
5037  }
5038  
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)5039  Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5040      Local<Context> context, Local<Name> key) {
5041    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5042    ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
5043             Nothing<PropertyAttribute>(), i::HandleScope);
5044    i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5045    i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5046    i::PropertyKey lookup_key(isolate, key_obj);
5047    i::LookupIterator it(isolate, self, lookup_key, self,
5048                         i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5049    auto result = i::JSReceiver::GetPropertyAttributes(&it);
5050    has_pending_exception = result.IsNothing();
5051    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5052    if (!it.IsFound()) return Nothing<PropertyAttribute>();
5053    if (result.FromJust() == i::ABSENT) {
5054      return Just(static_cast<PropertyAttribute>(i::NONE));
5055    }
5056    return Just<PropertyAttribute>(
5057        static_cast<PropertyAttribute>(result.FromJust()));
5058  }
5059  
Clone()5060  Local<v8::Object> v8::Object::Clone() {
5061    auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5062    auto isolate = self->GetIsolate();
5063    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5064    i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
5065    return Utils::ToLocal(result);
5066  }
5067  
5068  namespace {
CreationContextImpl(i::Handle<i::JSReceiver> self)5069  Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) {
5070    i::Handle<i::Context> context;
5071    if (self->GetCreationContext().ToHandle(&context)) {
5072      return Utils::ToLocal(context);
5073    }
5074  
5075    return Local<v8::Context>();
5076  }
5077  }  // namespace
5078  
CreationContext()5079  Local<v8::Context> v8::Object::CreationContext() {
5080    auto self = Utils::OpenHandle(this);
5081    return CreationContextImpl(self);
5082  }
5083  
CreationContext(const PersistentBase<Object> & object)5084  Local<v8::Context> v8::Object::CreationContext(
5085      const PersistentBase<Object>& object) {
5086    auto self = Utils::OpenHandle(object.val_);
5087    return CreationContextImpl(self);
5088  }
5089  
GetCreationContext()5090  MaybeLocal<v8::Context> v8::Object::GetCreationContext() {
5091    auto self = Utils::OpenHandle(this);
5092    i::Handle<i::Context> context;
5093    if (self->GetCreationContext().ToHandle(&context)) {
5094      return Utils::ToLocal(context);
5095    }
5096    return MaybeLocal<v8::Context>();
5097  }
5098  
GetCreationContextChecked()5099  Local<v8::Context> v8::Object::GetCreationContextChecked() {
5100    Local<Context> context;
5101    Utils::ApiCheck(GetCreationContext().ToLocal(&context),
5102                    "v8::Object::GetCreationContextChecked",
5103                    "No creation context available");
5104    return context;
5105  }
5106  
GetIdentityHash()5107  int v8::Object::GetIdentityHash() {
5108    i::DisallowGarbageCollection no_gc;
5109    auto self = Utils::OpenHandle(this);
5110    auto isolate = self->GetIsolate();
5111    ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
5112    i::HandleScope scope(isolate);
5113    return self->GetOrCreateIdentityHash(isolate).value();
5114  }
5115  
IsCallable() const5116  bool v8::Object::IsCallable() const {
5117    auto self = Utils::OpenHandle(this);
5118    return self->IsCallable();
5119  }
5120  
IsConstructor() const5121  bool v8::Object::IsConstructor() const {
5122    auto self = Utils::OpenHandle(this);
5123    return self->IsConstructor();
5124  }
5125  
IsApiWrapper() const5126  bool v8::Object::IsApiWrapper() const {
5127    auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5128    // Objects with embedder fields can wrap API objects.
5129    return self->MayHaveEmbedderFields();
5130  }
5131  
IsUndetectable() const5132  bool v8::Object::IsUndetectable() const {
5133    auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5134    return self->IsUndetectable();
5135  }
5136  
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5137  MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5138                                           Local<Value> recv, int argc,
5139                                           Local<Value> argv[]) {
5140    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5141    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5142    ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5143             InternalEscapableScope);
5144    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5145    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5146                                               isolate);
5147    auto self = Utils::OpenHandle(this);
5148    auto recv_obj = Utils::OpenHandle(*recv);
5149    STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5150    i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5151    Local<Value> result;
5152    has_pending_exception = !ToLocal<Value>(
5153        i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5154    RETURN_ON_FAILED_EXECUTION(Value);
5155    RETURN_ESCAPED(result);
5156  }
5157  
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5158  MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5159                                              Local<Value> argv[]) {
5160    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5161    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5162    ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5163             InternalEscapableScope);
5164    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5165    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5166                                               isolate);
5167    auto self = Utils::OpenHandle(this);
5168    STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5169    i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5170    Local<Value> result;
5171    has_pending_exception = !ToLocal<Value>(
5172        i::Execution::New(isolate, self, self, argc, args), &result);
5173    RETURN_ON_FAILED_EXECUTION(Value);
5174    RETURN_ESCAPED(result);
5175  }
5176  
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)5177  MaybeLocal<Function> Function::New(Local<Context> context,
5178                                     FunctionCallback callback, Local<Value> data,
5179                                     int length, ConstructorBehavior behavior,
5180                                     SideEffectType side_effect_type) {
5181    i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5182    API_RCS_SCOPE(isolate, Function, New);
5183    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5184    auto templ =
5185        FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
5186                            behavior, true, Local<Private>(), side_effect_type);
5187    return templ->GetFunction(context);
5188  }
5189  
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5190  MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5191                                           v8::Local<v8::Value> argv[]) const {
5192    return NewInstanceWithSideEffectType(context, argc, argv,
5193                                         SideEffectType::kHasSideEffect);
5194  }
5195  
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const5196  MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
5197      Local<Context> context, int argc, v8::Local<v8::Value> argv[],
5198      SideEffectType side_effect_type) const {
5199    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5200    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5201    ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5202             InternalEscapableScope);
5203    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5204    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5205                                               isolate);
5206    auto self = Utils::OpenHandle(this);
5207    STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5208    bool should_set_has_no_side_effect =
5209        side_effect_type == SideEffectType::kHasNoSideEffect &&
5210        isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
5211    if (should_set_has_no_side_effect) {
5212      CHECK(self->IsJSFunction() &&
5213            i::JSFunction::cast(*self).shared().IsApiFunction());
5214      i::Object obj =
5215          i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5216              kAcquireLoad);
5217      if (obj.IsCallHandlerInfo()) {
5218        i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5219        if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
5220          handler_info.SetNextCallHasNoSideEffect();
5221        }
5222      }
5223    }
5224    i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5225    Local<Object> result;
5226    has_pending_exception = !ToLocal<Object>(
5227        i::Execution::New(isolate, self, self, argc, args), &result);
5228    if (should_set_has_no_side_effect) {
5229      i::Object obj =
5230          i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5231              kAcquireLoad);
5232      if (obj.IsCallHandlerInfo()) {
5233        i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5234        if (has_pending_exception) {
5235          // Restore the map if an exception prevented restoration.
5236          handler_info.NextCallHasNoSideEffect();
5237        } else {
5238          DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
5239                 handler_info.IsSideEffectFreeCallHandlerInfo());
5240        }
5241      }
5242    }
5243    RETURN_ON_FAILED_EXECUTION(Object);
5244    RETURN_ESCAPED(result);
5245  }
5246  
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5247  MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5248                                       v8::Local<v8::Value> recv, int argc,
5249                                       v8::Local<v8::Value> argv[]) {
5250    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5251    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5252    ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5253             InternalEscapableScope);
5254    i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5255    i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5256                                               isolate);
5257    auto self = Utils::OpenHandle(this);
5258    Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
5259                    "Function to be called is a null pointer");
5260    i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5261    STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5262    i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5263    Local<Value> result;
5264    has_pending_exception = !ToLocal<Value>(
5265        i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5266    RETURN_ON_FAILED_EXECUTION(Value);
5267    RETURN_ESCAPED(result);
5268  }
5269  
SetName(v8::Local<v8::String> name)5270  void Function::SetName(v8::Local<v8::String> name) {
5271    auto self = Utils::OpenHandle(this);
5272    if (!self->IsJSFunction()) return;
5273    auto func = i::Handle<i::JSFunction>::cast(self);
5274    ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
5275    func->shared().SetName(*Utils::OpenHandle(*name));
5276  }
5277  
GetName() const5278  Local<Value> Function::GetName() const {
5279    auto self = Utils::OpenHandle(this);
5280    i::Isolate* isolate = self->GetIsolate();
5281    if (self->IsJSBoundFunction()) {
5282      auto func = i::Handle<i::JSBoundFunction>::cast(self);
5283      i::Handle<i::Object> name;
5284      ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5285                                       i::JSBoundFunction::GetName(isolate, func),
5286                                       Local<Value>());
5287      return Utils::ToLocal(name);
5288    }
5289    if (self->IsJSFunction()) {
5290      auto func = i::Handle<i::JSFunction>::cast(self);
5291      return Utils::ToLocal(handle(func->shared().Name(), isolate));
5292    }
5293    return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5294  }
5295  
GetInferredName() const5296  Local<Value> Function::GetInferredName() const {
5297    auto self = Utils::OpenHandle(this);
5298    if (!self->IsJSFunction()) {
5299      return ToApiHandle<Primitive>(
5300          self->GetIsolate()->factory()->undefined_value());
5301    }
5302    auto func = i::Handle<i::JSFunction>::cast(self);
5303    return Utils::ToLocal(
5304        i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5305  }
5306  
GetDebugName() const5307  Local<Value> Function::GetDebugName() const {
5308    auto self = Utils::OpenHandle(this);
5309    if (!self->IsJSFunction()) {
5310      return ToApiHandle<Primitive>(
5311          self->GetIsolate()->factory()->undefined_value());
5312    }
5313    auto func = i::Handle<i::JSFunction>::cast(self);
5314    i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5315    return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5316  }
5317  
GetScriptOrigin() const5318  ScriptOrigin Function::GetScriptOrigin() const {
5319    auto self = Utils::OpenHandle(this);
5320    auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate());
5321    if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>());
5322    auto func = i::Handle<i::JSFunction>::cast(self);
5323    if (func->shared().script().IsScript()) {
5324      i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5325                                  func->GetIsolate());
5326      return GetScriptOriginForScript(func->GetIsolate(), script);
5327    }
5328    return v8::ScriptOrigin(isolate, Local<Value>());
5329  }
5330  
5331  const int Function::kLineOffsetNotFound = -1;
5332  
GetScriptLineNumber() const5333  int Function::GetScriptLineNumber() const {
5334    auto self = Utils::OpenHandle(this);
5335    if (!self->IsJSFunction()) {
5336      return kLineOffsetNotFound;
5337    }
5338    auto func = i::Handle<i::JSFunction>::cast(self);
5339    if (func->shared().script().IsScript()) {
5340      i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5341                                  func->GetIsolate());
5342      return i::Script::GetLineNumber(script, func->shared().StartPosition());
5343    }
5344    return kLineOffsetNotFound;
5345  }
5346  
GetScriptColumnNumber() const5347  int Function::GetScriptColumnNumber() const {
5348    auto self = Utils::OpenHandle(this);
5349    if (!self->IsJSFunction()) {
5350      return kLineOffsetNotFound;
5351    }
5352    auto func = i::Handle<i::JSFunction>::cast(self);
5353    if (func->shared().script().IsScript()) {
5354      i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5355                                  func->GetIsolate());
5356      return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5357    }
5358    return kLineOffsetNotFound;
5359  }
5360  
GetUnboundScript() const5361  MaybeLocal<UnboundScript> Function::GetUnboundScript() const {
5362    i::Handle<i::Object> self = Utils::OpenHandle(this);
5363    if (!self->IsJSFunction()) return MaybeLocal<UnboundScript>();
5364    i::SharedFunctionInfo sfi = i::JSFunction::cast(*self).shared();
5365    i::Isolate* isolate = sfi.GetIsolate();
5366    return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
5367  }
5368  
ScriptId() const5369  int Function::ScriptId() const {
5370    i::JSReceiver self = *Utils::OpenHandle(this);
5371    if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
5372    auto func = i::JSFunction::cast(self);
5373    if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
5374    return i::Script::cast(func.shared().script()).id();
5375  }
5376  
GetBoundFunction() const5377  Local<v8::Value> Function::GetBoundFunction() const {
5378    auto self = Utils::OpenHandle(this);
5379    if (self->IsJSBoundFunction()) {
5380      auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5381      auto bound_target_function = i::handle(
5382          bound_function->bound_target_function(), bound_function->GetIsolate());
5383      return Utils::CallableToLocal(bound_target_function);
5384    }
5385    return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5386  }
5387  
FunctionProtoToString(Local<Context> context)5388  MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5389    PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5390    auto self = Utils::OpenHandle(this);
5391    Local<Value> result;
5392    has_pending_exception = !ToLocal<Value>(
5393        i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5394                                  nullptr),
5395        &result);
5396    RETURN_ON_FAILED_EXECUTION(String);
5397    RETURN_ESCAPED(Local<String>::Cast(result));
5398  }
5399  
GetIdentityHash()5400  int Name::GetIdentityHash() {
5401    auto self = Utils::OpenHandle(this);
5402    return static_cast<int>(self->EnsureHash());
5403  }
5404  
Length() const5405  int String::Length() const {
5406    i::Handle<i::String> str = Utils::OpenHandle(this);
5407    return str->length();
5408  }
5409  
IsOneByte() const5410  bool String::IsOneByte() const {
5411    i::Handle<i::String> str = Utils::OpenHandle(this);
5412    return str->IsOneByteRepresentation();
5413  }
5414  
5415  // Helpers for ContainsOnlyOneByteHelper
5416  template <size_t size>
5417  struct OneByteMask;
5418  template <>
5419  struct OneByteMask<4> {
5420    static const uint32_t value = 0xFF00FF00;
5421  };
5422  template <>
5423  struct OneByteMask<8> {
5424    static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5425  };
5426  static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5427  static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5428  static inline bool Unaligned(const uint16_t* chars) {
5429    return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5430  }
5431  
Align(const uint16_t * chars)5432  static inline const uint16_t* Align(const uint16_t* chars) {
5433    return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5434                                       ~kAlignmentMask);
5435  }
5436  
5437  class ContainsOnlyOneByteHelper {
5438   public:
ContainsOnlyOneByteHelper()5439    ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5440    ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5441    ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5442        delete;
Check(i::String string)5443    bool Check(i::String string) {
5444      i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5445      if (cons_string.is_null()) return is_one_byte_;
5446      return CheckCons(cons_string);
5447    }
VisitOneByteString(const uint8_t * chars,int length)5448    void VisitOneByteString(const uint8_t* chars, int length) {
5449      // Nothing to do.
5450    }
VisitTwoByteString(const uint16_t * chars,int length)5451    void VisitTwoByteString(const uint16_t* chars, int length) {
5452      // Accumulated bits.
5453      uintptr_t acc = 0;
5454      // Align to uintptr_t.
5455      const uint16_t* end = chars + length;
5456      while (Unaligned(chars) && chars != end) {
5457        acc |= *chars++;
5458      }
5459      // Read word aligned in blocks,
5460      // checking the return value at the end of each block.
5461      const uint16_t* aligned_end = Align(end);
5462      const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5463      const int inner_loops = 16;
5464      while (chars + inner_loops * increment < aligned_end) {
5465        for (int i = 0; i < inner_loops; i++) {
5466          acc |= *reinterpret_cast<const uintptr_t*>(chars);
5467          chars += increment;
5468        }
5469        // Check for early return.
5470        if ((acc & kOneByteMask) != 0) {
5471          is_one_byte_ = false;
5472          return;
5473        }
5474      }
5475      // Read the rest.
5476      while (chars != end) {
5477        acc |= *chars++;
5478      }
5479      // Check result.
5480      if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5481    }
5482  
5483   private:
CheckCons(i::ConsString cons_string)5484    bool CheckCons(i::ConsString cons_string) {
5485      while (true) {
5486        // Check left side if flat.
5487        i::String left = cons_string.first();
5488        i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5489        if (!is_one_byte_) return false;
5490        // Check right side if flat.
5491        i::String right = cons_string.second();
5492        i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5493        if (!is_one_byte_) return false;
5494        // Standard recurse/iterate trick.
5495        if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5496          if (left.length() < right.length()) {
5497            CheckCons(left_as_cons);
5498            cons_string = right_as_cons;
5499          } else {
5500            CheckCons(right_as_cons);
5501            cons_string = left_as_cons;
5502          }
5503          // Check fast return.
5504          if (!is_one_byte_) return false;
5505          continue;
5506        }
5507        // Descend left in place.
5508        if (!left_as_cons.is_null()) {
5509          cons_string = left_as_cons;
5510          continue;
5511        }
5512        // Descend right in place.
5513        if (!right_as_cons.is_null()) {
5514          cons_string = right_as_cons;
5515          continue;
5516        }
5517        // Terminate.
5518        break;
5519      }
5520      return is_one_byte_;
5521    }
5522    bool is_one_byte_;
5523  };
5524  
ContainsOnlyOneByte() const5525  bool String::ContainsOnlyOneByte() const {
5526    i::Handle<i::String> str = Utils::OpenHandle(this);
5527    if (str->IsOneByteRepresentation()) return true;
5528    ContainsOnlyOneByteHelper helper;
5529    return helper.Check(*str);
5530  }
5531  
Utf8Length(Isolate * isolate) const5532  int String::Utf8Length(Isolate* isolate) const {
5533    i::Handle<i::String> str = Utils::OpenHandle(this);
5534    str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5535    int length = str->length();
5536    if (length == 0) return 0;
5537    i::DisallowGarbageCollection no_gc;
5538    i::String::FlatContent flat = str->GetFlatContent(no_gc);
5539    DCHECK(flat.IsFlat());
5540    int utf8_length = 0;
5541    if (flat.IsOneByte()) {
5542      for (uint8_t c : flat.ToOneByteVector()) {
5543        utf8_length += c >> 7;
5544      }
5545      utf8_length += length;
5546    } else {
5547      int last_character = unibrow::Utf16::kNoPreviousCharacter;
5548      for (uint16_t c : flat.ToUC16Vector()) {
5549        utf8_length += unibrow::Utf8::Length(c, last_character);
5550        last_character = c;
5551      }
5552    }
5553    return utf8_length;
5554  }
5555  
5556  namespace {
5557  // Writes the flat content of a string to a buffer. This is done in two phases.
5558  // The first phase calculates a pessimistic estimate (writable_length) on how
5559  // many code units can be safely written without exceeding the buffer capacity
5560  // and without leaving at a lone surrogate. The estimated number of code units
5561  // is then written out in one go, and the reported byte usage is used to
5562  // correct the estimate. This is repeated until the estimate becomes <= 0 or
5563  // all code units have been written out. The second phase writes out code
5564  // units until the buffer capacity is reached, would be exceeded by the next
5565  // unit, or all code units have been written out.
5566  template <typename Char>
WriteUtf8Impl(base::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5567  static int WriteUtf8Impl(base::Vector<const Char> string, char* write_start,
5568                           int write_capacity, int options,
5569                           int* utf16_chars_read_out) {
5570    bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5571    bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5572    char* current_write = write_start;
5573    const Char* read_start = string.begin();
5574    int read_index = 0;
5575    int read_length = string.length();
5576    int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5577    // Do a fast loop where there is no exit capacity check.
5578    // Need enough space to write everything but one character.
5579    STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5580    static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5581    while (read_index < read_length) {
5582      int up_to = read_length;
5583      if (write_capacity != -1) {
5584        int remaining_capacity =
5585            write_capacity - static_cast<int>(current_write - write_start);
5586        int writable_length =
5587            (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5588        // Need to drop into slow loop.
5589        if (writable_length <= 0) break;
5590        up_to = std::min(up_to, read_index + writable_length);
5591      }
5592      // Write the characters to the stream.
5593      if (sizeof(Char) == 1) {
5594        // Simply memcpy if we only have ASCII characters.
5595        uint8_t char_mask = 0;
5596        for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5597        if ((char_mask & 0x80) == 0) {
5598          int copy_length = up_to - read_index;
5599          memcpy(current_write, read_start + read_index, copy_length);
5600          current_write += copy_length;
5601          read_index = up_to;
5602        } else {
5603          for (; read_index < up_to; read_index++) {
5604            current_write += unibrow::Utf8::EncodeOneByte(
5605                current_write, static_cast<uint8_t>(read_start[read_index]));
5606            DCHECK(write_capacity == -1 ||
5607                   (current_write - write_start) <= write_capacity);
5608          }
5609        }
5610      } else {
5611        for (; read_index < up_to; read_index++) {
5612          uint16_t character = read_start[read_index];
5613          current_write += unibrow::Utf8::Encode(current_write, character,
5614                                                 prev_char, replace_invalid_utf8);
5615          prev_char = character;
5616          DCHECK(write_capacity == -1 ||
5617                 (current_write - write_start) <= write_capacity);
5618        }
5619      }
5620    }
5621    if (read_index < read_length) {
5622      DCHECK_NE(-1, write_capacity);
5623      // Aborted due to limited capacity. Check capacity on each iteration.
5624      int remaining_capacity =
5625          write_capacity - static_cast<int>(current_write - write_start);
5626      DCHECK_GE(remaining_capacity, 0);
5627      for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5628        uint32_t character = read_start[read_index];
5629        int written = 0;
5630        // We can't use a local buffer here because Encode needs to modify
5631        // previous characters in the stream.  We know, however, that
5632        // exactly one character will be advanced.
5633        if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5634          written = unibrow::Utf8::Encode(current_write, character, prev_char,
5635                                          replace_invalid_utf8);
5636          DCHECK_EQ(written, 1);
5637        } else {
5638          // Use a scratch buffer to check the required characters.
5639          char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5640          // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5641          static const int kSurrogatePairEncodedSize =
5642              static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5643          // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5644          // middle of a surrogate pair. Abort before encoding the pair instead.
5645          if (replace_invalid_utf8 &&
5646              remaining_capacity < kSurrogatePairEncodedSize &&
5647              unibrow::Utf16::IsLeadSurrogate(character) &&
5648              read_index + 1 < read_length &&
5649              unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5650            write_null = false;
5651            break;
5652          }
5653          // Can't encode using prev_char as gcc has array bounds issues.
5654          written = unibrow::Utf8::Encode(temp_buffer, character,
5655                                          unibrow::Utf16::kNoPreviousCharacter,
5656                                          replace_invalid_utf8);
5657          if (written > remaining_capacity) {
5658            // Won't fit. Abort and do not null-terminate the result.
5659            write_null = false;
5660            break;
5661          }
5662          // Copy over the character from temp_buffer.
5663          for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5664        }
5665  
5666        current_write += written;
5667        remaining_capacity -= written;
5668        prev_char = character;
5669      }
5670    }
5671  
5672    // Write out number of utf16 characters written to the stream.
5673    if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5674  
5675    // Only null-terminate if there's space.
5676    if (write_null && (write_capacity == -1 ||
5677                       (current_write - write_start) < write_capacity)) {
5678      *current_write++ = '\0';
5679    }
5680    return static_cast<int>(current_write - write_start);
5681  }
5682  }  // anonymous namespace
5683  
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5684  int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5685                        int* nchars_ref, int options) const {
5686    i::Handle<i::String> str = Utils::OpenHandle(this);
5687    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5688    API_RCS_SCOPE(isolate, String, WriteUtf8);
5689    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5690    str = i::String::Flatten(isolate, str);
5691    i::DisallowGarbageCollection no_gc;
5692    i::String::FlatContent content = str->GetFlatContent(no_gc);
5693    if (content.IsOneByte()) {
5694      return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5695                                    options, nchars_ref);
5696    } else {
5697      return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5698                                     options, nchars_ref);
5699    }
5700  }
5701  
5702  template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5703  static inline int WriteHelper(i::Isolate* isolate, const String* string,
5704                                CharType* buffer, int start, int length,
5705                                int options) {
5706    API_RCS_SCOPE(isolate, String, Write);
5707    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5708    DCHECK(start >= 0 && length >= -1);
5709    i::Handle<i::String> str = Utils::OpenHandle(string);
5710    str = i::String::Flatten(isolate, str);
5711    int end = start + length;
5712    if ((length == -1) || (length > str->length() - start)) end = str->length();
5713    if (end < 0) return 0;
5714    int write_length = end - start;
5715    if (start < end) i::String::WriteToFlat(*str, buffer, start, write_length);
5716    if (!(options & String::NO_NULL_TERMINATION) &&
5717        (length == -1 || write_length < length)) {
5718      buffer[write_length] = '\0';
5719    }
5720    return write_length;
5721  }
5722  
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5723  int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5724                           int length, int options) const {
5725    return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5726                       start, length, options);
5727  }
5728  
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5729  int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5730                    int options) const {
5731    return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5732                       start, length, options);
5733  }
5734  
IsExternal() const5735  bool v8::String::IsExternal() const {
5736    i::Handle<i::String> str = Utils::OpenHandle(this);
5737    return i::StringShape(*str).IsExternal();
5738  }
5739  
IsExternalTwoByte() const5740  bool v8::String::IsExternalTwoByte() const {
5741    i::Handle<i::String> str = Utils::OpenHandle(this);
5742    return i::StringShape(*str).IsExternalTwoByte();
5743  }
5744  
IsExternalOneByte() const5745  bool v8::String::IsExternalOneByte() const {
5746    i::Handle<i::String> str = Utils::OpenHandle(this);
5747    return i::StringShape(*str).IsExternalOneByte();
5748  }
5749  
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5750  void v8::String::VerifyExternalStringResource(
5751      v8::String::ExternalStringResource* value) const {
5752    i::DisallowGarbageCollection no_gc;
5753    i::String str = *Utils::OpenHandle(this);
5754    const v8::String::ExternalStringResource* expected;
5755  
5756    if (str.IsThinString()) {
5757      str = i::ThinString::cast(str).actual();
5758    }
5759  
5760    if (i::StringShape(str).IsExternalTwoByte()) {
5761      const void* resource = i::ExternalTwoByteString::cast(str).resource();
5762      expected = reinterpret_cast<const ExternalStringResource*>(resource);
5763    } else {
5764      expected = nullptr;
5765    }
5766    CHECK_EQ(expected, value);
5767  }
5768  
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5769  void v8::String::VerifyExternalStringResourceBase(
5770      v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5771    i::DisallowGarbageCollection no_gc;
5772    i::String str = *Utils::OpenHandle(this);
5773    const v8::String::ExternalStringResourceBase* expected;
5774    Encoding expectedEncoding;
5775  
5776    if (str.IsThinString()) {
5777      str = i::ThinString::cast(str).actual();
5778    }
5779  
5780    if (i::StringShape(str).IsExternalOneByte()) {
5781      const void* resource = i::ExternalOneByteString::cast(str).resource();
5782      expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5783      expectedEncoding = ONE_BYTE_ENCODING;
5784    } else if (i::StringShape(str).IsExternalTwoByte()) {
5785      const void* resource = i::ExternalTwoByteString::cast(str).resource();
5786      expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5787      expectedEncoding = TWO_BYTE_ENCODING;
5788    } else {
5789      expected = nullptr;
5790      expectedEncoding =
5791          str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5792    }
5793    CHECK_EQ(expected, value);
5794    CHECK_EQ(expectedEncoding, encoding);
5795  }
5796  
GetExternalStringResourceSlow() const5797  String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5798    i::DisallowGarbageCollection no_gc;
5799    using I = internal::Internals;
5800    i::String str = *Utils::OpenHandle(this);
5801  
5802    if (str.IsThinString()) {
5803      str = i::ThinString::cast(str).actual();
5804    }
5805  
5806    if (i::StringShape(str).IsExternalTwoByte()) {
5807      internal::Isolate* isolate = I::GetIsolateForSandbox(str.ptr());
5808      internal::Address value = I::ReadExternalPointerField(
5809          isolate, str.ptr(), I::kStringResourceOffset,
5810          internal::kExternalStringResourceTag);
5811      return reinterpret_cast<String::ExternalStringResource*>(value);
5812    }
5813    return nullptr;
5814  }
5815  
UpdateDataCache()5816  void String::ExternalStringResource::UpdateDataCache() {
5817    DCHECK(IsCacheable());
5818    cached_data_ = data();
5819  }
5820  
CheckCachedDataInvariants() const5821  void String::ExternalStringResource::CheckCachedDataInvariants() const {
5822    DCHECK(IsCacheable() && cached_data_ != nullptr);
5823  }
5824  
UpdateDataCache()5825  void String::ExternalOneByteStringResource::UpdateDataCache() {
5826    DCHECK(IsCacheable());
5827    cached_data_ = data();
5828  }
5829  
CheckCachedDataInvariants() const5830  void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5831    DCHECK(IsCacheable() && cached_data_ != nullptr);
5832  }
5833  
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5834  String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5835      String::Encoding* encoding_out) const {
5836    i::DisallowGarbageCollection no_gc;
5837    using I = internal::Internals;
5838    ExternalStringResourceBase* resource = nullptr;
5839    i::String str = *Utils::OpenHandle(this);
5840  
5841    if (str.IsThinString()) {
5842      str = i::ThinString::cast(str).actual();
5843    }
5844  
5845    internal::Address string = str.ptr();
5846    int type =
5847        I::GetInstanceType(string) & I::kStringRepresentationAndEncodingMask;
5848    *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5849    if (i::StringShape(str).IsExternalOneByte() ||
5850        i::StringShape(str).IsExternalTwoByte()) {
5851      internal::Isolate* isolate = I::GetIsolateForSandbox(string);
5852      internal::Address value =
5853          I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5854                                      internal::kExternalStringResourceTag);
5855      resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5856    }
5857    return resource;
5858  }
5859  
5860  const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5861  v8::String::GetExternalOneByteStringResource() const {
5862    i::DisallowGarbageCollection no_gc;
5863    i::String str = *Utils::OpenHandle(this);
5864    if (i::StringShape(str).IsExternalOneByte()) {
5865      return i::ExternalOneByteString::cast(str).resource();
5866    } else if (str.IsThinString()) {
5867      str = i::ThinString::cast(str).actual();
5868      if (i::StringShape(str).IsExternalOneByte()) {
5869        return i::ExternalOneByteString::cast(str).resource();
5870      }
5871    }
5872    return nullptr;
5873  }
5874  
Description(Isolate * isolate) const5875  Local<Value> Symbol::Description(Isolate* isolate) const {
5876    i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5877    i::Handle<i::Object> description(sym->description(),
5878                                     reinterpret_cast<i::Isolate*>(isolate));
5879    return Utils::ToLocal(description);
5880  }
5881  
Name() const5882  Local<Value> Private::Name() const {
5883    const Symbol* sym = reinterpret_cast<const Symbol*>(this);
5884    i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym);
5885    // v8::Private symbols are created by API and are therefore writable, so we
5886    // can always recover an Isolate.
5887    i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym);
5888    return sym->Description(reinterpret_cast<Isolate*>(isolate));
5889  }
5890  
Value() const5891  double Number::Value() const {
5892    i::Handle<i::Object> obj = Utils::OpenHandle(this);
5893    return obj->Number();
5894  }
5895  
Value() const5896  bool Boolean::Value() const {
5897    i::Handle<i::Object> obj = Utils::OpenHandle(this);
5898    return obj->IsTrue();
5899  }
5900  
Value() const5901  int64_t Integer::Value() const {
5902    i::Object obj = *Utils::OpenHandle(this);
5903    if (obj.IsSmi()) {
5904      return i::Smi::ToInt(obj);
5905    } else {
5906      return static_cast<int64_t>(obj.Number());
5907    }
5908  }
5909  
Value() const5910  int32_t Int32::Value() const {
5911    i::Object obj = *Utils::OpenHandle(this);
5912    if (obj.IsSmi()) {
5913      return i::Smi::ToInt(obj);
5914    } else {
5915      return static_cast<int32_t>(obj.Number());
5916    }
5917  }
5918  
Value() const5919  uint32_t Uint32::Value() const {
5920    i::Object obj = *Utils::OpenHandle(this);
5921    if (obj.IsSmi()) {
5922      return i::Smi::ToInt(obj);
5923    } else {
5924      return static_cast<uint32_t>(obj.Number());
5925    }
5926  }
5927  
InternalFieldCount() const5928  int v8::Object::InternalFieldCount() const {
5929    i::JSReceiver self = *Utils::OpenHandle(this);
5930    if (!self.IsJSObject()) return 0;
5931    return i::JSObject::cast(self).GetEmbedderFieldCount();
5932  }
5933  
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5934  static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5935                              const char* location) {
5936    return Utils::ApiCheck(
5937        obj->IsJSObject() &&
5938            (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5939        location, "Internal field out of bounds");
5940  }
5941  
SlowGetInternalField(int index)5942  Local<Value> v8::Object::SlowGetInternalField(int index) {
5943    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5944    const char* location = "v8::Object::GetInternalField()";
5945    if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5946    i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
5947                               obj->GetIsolate());
5948    return Utils::ToLocal(value);
5949  }
5950  
5951  template<typename T>
SetInternalFieldImpl(v8::Object * receiver,int index,v8::Local<T> value)5952  void SetInternalFieldImpl(v8::Object* receiver, int index, v8::Local<T> value) {
5953    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(receiver);
5954    const char* location = "v8::Object::SetInternalField()";
5955    if (!InternalFieldOK(obj, index, location)) return;
5956    i::Handle<i::Object> val = Utils::OpenHandle(*value);
5957    i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
5958  }
5959  
SetInternalField(int index,v8::Local<Value> value)5960  void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5961    SetInternalFieldImpl(this, index, value);
5962  }
5963  
5964  /**
5965   * These are Node.js-specific extentions used to avoid breaking changes in
5966   * Node.js v20.x.
5967   */
SetInternalFieldForNodeCore(int index,v8::Local<Module> value)5968  void v8::Object::SetInternalFieldForNodeCore(int index,
5969                                               v8::Local<Module> value) {
5970    SetInternalFieldImpl(this, index, value);
5971  }
5972  
SetInternalFieldForNodeCore(int index,v8::Local<UnboundScript> value)5973  void v8::Object::SetInternalFieldForNodeCore(int index,
5974                                               v8::Local<UnboundScript> value) {
5975    SetInternalFieldImpl(this, index, value);
5976  }
5977  
SlowGetAlignedPointerFromInternalField(int index)5978  void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5979    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5980    const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5981    if (!InternalFieldOK(obj, index, location)) return nullptr;
5982    void* result;
5983    Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5984                        .ToAlignedPointer(obj->GetIsolate(), &result),
5985                    location, "Unaligned pointer");
5986    return result;
5987  }
5988  
SetAlignedPointerInInternalField(int index,void * value)5989  void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5990    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5991    const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5992    if (!InternalFieldOK(obj, index, location)) return;
5993  
5994    i::DisallowGarbageCollection no_gc;
5995  
5996    // There's no need to invalidate slots as embedder fields are always
5997    // tagged.
5998    obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
5999                                             i::InvalidateRecordedSlots::kNo);
6000  
6001    Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
6002                        .store_aligned_pointer(obj->GetIsolate(), value),
6003                    location, "Unaligned pointer");
6004    DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6005    internal::WriteBarrier::MarkingFromInternalFields(i::JSObject::cast(*obj));
6006  
6007  #ifdef VERIFY_HEAP
6008    obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6009  #endif  // VERIFY_HEAP
6010  }
6011  
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])6012  void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
6013                                                     void* values[]) {
6014    i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6015  
6016    i::DisallowGarbageCollection no_gc;
6017    // There's no need to invalidate slots as embedder fields are always
6018    // tagged.
6019    obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
6020                                             i::InvalidateRecordedSlots::kNo);
6021  
6022    const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6023    i::JSObject js_obj = i::JSObject::cast(*obj);
6024    int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
6025    for (int i = 0; i < argc; i++) {
6026      int index = indices[i];
6027      if (!Utils::ApiCheck(index < nof_embedder_fields, location,
6028                           "Internal field out of bounds")) {
6029        return;
6030      }
6031      void* value = values[i];
6032      Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
6033                          .store_aligned_pointer(obj->GetIsolate(), value),
6034                      location, "Unaligned pointer");
6035      DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6036    }
6037    internal::WriteBarrier::MarkingFromInternalFields(js_obj);
6038  
6039  #ifdef VERIFY_HEAP
6040    obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6041  #endif  // VERIFY_HEAP
6042  }
6043  
6044  // --- E n v i r o n m e n t ---
6045  
InitializePlatform(Platform * platform)6046  void v8::V8::InitializePlatform(Platform* platform) {
6047    i::V8::InitializePlatform(platform);
6048  }
6049  
6050  #ifdef V8_SANDBOX
InitializeSandbox()6051  bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); }
6052  #endif
6053  
DisposePlatform()6054  void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); }
6055  
Initialize(const int build_config)6056  bool v8::V8::Initialize(const int build_config) {
6057    const bool kEmbedderPointerCompression =
6058        (build_config & kPointerCompression) != 0;
6059    if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
6060      FATAL(
6061          "Embedder-vs-V8 build configuration mismatch. On embedder side "
6062          "pointer compression is %s while on V8 side it's %s.",
6063          kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
6064          COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6065    }
6066  
6067    const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
6068    if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
6069      FATAL(
6070          "Embedder-vs-V8 build configuration mismatch. On embedder side "
6071          "Smi value size is %d while on V8 side it's %d.",
6072          kEmbedderSmiValueSize, internal::kSmiValueSize);
6073    }
6074  
6075    const bool kEmbedderSandboxedExternalPointers =
6076        (build_config & kSandboxedExternalPointers) != 0;
6077    if (kEmbedderSandboxedExternalPointers !=
6078        V8_SANDBOXED_EXTERNAL_POINTERS_BOOL) {
6079      FATAL(
6080          "Embedder-vs-V8 build configuration mismatch. On embedder side "
6081          "sandboxed external pointers is %s while on V8 side it's %s.",
6082          kEmbedderSandboxedExternalPointers ? "ENABLED" : "DISABLED",
6083          V8_SANDBOXED_EXTERNAL_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6084    }
6085  
6086    const bool kEmbedderSandbox = (build_config & kSandbox) != 0;
6087    if (kEmbedderSandbox != V8_SANDBOX_BOOL) {
6088      FATAL(
6089          "Embedder-vs-V8 build configuration mismatch. On embedder side "
6090          "sandbox is %s while on V8 side it's %s.",
6091          kEmbedderSandbox ? "ENABLED" : "DISABLED",
6092          V8_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
6093    }
6094  
6095    i::V8::Initialize();
6096    return true;
6097  }
6098  
6099  #if V8_OS_LINUX || V8_OS_DARWIN
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)6100  bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
6101                                     void* context) {
6102  #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6103    return i::trap_handler::TryHandleSignal(sig_code, info, context);
6104  #else
6105    return false;
6106  #endif
6107  }
6108  #endif
6109  
6110  #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)6111  bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
6112  #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6113    return i::trap_handler::TryHandleWasmTrap(exception);
6114  #else
6115    return false;
6116  #endif
6117  }
6118  #endif
6119  
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)6120  bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6121  #if V8_ENABLE_WEBASSEMBLY
6122    return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
6123  #else
6124    return false;
6125  #endif
6126  }
6127  
6128  #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6129  void V8::SetUnhandledExceptionCallback(
6130      UnhandledExceptionCallback unhandled_exception_callback) {
6131  #if defined(V8_OS_WIN64)
6132    v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
6133        unhandled_exception_callback);
6134  #else
6135    // Not implemented, port needed.
6136  #endif  // V8_OS_WIN64
6137  }
6138  #endif  // V8_OS_WIN
6139  
SetFatalMemoryErrorCallback(v8::OOMErrorCallback oom_error_callback)6140  void v8::V8::SetFatalMemoryErrorCallback(
6141      v8::OOMErrorCallback oom_error_callback) {
6142    g_oom_error_callback = oom_error_callback;
6143  }
6144  
SetEntropySource(EntropySource entropy_source)6145  void v8::V8::SetEntropySource(EntropySource entropy_source) {
6146    base::RandomNumberGenerator::SetEntropySource(entropy_source);
6147  }
6148  
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6149  void v8::V8::SetReturnAddressLocationResolver(
6150      ReturnAddressLocationResolver return_address_resolver) {
6151    i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6152  }
6153  
Dispose()6154  bool v8::V8::Dispose() {
6155    i::V8::Dispose();
6156    return true;
6157  }
6158  
SharedMemoryStatistics()6159  SharedMemoryStatistics::SharedMemoryStatistics()
6160      : read_only_space_size_(0),
6161        read_only_space_used_size_(0),
6162        read_only_space_physical_size_(0) {}
6163  
HeapStatistics()6164  HeapStatistics::HeapStatistics()
6165      : total_heap_size_(0),
6166        total_heap_size_executable_(0),
6167        total_physical_size_(0),
6168        total_available_size_(0),
6169        used_heap_size_(0),
6170        heap_size_limit_(0),
6171        malloced_memory_(0),
6172        external_memory_(0),
6173        peak_malloced_memory_(0),
6174        does_zap_garbage_(false),
6175        number_of_native_contexts_(0),
6176        number_of_detached_contexts_(0) {}
6177  
HeapSpaceStatistics()6178  HeapSpaceStatistics::HeapSpaceStatistics()
6179      : space_name_(nullptr),
6180        space_size_(0),
6181        space_used_size_(0),
6182        space_available_size_(0),
6183        physical_space_size_(0) {}
6184  
HeapObjectStatistics()6185  HeapObjectStatistics::HeapObjectStatistics()
6186      : object_type_(nullptr),
6187        object_sub_type_(nullptr),
6188        object_count_(0),
6189        object_size_(0) {}
6190  
HeapCodeStatistics()6191  HeapCodeStatistics::HeapCodeStatistics()
6192      : code_and_metadata_size_(0),
6193        bytecode_and_metadata_size_(0),
6194        external_script_source_size_(0),
6195        cpu_profiler_metadata_size_(0) {}
6196  
InitializeICU(const char * icu_data_file)6197  bool v8::V8::InitializeICU(const char* icu_data_file) {
6198    return i::InitializeICU(icu_data_file);
6199  }
6200  
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6201  bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6202                                            const char* icu_data_file) {
6203    return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6204  }
6205  
InitializeExternalStartupData(const char * directory_path)6206  void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6207    i::InitializeExternalStartupData(directory_path);
6208  }
6209  
6210  // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)6211  void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6212    i::InitializeExternalStartupDataFromFile(snapshot_blob);
6213  }
6214  
GetVersion()6215  const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6216  
6217  #ifdef V8_SANDBOX
GetSandboxAddressSpace()6218  VirtualAddressSpace* v8::V8::GetSandboxAddressSpace() {
6219    Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6220                    "v8::V8::GetSandboxAddressSpace",
6221                    "The sandbox must be initialized first.");
6222    return i::GetProcessWideSandbox()->address_space();
6223  }
6224  
GetVirtualMemoryCagePageAllocator()6225  PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() {
6226    Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6227                    "v8::V8::GetVirtualMemoryCagePageAllocator",
6228                    "The sandbox must be initialized first.");
6229    return i::GetProcessWideSandbox()->page_allocator();
6230  }
6231  
GetSandboxSizeInBytes()6232  size_t v8::V8::GetSandboxSizeInBytes() {
6233    if (!i::GetProcessWideSandbox()->is_initialized()) {
6234      return 0;
6235    } else {
6236      return i::GetProcessWideSandbox()->size();
6237    }
6238  }
6239  
IsSandboxConfiguredSecurely()6240  bool v8::V8::IsSandboxConfiguredSecurely() {
6241    Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6242                    "v8::V8::IsSandoxConfiguredSecurely",
6243                    "The sandbox must be initialized first.");
6244    // TODO(saelo) For now, we only treat a partially reserved sandbox as
6245    // insecure. Once we use sandboxed pointers, which assume that the sandbox
6246    // has a fixed size, we'll also treat sandboxes with a smaller size as
6247    // insecure because these pointers can then access memory outside of them.
6248    return !i::GetProcessWideSandbox()->is_partially_reserved();
6249  }
6250  #endif
6251  
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6252  void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6253    i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6254  }
6255  
6256  template <typename ObjectType>
6257  struct InvokeBootstrapper;
6258  
6259  template <>
6260  struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6261    i::Handle<i::Context> Invoke(
6262        i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6263        v8::Local<v8::ObjectTemplate> global_proxy_template,
6264        v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6265        v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6266        v8::MicrotaskQueue* microtask_queue) {
6267      return isolate->bootstrapper()->CreateEnvironment(
6268          maybe_global_proxy, global_proxy_template, extensions,
6269          context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6270    }
6271  };
6272  
6273  template <>
6274  struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6275    i::Handle<i::JSGlobalProxy> Invoke(
6276        i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6277        v8::Local<v8::ObjectTemplate> global_proxy_template,
6278        v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6279        v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6280        v8::MicrotaskQueue* microtask_queue) {
6281      USE(extensions);
6282      USE(context_snapshot_index);
6283      return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6284                                                       global_proxy_template);
6285    }
6286  };
6287  
6288  template <typename ObjectType>
CreateEnvironment(i::Isolate * isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> maybe_global_template,v8::MaybeLocal<Value> maybe_global_proxy,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6289  static i::Handle<ObjectType> CreateEnvironment(
6290      i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6291      v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6292      v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6293      v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6294      v8::MicrotaskQueue* microtask_queue) {
6295    i::Handle<ObjectType> result;
6296  
6297    {
6298      ENTER_V8_FOR_NEW_CONTEXT(isolate);
6299      v8::Local<ObjectTemplate> proxy_template;
6300      i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6301      i::Handle<i::FunctionTemplateInfo> global_constructor;
6302      i::Handle<i::HeapObject> named_interceptor(
6303          isolate->factory()->undefined_value());
6304      i::Handle<i::HeapObject> indexed_interceptor(
6305          isolate->factory()->undefined_value());
6306  
6307      if (!maybe_global_template.IsEmpty()) {
6308        v8::Local<v8::ObjectTemplate> global_template =
6309            maybe_global_template.ToLocalChecked();
6310        // Make sure that the global_template has a constructor.
6311        global_constructor = EnsureConstructor(isolate, *global_template);
6312  
6313        // Create a fresh template for the global proxy object.
6314        proxy_template =
6315            ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
6316        proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6317  
6318        // Set the global template to be the prototype template of
6319        // global proxy template.
6320        i::FunctionTemplateInfo::SetPrototypeTemplate(
6321            isolate, proxy_constructor, Utils::OpenHandle(*global_template));
6322  
6323        proxy_template->SetInternalFieldCount(
6324            global_template->InternalFieldCount());
6325  
6326        // Migrate security handlers from global_template to
6327        // proxy_template.  Temporarily removing access check
6328        // information from the global template.
6329        if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
6330          i::FunctionTemplateInfo::SetAccessCheckInfo(
6331              isolate, proxy_constructor,
6332              i::handle(global_constructor->GetAccessCheckInfo(), isolate));
6333          proxy_constructor->set_needs_access_check(
6334              global_constructor->needs_access_check());
6335          global_constructor->set_needs_access_check(false);
6336          i::FunctionTemplateInfo::SetAccessCheckInfo(
6337              isolate, global_constructor,
6338              i::ReadOnlyRoots(isolate).undefined_value_handle());
6339        }
6340  
6341        // Same for other interceptors. If the global constructor has
6342        // interceptors, we need to replace them temporarily with noop
6343        // interceptors, so the map is correctly marked as having interceptors,
6344        // but we don't invoke any.
6345        if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
6346          named_interceptor =
6347              handle(global_constructor->GetNamedPropertyHandler(), isolate);
6348          i::FunctionTemplateInfo::SetNamedPropertyHandler(
6349              isolate, global_constructor,
6350              i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6351        }
6352        if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
6353                isolate)) {
6354          indexed_interceptor =
6355              handle(global_constructor->GetIndexedPropertyHandler(), isolate);
6356          i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6357              isolate, global_constructor,
6358              i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6359        }
6360      }
6361  
6362      i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6363      if (!maybe_global_proxy.IsEmpty()) {
6364        maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6365            Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6366      }
6367      // Create the environment.
6368      InvokeBootstrapper<ObjectType> invoke;
6369      result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6370                             context_snapshot_index, embedder_fields_deserializer,
6371                             microtask_queue);
6372  
6373      // Restore the access check info and interceptors on the global template.
6374      if (!maybe_global_template.IsEmpty()) {
6375        DCHECK(!global_constructor.is_null());
6376        DCHECK(!proxy_constructor.is_null());
6377        i::FunctionTemplateInfo::SetAccessCheckInfo(
6378            isolate, global_constructor,
6379            i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6380        global_constructor->set_needs_access_check(
6381            proxy_constructor->needs_access_check());
6382        i::FunctionTemplateInfo::SetNamedPropertyHandler(
6383            isolate, global_constructor, named_interceptor);
6384        i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6385            isolate, global_constructor, indexed_interceptor);
6386      }
6387    }
6388    // Leave V8.
6389  
6390    return result;
6391  }
6392  
NewContext(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6393  Local<Context> NewContext(
6394      v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6395      v8::MaybeLocal<ObjectTemplate> global_template,
6396      v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6397      v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6398      v8::MicrotaskQueue* microtask_queue) {
6399    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6400    // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6401    // fail.
6402    // Sanity-check that the isolate is initialized and usable.
6403    CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT());
6404  
6405    TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6406    API_RCS_SCOPE(isolate, Context, New);
6407    i::HandleScope scope(isolate);
6408    ExtensionConfiguration no_extensions;
6409    if (extensions == nullptr) extensions = &no_extensions;
6410    i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6411        isolate, extensions, global_template, global_object,
6412        context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6413    if (env.is_null()) {
6414      if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6415      return Local<Context>();
6416    }
6417    return Utils::ToLocal(scope.CloseAndEscape(env));
6418  }
6419  
New(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,DeserializeInternalFieldsCallback internal_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6420  Local<Context> v8::Context::New(
6421      v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6422      v8::MaybeLocal<ObjectTemplate> global_template,
6423      v8::MaybeLocal<Value> global_object,
6424      DeserializeInternalFieldsCallback internal_fields_deserializer,
6425      v8::MicrotaskQueue* microtask_queue) {
6426    return NewContext(external_isolate, extensions, global_template,
6427                      global_object, 0, internal_fields_deserializer,
6428                      microtask_queue);
6429  }
6430  
FromSnapshot(v8::Isolate * external_isolate,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::ExtensionConfiguration * extensions,MaybeLocal<Value> global_object,v8::MicrotaskQueue * microtask_queue)6431  MaybeLocal<Context> v8::Context::FromSnapshot(
6432      v8::Isolate* external_isolate, size_t context_snapshot_index,
6433      v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6434      v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6435      v8::MicrotaskQueue* microtask_queue) {
6436    size_t index_including_default_context = context_snapshot_index + 1;
6437    if (!i::Snapshot::HasContextSnapshot(
6438            reinterpret_cast<i::Isolate*>(external_isolate),
6439            index_including_default_context)) {
6440      return MaybeLocal<Context>();
6441    }
6442    return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6443                      global_object, index_including_default_context,
6444                      embedder_fields_deserializer, microtask_queue);
6445  }
6446  
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6447  MaybeLocal<Object> v8::Context::NewRemoteContext(
6448      v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6449      v8::MaybeLocal<v8::Value> global_object) {
6450    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6451    API_RCS_SCOPE(isolate, Context, NewRemoteContext);
6452    i::HandleScope scope(isolate);
6453    i::Handle<i::FunctionTemplateInfo> global_constructor =
6454        EnsureConstructor(isolate, *global_template);
6455    Utils::ApiCheck(global_constructor->needs_access_check(),
6456                    "v8::Context::NewRemoteContext",
6457                    "Global template needs to have access checks enabled.");
6458    i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6459        i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6460        isolate);
6461    Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6462                    "v8::Context::NewRemoteContext",
6463                    "Global template needs to have access check handlers.");
6464    i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6465        isolate, nullptr, global_template, global_object, 0,
6466        DeserializeInternalFieldsCallback(), nullptr);
6467    if (global_proxy.is_null()) {
6468      if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6469      return MaybeLocal<Object>();
6470    }
6471    return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6472  }
6473  
SetSecurityToken(Local<Value> token)6474  void v8::Context::SetSecurityToken(Local<Value> token) {
6475    i::Handle<i::Context> env = Utils::OpenHandle(this);
6476    i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6477    env->set_security_token(*token_handle);
6478  }
6479  
UseDefaultSecurityToken()6480  void v8::Context::UseDefaultSecurityToken() {
6481    i::Handle<i::Context> env = Utils::OpenHandle(this);
6482    env->set_security_token(env->global_object());
6483  }
6484  
GetSecurityToken()6485  Local<Value> v8::Context::GetSecurityToken() {
6486    i::Handle<i::Context> env = Utils::OpenHandle(this);
6487    i::Isolate* isolate = env->GetIsolate();
6488    i::Object security_token = env->security_token();
6489    i::Handle<i::Object> token_handle(security_token, isolate);
6490    return Utils::ToLocal(token_handle);
6491  }
6492  
GetIsolate()6493  v8::Isolate* Context::GetIsolate() {
6494    i::Handle<i::Context> env = Utils::OpenHandle(this);
6495    return reinterpret_cast<Isolate*>(env->GetIsolate());
6496  }
6497  
GetMicrotaskQueue()6498  v8::MicrotaskQueue* Context::GetMicrotaskQueue() {
6499    i::Handle<i::Context> env = Utils::OpenHandle(this);
6500    Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue",
6501                    "Must be calld on a native context");
6502    return i::Handle<i::NativeContext>::cast(env)->microtask_queue();
6503  }
6504  
Global()6505  v8::Local<v8::Object> Context::Global() {
6506    i::Handle<i::Context> context = Utils::OpenHandle(this);
6507    i::Isolate* isolate = context->GetIsolate();
6508    i::Handle<i::Object> global(context->global_proxy(), isolate);
6509    // TODO(chromium:324812): This should always return the global proxy
6510    // but can't presently as calls to GetProtoype will return the wrong result.
6511    if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6512            context->global_object())) {
6513      global = i::Handle<i::Object>(context->global_object(), isolate);
6514    }
6515    return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6516  }
6517  
DetachGlobal()6518  void Context::DetachGlobal() {
6519    i::Handle<i::Context> context = Utils::OpenHandle(this);
6520    i::Isolate* isolate = context->GetIsolate();
6521    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6522    isolate->DetachGlobal(context);
6523  }
6524  
GetExtrasBindingObject()6525  Local<v8::Object> Context::GetExtrasBindingObject() {
6526    i::Handle<i::Context> context = Utils::OpenHandle(this);
6527    i::Isolate* isolate = context->GetIsolate();
6528    i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6529    return Utils::ToLocal(binding);
6530  }
6531  
AllowCodeGenerationFromStrings(bool allow)6532  void Context::AllowCodeGenerationFromStrings(bool allow) {
6533    i::Handle<i::Context> context = Utils::OpenHandle(this);
6534    i::Isolate* isolate = context->GetIsolate();
6535    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6536    context->set_allow_code_gen_from_strings(
6537        allow ? i::ReadOnlyRoots(isolate).true_value()
6538              : i::ReadOnlyRoots(isolate).false_value());
6539  }
6540  
IsCodeGenerationFromStringsAllowed() const6541  bool Context::IsCodeGenerationFromStringsAllowed() const {
6542    i::Context context = *Utils::OpenHandle(this);
6543    return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6544  }
6545  
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6546  void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6547    i::Handle<i::Context> context = Utils::OpenHandle(this);
6548    i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6549    context->set_error_message_for_code_gen_from_strings(*error_handle);
6550  }
6551  
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6552  void Context::SetAbortScriptExecution(
6553      Context::AbortScriptExecutionCallback callback) {
6554    i::Handle<i::Context> context = Utils::OpenHandle(this);
6555    i::Isolate* isolate = context->GetIsolate();
6556    if (callback == nullptr) {
6557      context->set_script_execution_callback(
6558          i::ReadOnlyRoots(isolate).undefined_value());
6559    } else {
6560      SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6561                        callback);
6562    }
6563  }
6564  
GetContinuationPreservedEmbedderData() const6565  Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6566    i::Handle<i::Context> context = Utils::OpenHandle(this);
6567    i::Isolate* isolate = context->GetIsolate();
6568    i::Handle<i::Object> data(
6569        context->native_context().continuation_preserved_embedder_data(),
6570        isolate);
6571    return ToApiHandle<Object>(data);
6572  }
6573  
SetContinuationPreservedEmbedderData(Local<Value> data)6574  void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6575    i::Handle<i::Context> context = Utils::OpenHandle(this);
6576    i::Isolate* isolate = context->GetIsolate();
6577    if (data.IsEmpty())
6578      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6579    context->native_context().set_continuation_preserved_embedder_data(
6580        *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6581  }
6582  
SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6583  void v8::Context::SetPromiseHooks(Local<Function> init_hook,
6584                                    Local<Function> before_hook,
6585                                    Local<Function> after_hook,
6586                                    Local<Function> resolve_hook) {
6587  #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6588    i::Handle<i::Context> context = Utils::OpenHandle(this);
6589    i::Isolate* isolate = context->GetIsolate();
6590  
6591    i::Handle<i::Object> init = isolate->factory()->undefined_value();
6592    i::Handle<i::Object> before = isolate->factory()->undefined_value();
6593    i::Handle<i::Object> after = isolate->factory()->undefined_value();
6594    i::Handle<i::Object> resolve = isolate->factory()->undefined_value();
6595  
6596    bool has_hook = false;
6597  
6598    if (!init_hook.IsEmpty()) {
6599      init = Utils::OpenHandle(*init_hook);
6600      has_hook = true;
6601    }
6602    if (!before_hook.IsEmpty()) {
6603      before = Utils::OpenHandle(*before_hook);
6604      has_hook = true;
6605    }
6606    if (!after_hook.IsEmpty()) {
6607      after = Utils::OpenHandle(*after_hook);
6608      has_hook = true;
6609    }
6610    if (!resolve_hook.IsEmpty()) {
6611      resolve = Utils::OpenHandle(*resolve_hook);
6612      has_hook = true;
6613    }
6614  
6615    isolate->SetHasContextPromiseHooks(has_hook);
6616  
6617    context->native_context().set_promise_hook_init_function(*init);
6618    context->native_context().set_promise_hook_before_function(*before);
6619    context->native_context().set_promise_hook_after_function(*after);
6620    context->native_context().set_promise_hook_resolve_function(*resolve);
6621  #else   // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6622    Utils::ApiCheck(false, "v8::Context::SetPromiseHook",
6623                    "V8 was compiled without JavaScript Promise hooks");
6624  #endif  // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6625  }
6626  
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6627  MaybeLocal<Context> metrics::Recorder::GetContext(
6628      Isolate* isolate, metrics::Recorder::ContextId id) {
6629    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6630    return i_isolate->GetContextFromRecorderContextId(id);
6631  }
6632  
GetContextId(Local<Context> context)6633  metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6634      Local<Context> context) {
6635    i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6636    i::Isolate* isolate = i_context->GetIsolate();
6637    return isolate->GetOrRegisterRecorderContextId(
6638        handle(i_context->native_context(), isolate));
6639  }
6640  
Get(v8::Isolate * isolate)6641  metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6642    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6643    return *i_isolate->GetCurrentLongTaskStats();
6644  }
6645  
6646  namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6647  i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6648                                              i::FixedArray list, size_t index) {
6649    if (index < static_cast<size_t>(list.length())) {
6650      int int_index = static_cast<int>(index);
6651      i::Object object = list.get(int_index);
6652      if (!object.IsTheHole(isolate)) {
6653        list.set_the_hole(isolate, int_index);
6654        // Shrink the list so that the last element is not the hole (unless it's
6655        // the first element, because we don't want to end up with a non-canonical
6656        // empty FixedArray).
6657        int last = list.length() - 1;
6658        while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6659        if (last != -1) list.Shrink(isolate, last + 1);
6660        return i::Handle<i::Object>(object, isolate).location();
6661      }
6662    }
6663    return nullptr;
6664  }
6665  }  // anonymous namespace
6666  
GetDataFromSnapshotOnce(size_t index)6667  i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6668    auto context = Utils::OpenHandle(this);
6669    i::Isolate* i_isolate = context->GetIsolate();
6670    i::FixedArray list = context->serialized_objects();
6671    return GetSerializedDataFromFixedArray(i_isolate, list, index);
6672  }
6673  
NewInstance(Local<Context> context)6674  MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6675    PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6676    auto self = Utils::OpenHandle(this);
6677    Local<Object> result;
6678    has_pending_exception = !ToLocal<Object>(
6679        i::ApiNatives::InstantiateObject(isolate, self), &result);
6680    RETURN_ON_FAILED_EXECUTION(Object);
6681    RETURN_ESCAPED(result);
6682  }
6683  
CheckCast(Data * that)6684  void v8::ObjectTemplate::CheckCast(Data* that) {
6685    i::Handle<i::Object> obj = Utils::OpenHandle(that);
6686    Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6687                    "Value is not an ObjectTemplate");
6688  }
6689  
CheckCast(Data * that)6690  void v8::FunctionTemplate::CheckCast(Data* that) {
6691    i::Handle<i::Object> obj = Utils::OpenHandle(that);
6692    Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6693                    "Value is not a FunctionTemplate");
6694  }
6695  
CheckCast(Data * that)6696  void v8::Signature::CheckCast(Data* that) {
6697    i::Handle<i::Object> obj = Utils::OpenHandle(that);
6698    Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6699                    "Value is not a Signature");
6700  }
6701  
CheckCast(Data * that)6702  void v8::AccessorSignature::CheckCast(Data* that) {
6703    i::Handle<i::Object> obj = Utils::OpenHandle(that);
6704    Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6705                    "Value is not an AccessorSignature");
6706  }
6707  
GetFunction(Local<Context> context)6708  MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6709    PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6710    auto self = Utils::OpenHandle(this);
6711    Local<Function> result;
6712    has_pending_exception =
6713        !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6714    RETURN_ON_FAILED_EXECUTION(Function);
6715    RETURN_ESCAPED(result);
6716  }
6717  
NewRemoteInstance()6718  MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6719    auto self = Utils::OpenHandle(this);
6720    i::Isolate* isolate = self->GetIsolate();
6721    API_RCS_SCOPE(isolate, FunctionTemplate, NewRemoteInstance);
6722    i::HandleScope scope(isolate);
6723    i::Handle<i::FunctionTemplateInfo> constructor =
6724        EnsureConstructor(isolate, *InstanceTemplate());
6725    Utils::ApiCheck(constructor->needs_access_check(),
6726                    "v8::FunctionTemplate::NewRemoteInstance",
6727                    "InstanceTemplate needs to have access checks enabled.");
6728    i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6729        i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6730    Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6731                    "v8::FunctionTemplate::NewRemoteInstance",
6732                    "InstanceTemplate needs to have access check handlers.");
6733    i::Handle<i::JSObject> object;
6734    if (!i::ApiNatives::InstantiateRemoteObject(
6735             Utils::OpenHandle(*InstanceTemplate()))
6736             .ToHandle(&object)) {
6737      if (isolate->has_pending_exception()) {
6738        isolate->OptionalRescheduleException(true);
6739      }
6740      return MaybeLocal<Object>();
6741    }
6742    return Utils::ToLocal(scope.CloseAndEscape(object));
6743  }
6744  
HasInstance(v8::Local<v8::Value> value)6745  bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6746    auto self = Utils::OpenHandle(this);
6747    auto obj = Utils::OpenHandle(*value);
6748    if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6749      return true;
6750    }
6751    if (obj->IsJSGlobalProxy()) {
6752      // If it's a global proxy, then test with the global object. Note that the
6753      // inner global object may not necessarily be a JSGlobalObject.
6754      i::PrototypeIterator iter(self->GetIsolate(),
6755                                i::JSObject::cast(*obj).map());
6756      // The global proxy should always have a prototype, as it is a bug to call
6757      // this on a detached JSGlobalProxy.
6758      DCHECK(!iter.IsAtEnd());
6759      return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6760    }
6761    return false;
6762  }
6763  
IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6764  bool FunctionTemplate::IsLeafTemplateForApiObject(
6765      v8::Local<v8::Value> value) const {
6766    i::DisallowGarbageCollection no_gc;
6767  
6768    i::Object object = *Utils::OpenHandle(*value);
6769  
6770    auto self = Utils::OpenHandle(this);
6771    return self->IsLeafTemplateForApiObject(object);
6772  }
6773  
New(Isolate * isolate,void * value)6774  Local<External> v8::External::New(Isolate* isolate, void* value) {
6775    STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6776    // Nullptr is not allowed here because serialization/deserialization of
6777    // nullptr external api references is not possible as nullptr is used as an
6778    // external_references table terminator, see v8::SnapshotCreator()
6779    // constructors.
6780    DCHECK_NOT_NULL(value);
6781    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6782    API_RCS_SCOPE(i_isolate, External, New);
6783    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6784    i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6785    return Utils::ExternalToLocal(external);
6786  }
6787  
Value() const6788  void* External::Value() const {
6789    auto self = Utils::OpenHandle(this);
6790    return i::JSExternalObject::cast(*self).value();
6791  }
6792  
6793  // anonymous namespace for string creation helper functions
6794  namespace {
6795  
StringLength(const char * string)6796  inline int StringLength(const char* string) {
6797    size_t len = strlen(string);
6798    CHECK_GE(i::kMaxInt, len);
6799    return static_cast<int>(len);
6800  }
6801  
StringLength(const uint8_t * string)6802  inline int StringLength(const uint8_t* string) {
6803    return StringLength(reinterpret_cast<const char*>(string));
6804  }
6805  
StringLength(const uint16_t * string)6806  inline int StringLength(const uint16_t* string) {
6807    size_t length = 0;
6808    while (string[length] != '\0') length++;
6809    CHECK_GE(i::kMaxInt, length);
6810    return static_cast<int>(length);
6811  }
6812  
6813  V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6814  inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6815                                             NewStringType type,
6816                                             base::Vector<const char> string) {
6817    if (type == NewStringType::kInternalized) {
6818      return factory->InternalizeUtf8String(string);
6819    }
6820    return factory->NewStringFromUtf8(string);
6821  }
6822  
6823  V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6824  inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6825                                             NewStringType type,
6826                                             base::Vector<const uint8_t> string) {
6827    if (type == NewStringType::kInternalized) {
6828      return factory->InternalizeString(string);
6829    }
6830    return factory->NewStringFromOneByte(string);
6831  }
6832  
6833  V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6834  inline i::MaybeHandle<i::String> NewString(
6835      i::Factory* factory, NewStringType type,
6836      base::Vector<const uint16_t> string) {
6837    if (type == NewStringType::kInternalized) {
6838      return factory->InternalizeString(string);
6839    }
6840    return factory->NewStringFromTwoByte(string);
6841  }
6842  
6843  STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6844  
6845  }  // anonymous namespace
6846  
6847  // TODO(dcarney): throw a context free exception.
6848  #define NEW_STRING(isolate, class_name, function_name, Char, data, type,   \
6849                     length)                                                 \
6850    MaybeLocal<String> result;                                               \
6851    if (length == 0) {                                                       \
6852      result = String::Empty(isolate);                                       \
6853    } else if (length > i::String::kMaxLength) {                             \
6854      result = MaybeLocal<String>();                                         \
6855    } else {                                                                 \
6856      i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6857      ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);                            \
6858      API_RCS_SCOPE(i_isolate, class_name, function_name);                   \
6859      if (length < 0) length = StringLength(data);                           \
6860      i::Handle<i::String> handle_result =                                   \
6861          NewString(i_isolate->factory(), type,                              \
6862                    base::Vector<const Char>(data, length))                  \
6863              .ToHandleChecked();                                            \
6864      result = Utils::ToLocal(handle_result);                                \
6865    }
6866  
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6867  Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6868                                           NewStringType type, int length) {
6869    DCHECK_LE(length, i::String::kMaxLength);
6870    i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6871    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6872    API_RCS_SCOPE(i_isolate, String, NewFromUtf8Literal);
6873    i::Handle<i::String> handle_result =
6874        NewString(i_isolate->factory(), type,
6875                  base::Vector<const char>(literal, length))
6876            .ToHandleChecked();
6877    return Utils::ToLocal(handle_result);
6878  }
6879  
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6880  MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6881                                         NewStringType type, int length) {
6882    NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6883    return result;
6884  }
6885  
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6886  MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6887                                            NewStringType type, int length) {
6888    NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6889    return result;
6890  }
6891  
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6892  MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6893                                            const uint16_t* data,
6894                                            NewStringType type, int length) {
6895    NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6896    return result;
6897  }
6898  
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6899  Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6900                                   Local<String> right) {
6901    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6902    i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6903    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6904    API_RCS_SCOPE(isolate, String, Concat);
6905    i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6906    // If we are steering towards a range error, do not wait for the error to be
6907    // thrown, and return the null handle instead.
6908    if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6909      return Local<String>();
6910    }
6911    i::Handle<i::String> result = isolate->factory()
6912                                      ->NewConsString(left_string, right_string)
6913                                      .ToHandleChecked();
6914    return Utils::ToLocal(result);
6915  }
6916  
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6917  MaybeLocal<String> v8::String::NewExternalTwoByte(
6918      Isolate* isolate, v8::String::ExternalStringResource* resource) {
6919    CHECK(resource && resource->data());
6920    // TODO(dcarney): throw a context free exception.
6921    if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6922      return MaybeLocal<String>();
6923    }
6924    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6925    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6926    API_RCS_SCOPE(i_isolate, String, NewExternalTwoByte);
6927    if (resource->length() > 0) {
6928      i::Handle<i::String> string = i_isolate->factory()
6929                                        ->NewExternalStringFromTwoByte(resource)
6930                                        .ToHandleChecked();
6931      return Utils::ToLocal(string);
6932    } else {
6933      // The resource isn't going to be used, free it immediately.
6934      resource->Dispose();
6935      return Utils::ToLocal(i_isolate->factory()->empty_string());
6936    }
6937  }
6938  
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6939  MaybeLocal<String> v8::String::NewExternalOneByte(
6940      Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6941    CHECK_NOT_NULL(resource);
6942    // TODO(dcarney): throw a context free exception.
6943    if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6944      return MaybeLocal<String>();
6945    }
6946    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6947    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6948    API_RCS_SCOPE(i_isolate, String, NewExternalOneByte);
6949    if (resource->length() == 0) {
6950      // The resource isn't going to be used, free it immediately.
6951      resource->Dispose();
6952      return Utils::ToLocal(i_isolate->factory()->empty_string());
6953    }
6954    CHECK_NOT_NULL(resource->data());
6955    i::Handle<i::String> string = i_isolate->factory()
6956                                      ->NewExternalStringFromOneByte(resource)
6957                                      .ToHandleChecked();
6958    return Utils::ToLocal(string);
6959  }
6960  
MakeExternal(v8::String::ExternalStringResource * resource)6961  bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6962    i::DisallowGarbageCollection no_gc;
6963  
6964    i::String obj = *Utils::OpenHandle(this);
6965  
6966    if (obj.IsThinString()) {
6967      obj = i::ThinString::cast(obj).actual();
6968    }
6969  
6970    if (!obj.SupportsExternalization()) {
6971      return false;
6972    }
6973  
6974    // It is safe to call GetIsolateFromWritableHeapObject because
6975    // SupportsExternalization already checked that the object is writable.
6976    i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6977    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6978  
6979    CHECK(resource && resource->data());
6980  
6981    bool result = obj.MakeExternal(resource);
6982    DCHECK(result);
6983    DCHECK(obj.IsExternalString());
6984    return result;
6985  }
6986  
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6987  bool v8::String::MakeExternal(
6988      v8::String::ExternalOneByteStringResource* resource) {
6989    i::DisallowGarbageCollection no_gc;
6990  
6991    i::String obj = *Utils::OpenHandle(this);
6992  
6993    if (obj.IsThinString()) {
6994      obj = i::ThinString::cast(obj).actual();
6995    }
6996  
6997    if (!obj.SupportsExternalization()) {
6998      return false;
6999    }
7000  
7001    // It is safe to call GetIsolateFromWritableHeapObject because
7002    // SupportsExternalization already checked that the object is writable.
7003    i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
7004    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7005  
7006    CHECK(resource && resource->data());
7007  
7008    bool result = obj.MakeExternal(resource);
7009    DCHECK_IMPLIES(result, obj.IsExternalString());
7010    return result;
7011  }
7012  
CanMakeExternal() const7013  bool v8::String::CanMakeExternal() const {
7014    i::String obj = *Utils::OpenHandle(this);
7015  
7016    if (obj.IsThinString()) {
7017      obj = i::ThinString::cast(obj).actual();
7018    }
7019  
7020    if (!obj.SupportsExternalization()) {
7021      return false;
7022    }
7023  
7024    // Only old space strings should be externalized.
7025    return !i::Heap::InYoungGeneration(obj);
7026  }
7027  
StringEquals(Local<String> that) const7028  bool v8::String::StringEquals(Local<String> that) const {
7029    auto self = Utils::OpenHandle(this);
7030    auto other = Utils::OpenHandle(*that);
7031    return self->Equals(*other);
7032  }
7033  
GetIsolate()7034  Isolate* v8::Object::GetIsolate() {
7035    i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7036    return reinterpret_cast<Isolate*>(i_isolate);
7037  }
7038  
New(Isolate * isolate)7039  Local<v8::Object> v8::Object::New(Isolate* isolate) {
7040    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7041    API_RCS_SCOPE(i_isolate, Object, New);
7042    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7043    i::Handle<i::JSObject> obj =
7044        i_isolate->factory()->NewJSObject(i_isolate->object_function());
7045    return Utils::ToLocal(obj);
7046  }
7047  
7048  namespace {
7049  
7050  // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference
7051  // in the return types of the different Add functions:
7052  // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns
7053  // Handle.
7054  template <typename T>
ToHandle(i::Handle<T> h)7055  i::Handle<T> ToHandle(i::Handle<T> h) {
7056    return h;
7057  }
7058  template <typename T>
ToHandle(i::MaybeHandle<T> h)7059  i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
7060    return h.ToHandleChecked();
7061  }
7062  
7063  template <typename Dictionary>
AddPropertiesAndElementsToObject(i::Isolate * i_isolate,i::Handle<Dictionary> & properties,i::Handle<i::FixedArrayBase> & elements,Local<Name> * names,Local<Value> * values,size_t length)7064  void AddPropertiesAndElementsToObject(i::Isolate* i_isolate,
7065                                        i::Handle<Dictionary>& properties,
7066                                        i::Handle<i::FixedArrayBase>& elements,
7067                                        Local<Name>* names, Local<Value>* values,
7068                                        size_t length) {
7069    for (size_t i = 0; i < length; ++i) {
7070      i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
7071      i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
7072  
7073      // See if the {name} is a valid array index, in which case we need to
7074      // add the {name}/{value} pair to the {elements}, otherwise they end
7075      // up in the {properties} backing store.
7076      uint32_t index;
7077      if (name->AsArrayIndex(&index)) {
7078        // If this is the first element, allocate a proper
7079        // dictionary elements backing store for {elements}.
7080        if (!elements->IsNumberDictionary()) {
7081          elements =
7082              i::NumberDictionary::New(i_isolate, static_cast<int>(length));
7083        }
7084        elements = i::NumberDictionary::Set(
7085            i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
7086            value);
7087      } else {
7088        // Internalize the {name} first.
7089        name = i_isolate->factory()->InternalizeName(name);
7090        i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
7091        if (entry.is_not_found()) {
7092          // Add the {name}/{value} pair as a new entry.
7093          properties = ToHandle(Dictionary::Add(
7094              i_isolate, properties, name, value, i::PropertyDetails::Empty()));
7095        } else {
7096          // Overwrite the {entry} with the {value}.
7097          properties->ValueAtPut(entry, *value);
7098        }
7099      }
7100    }
7101  }
7102  
7103  }  // namespace
7104  
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)7105  Local<v8::Object> v8::Object::New(Isolate* isolate,
7106                                    Local<Value> prototype_or_null,
7107                                    Local<Name>* names, Local<Value>* values,
7108                                    size_t length) {
7109    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7110    i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
7111    if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
7112                         "v8::Object::New", "prototype must be null or object")) {
7113      return Local<v8::Object>();
7114    }
7115    API_RCS_SCOPE(i_isolate, Object, New);
7116    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7117  
7118    i::Handle<i::FixedArrayBase> elements =
7119        i_isolate->factory()->empty_fixed_array();
7120  
7121    // We assume that this API is mostly used to create objects with named
7122    // properties, and so we default to creating a properties backing store
7123    // large enough to hold all of them, while we start with no elements
7124    // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
7125    if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
7126      i::Handle<i::SwissNameDictionary> properties =
7127          i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length));
7128      AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7129                                       values, length);
7130      i::Handle<i::JSObject> obj =
7131          i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7132              i::Handle<i::HeapObject>::cast(proto), properties, elements);
7133      return Utils::ToLocal(obj);
7134    } else {
7135      i::Handle<i::NameDictionary> properties =
7136          i::NameDictionary::New(i_isolate, static_cast<int>(length));
7137      AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7138                                       values, length);
7139      i::Handle<i::JSObject> obj =
7140          i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7141              i::Handle<i::HeapObject>::cast(proto), properties, elements);
7142      return Utils::ToLocal(obj);
7143    }
7144  }
7145  
New(Isolate * isolate,double value)7146  Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
7147    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7148    API_RCS_SCOPE(i_isolate, NumberObject, New);
7149    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7150    i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
7151    i::Handle<i::Object> obj =
7152        i::Object::ToObject(i_isolate, number).ToHandleChecked();
7153    return Utils::ToLocal(obj);
7154  }
7155  
ValueOf() const7156  double v8::NumberObject::ValueOf() const {
7157    i::Handle<i::Object> obj = Utils::OpenHandle(this);
7158    i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7159        i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7160    API_RCS_SCOPE(js_primitive_wrapper->GetIsolate(), NumberObject, NumberValue);
7161    return js_primitive_wrapper->value().Number();
7162  }
7163  
New(Isolate * isolate,int64_t value)7164  Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
7165    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7166    API_RCS_SCOPE(i_isolate, BigIntObject, New);
7167    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7168    i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
7169    i::Handle<i::Object> obj =
7170        i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
7171    return Utils::ToLocal(obj);
7172  }
7173  
ValueOf() const7174  Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
7175    i::Handle<i::Object> obj = Utils::OpenHandle(this);
7176    i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7177        i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7178    i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7179    API_RCS_SCOPE(isolate, BigIntObject, BigIntValue);
7180    return Utils::ToLocal(i::Handle<i::BigInt>(
7181        i::BigInt::cast(js_primitive_wrapper->value()), isolate));
7182  }
7183  
New(Isolate * isolate,bool value)7184  Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7185    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7186    API_RCS_SCOPE(i_isolate, BooleanObject, New);
7187    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7188    i::Handle<i::Object> boolean(value
7189                                     ? i::ReadOnlyRoots(i_isolate).true_value()
7190                                     : i::ReadOnlyRoots(i_isolate).false_value(),
7191                                 i_isolate);
7192    i::Handle<i::Object> obj =
7193        i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7194    return Utils::ToLocal(obj);
7195  }
7196  
ValueOf() const7197  bool v8::BooleanObject::ValueOf() const {
7198    i::Object obj = *Utils::OpenHandle(this);
7199    i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
7200    i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
7201    API_RCS_SCOPE(isolate, BooleanObject, BooleanValue);
7202    return js_primitive_wrapper.value().IsTrue(isolate);
7203  }
7204  
New(Isolate * v8_isolate,Local<String> value)7205  Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
7206                                         Local<String> value) {
7207    i::Handle<i::String> string = Utils::OpenHandle(*value);
7208    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7209    API_RCS_SCOPE(isolate, StringObject, New);
7210    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7211    i::Handle<i::Object> obj =
7212        i::Object::ToObject(isolate, string).ToHandleChecked();
7213    return Utils::ToLocal(obj);
7214  }
7215  
ValueOf() const7216  Local<v8::String> v8::StringObject::ValueOf() const {
7217    i::Handle<i::Object> obj = Utils::OpenHandle(this);
7218    i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7219        i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7220    i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7221    API_RCS_SCOPE(isolate, StringObject, StringValue);
7222    return Utils::ToLocal(i::Handle<i::String>(
7223        i::String::cast(js_primitive_wrapper->value()), isolate));
7224  }
7225  
New(Isolate * isolate,Local<Symbol> value)7226  Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7227    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7228    API_RCS_SCOPE(i_isolate, SymbolObject, New);
7229    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7230    i::Handle<i::Object> obj =
7231        i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
7232            .ToHandleChecked();
7233    return Utils::ToLocal(obj);
7234  }
7235  
ValueOf() const7236  Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7237    i::Handle<i::Object> obj = Utils::OpenHandle(this);
7238    i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7239        i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7240    i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7241    API_RCS_SCOPE(isolate, SymbolObject, SymbolValue);
7242    return Utils::ToLocal(i::Handle<i::Symbol>(
7243        i::Symbol::cast(js_primitive_wrapper->value()), isolate));
7244  }
7245  
New(Local<Context> context,double time)7246  MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7247    if (std::isnan(time)) {
7248      // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7249      time = std::numeric_limits<double>::quiet_NaN();
7250    }
7251    PREPARE_FOR_EXECUTION(context, Date, New, Value);
7252    Local<Value> result;
7253    has_pending_exception = !ToLocal<Value>(
7254        i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7255        &result);
7256    RETURN_ON_FAILED_EXECUTION(Value);
7257    RETURN_ESCAPED(result);
7258  }
7259  
ValueOf() const7260  double v8::Date::ValueOf() const {
7261    i::Handle<i::Object> obj = Utils::OpenHandle(this);
7262    i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7263    API_RCS_SCOPE(jsdate->GetIsolate(), Date, NumberValue);
7264    return jsdate->value().Number();
7265  }
7266  
7267  // Assert that the static TimeZoneDetection cast in
7268  // DateTimeConfigurationChangeNotification is valid.
7269  #define TIME_ZONE_DETECTION_ASSERT_EQ(value)                     \
7270    STATIC_ASSERT(                                                 \
7271        static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
7272        static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
7273  TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7274  TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7275  #undef TIME_ZONE_DETECTION_ASSERT_EQ
7276  
7277  MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7278                                         Local<String> pattern, Flags flags) {
7279    PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7280    Local<v8::RegExp> result;
7281    has_pending_exception =
7282        !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7283                                          static_cast<i::JSRegExp::Flags>(flags)),
7284                         &result);
7285    RETURN_ON_FAILED_EXECUTION(RegExp);
7286    RETURN_ESCAPED(result);
7287  }
7288  
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7289  MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
7290      Local<Context> context, Local<String> pattern, Flags flags,
7291      uint32_t backtrack_limit) {
7292    Utils::ApiCheck(i::Smi::IsValid(backtrack_limit),
7293                    "v8::RegExp::NewWithBacktrackLimit",
7294                    "backtrack_limit is too large or too small.");
7295    Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit,
7296                    "v8::RegExp::NewWithBacktrackLimit",
7297                    "Must set backtrack_limit");
7298    PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7299    Local<v8::RegExp> result;
7300    has_pending_exception = !ToLocal<RegExp>(
7301        i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7302                         static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
7303        &result);
7304    RETURN_ON_FAILED_EXECUTION(RegExp);
7305    RETURN_ESCAPED(result);
7306  }
7307  
GetSource() const7308  Local<v8::String> v8::RegExp::GetSource() const {
7309    i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7310    return Utils::ToLocal(
7311        i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate()));
7312  }
7313  
7314  // Assert that the static flags cast in GetFlags is valid.
7315  #define REGEXP_FLAG_ASSERT_EQ(flag)                   \
7316    STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7317                  static_cast<int>(i::JSRegExp::flag))
7318  REGEXP_FLAG_ASSERT_EQ(kNone);
7319  REGEXP_FLAG_ASSERT_EQ(kGlobal);
7320  REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7321  REGEXP_FLAG_ASSERT_EQ(kMultiline);
7322  REGEXP_FLAG_ASSERT_EQ(kSticky);
7323  REGEXP_FLAG_ASSERT_EQ(kUnicode);
7324  REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7325  REGEXP_FLAG_ASSERT_EQ(kLinear);
7326  #undef REGEXP_FLAG_ASSERT_EQ
7327  
GetFlags() const7328  v8::RegExp::Flags v8::RegExp::GetFlags() const {
7329    i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7330    return RegExp::Flags(static_cast<int>(obj->flags()));
7331  }
7332  
Exec(Local<Context> context,Local<v8::String> subject)7333  MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
7334                                          Local<v8::String> subject) {
7335    PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
7336  
7337    i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
7338    i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
7339  
7340    // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
7341    // mind. It fetches the 'exec' property and then calls it through JSEntry.
7342    // Unfortunately, this is currently the only full implementation of
7343    // RegExp.prototype.exec available in C++.
7344    Local<v8::Object> result;
7345    has_pending_exception = !ToLocal<Object>(
7346        i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
7347                                   isolate->factory()->undefined_value()),
7348        &result);
7349  
7350    RETURN_ON_FAILED_EXECUTION(Object);
7351    RETURN_ESCAPED(result);
7352  }
7353  
New(Isolate * isolate,int length)7354  Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7355    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7356    API_RCS_SCOPE(i_isolate, Array, New);
7357    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7358    int real_length = length > 0 ? length : 0;
7359    i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7360    i::Handle<i::Object> length_obj =
7361        i_isolate->factory()->NewNumberFromInt(real_length);
7362    obj->set_length(*length_obj);
7363    return Utils::ToLocal(obj);
7364  }
7365  
New(Isolate * isolate,Local<Value> * elements,size_t length)7366  Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
7367                                  size_t length) {
7368    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7369    i::Factory* factory = i_isolate->factory();
7370    API_RCS_SCOPE(i_isolate, Array, New);
7371    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7372    int len = static_cast<int>(length);
7373  
7374    i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
7375    for (int i = 0; i < len; i++) {
7376      i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
7377      result->set(i, *element);
7378    }
7379  
7380    return Utils::ToLocal(
7381        factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
7382  }
7383  
Length() const7384  uint32_t v8::Array::Length() const {
7385    i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7386    i::Object length = obj->length();
7387    if (length.IsSmi()) {
7388      return i::Smi::ToInt(length);
7389    } else {
7390      return static_cast<uint32_t>(length.Number());
7391    }
7392  }
7393  
New(Isolate * isolate)7394  Local<v8::Map> v8::Map::New(Isolate* isolate) {
7395    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7396    API_RCS_SCOPE(i_isolate, Map, New);
7397    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7398    i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7399    return Utils::ToLocal(obj);
7400  }
7401  
Size() const7402  size_t v8::Map::Size() const {
7403    i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7404    return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7405  }
7406  
Clear()7407  void Map::Clear() {
7408    auto self = Utils::OpenHandle(this);
7409    i::Isolate* isolate = self->GetIsolate();
7410    API_RCS_SCOPE(isolate, Map, Clear);
7411    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7412    i::JSMap::Clear(isolate, self);
7413  }
7414  
Get(Local<Context> context,Local<Value> key)7415  MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7416    PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7417    auto self = Utils::OpenHandle(this);
7418    Local<Value> result;
7419    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7420    has_pending_exception =
7421        !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
7422                                                  self, arraysize(argv), argv),
7423                        &result);
7424    RETURN_ON_FAILED_EXECUTION(Value);
7425    RETURN_ESCAPED(result);
7426  }
7427  
Set(Local<Context> context,Local<Value> key,Local<Value> value)7428  MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7429                           Local<Value> value) {
7430    PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7431    auto self = Utils::OpenHandle(this);
7432    i::Handle<i::Object> result;
7433    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7434                                   Utils::OpenHandle(*value)};
7435    has_pending_exception =
7436        !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
7437                                   arraysize(argv), argv)
7438             .ToHandle(&result);
7439    RETURN_ON_FAILED_EXECUTION(Map);
7440    RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7441  }
7442  
Has(Local<Context> context,Local<Value> key)7443  Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7444    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7445    ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7446    auto self = Utils::OpenHandle(this);
7447    i::Handle<i::Object> result;
7448    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7449    has_pending_exception =
7450        !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
7451                                   arraysize(argv), argv)
7452             .ToHandle(&result);
7453    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7454    return Just(result->IsTrue(isolate));
7455  }
7456  
Delete(Local<Context> context,Local<Value> key)7457  Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7458    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7459    ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7460    auto self = Utils::OpenHandle(this);
7461    i::Handle<i::Object> result;
7462    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7463    has_pending_exception =
7464        !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
7465                                   arraysize(argv), argv)
7466             .ToHandle(&result);
7467    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7468    return Just(result->IsTrue(isolate));
7469  }
7470  
7471  namespace {
7472  
7473  enum class MapAsArrayKind {
7474    kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7475    kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7476    kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7477  };
7478  
7479  enum class SetAsArrayKind {
7480    kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7481    kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7482  };
7483  
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7484  i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7485                                   int offset, MapAsArrayKind kind) {
7486    i::Factory* factory = isolate->factory();
7487    i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7488                                       isolate);
7489    const bool collect_keys =
7490        kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7491    const bool collect_values =
7492        kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7493    int capacity = table->UsedCapacity();
7494    int max_length =
7495        (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7496    i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7497    int result_index = 0;
7498    {
7499      i::DisallowGarbageCollection no_gc;
7500      i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7501      for (int i = offset; i < capacity; ++i) {
7502        i::InternalIndex entry(i);
7503        i::Object key = table->KeyAt(entry);
7504        if (key == the_hole) continue;
7505        if (collect_keys) result->set(result_index++, key);
7506        if (collect_values) result->set(result_index++, table->ValueAt(entry));
7507      }
7508    }
7509    DCHECK_GE(max_length, result_index);
7510    if (result_index == 0) return factory->NewJSArray(0);
7511    result->Shrink(isolate, result_index);
7512    return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7513                                           result_index);
7514  }
7515  
7516  }  // namespace
7517  
AsArray() const7518  Local<Array> Map::AsArray() const {
7519    i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7520    i::Isolate* isolate = obj->GetIsolate();
7521    API_RCS_SCOPE(isolate, Map, AsArray);
7522    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7523    return Utils::ToLocal(
7524        MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7525  }
7526  
New(Isolate * isolate)7527  Local<v8::Set> v8::Set::New(Isolate* isolate) {
7528    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7529    API_RCS_SCOPE(i_isolate, Set, New);
7530    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7531    i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7532    return Utils::ToLocal(obj);
7533  }
7534  
Size() const7535  size_t v8::Set::Size() const {
7536    i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7537    return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7538  }
7539  
Clear()7540  void Set::Clear() {
7541    auto self = Utils::OpenHandle(this);
7542    i::Isolate* isolate = self->GetIsolate();
7543    API_RCS_SCOPE(isolate, Set, Clear);
7544    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7545    i::JSSet::Clear(isolate, self);
7546  }
7547  
Add(Local<Context> context,Local<Value> key)7548  MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7549    PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7550    auto self = Utils::OpenHandle(this);
7551    i::Handle<i::Object> result;
7552    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7553    has_pending_exception =
7554        !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7555                                   arraysize(argv), argv)
7556             .ToHandle(&result);
7557    RETURN_ON_FAILED_EXECUTION(Set);
7558    RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7559  }
7560  
Has(Local<Context> context,Local<Value> key)7561  Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7562    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7563    ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7564    auto self = Utils::OpenHandle(this);
7565    i::Handle<i::Object> result;
7566    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7567    has_pending_exception =
7568        !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7569                                   arraysize(argv), argv)
7570             .ToHandle(&result);
7571    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7572    return Just(result->IsTrue(isolate));
7573  }
7574  
Delete(Local<Context> context,Local<Value> key)7575  Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7576    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7577    ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7578    auto self = Utils::OpenHandle(this);
7579    i::Handle<i::Object> result;
7580    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7581    has_pending_exception =
7582        !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7583                                   arraysize(argv), argv)
7584             .ToHandle(&result);
7585    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7586    return Just(result->IsTrue(isolate));
7587  }
7588  
7589  namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7590  i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7591                                   int offset, SetAsArrayKind kind) {
7592    i::Factory* factory = isolate->factory();
7593    i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7594                                       isolate);
7595    // Elements skipped by |offset| may already be deleted.
7596    int capacity = table->UsedCapacity();
7597    const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7598    int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7599    if (max_length == 0) return factory->NewJSArray(0);
7600    i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7601    int result_index = 0;
7602    {
7603      i::DisallowGarbageCollection no_gc;
7604      i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7605      for (int i = offset; i < capacity; ++i) {
7606        i::InternalIndex entry(i);
7607        i::Object key = table->KeyAt(entry);
7608        if (key == the_hole) continue;
7609        result->set(result_index++, key);
7610        if (collect_key_values) result->set(result_index++, key);
7611      }
7612    }
7613    DCHECK_GE(max_length, result_index);
7614    if (result_index == 0) return factory->NewJSArray(0);
7615    result->Shrink(isolate, result_index);
7616    return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7617                                           result_index);
7618  }
7619  }  // namespace
7620  
AsArray() const7621  Local<Array> Set::AsArray() const {
7622    i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7623    i::Isolate* isolate = obj->GetIsolate();
7624    API_RCS_SCOPE(isolate, Set, AsArray);
7625    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7626    return Utils::ToLocal(
7627        SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7628  }
7629  
New(Local<Context> context)7630  MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7631    PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7632    Local<Promise::Resolver> result;
7633    has_pending_exception =
7634        !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7635    RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7636    RETURN_ESCAPED(result);
7637  }
7638  
GetPromise()7639  Local<Promise> Promise::Resolver::GetPromise() {
7640    i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7641    return Local<Promise>::Cast(Utils::ToLocal(promise));
7642  }
7643  
Resolve(Local<Context> context,Local<Value> value)7644  Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7645                                         Local<Value> value) {
7646    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7647    ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7648             i::HandleScope);
7649    auto self = Utils::OpenHandle(this);
7650    auto promise = i::Handle<i::JSPromise>::cast(self);
7651  
7652    if (promise->status() != Promise::kPending) {
7653      return Just(true);
7654    }
7655  
7656    has_pending_exception =
7657        i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7658    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7659    return Just(true);
7660  }
7661  
Reject(Local<Context> context,Local<Value> value)7662  Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7663                                        Local<Value> value) {
7664    auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7665    ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7666             i::HandleScope);
7667    auto self = Utils::OpenHandle(this);
7668    auto promise = i::Handle<i::JSPromise>::cast(self);
7669  
7670    if (promise->status() != Promise::kPending) {
7671      return Just(true);
7672    }
7673  
7674    has_pending_exception =
7675        i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7676    RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7677    return Just(true);
7678  }
7679  
Catch(Local<Context> context,Local<Function> handler)7680  MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7681                                     Local<Function> handler) {
7682    PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7683    auto self = Utils::OpenHandle(this);
7684    i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(),
7685                                   Utils::OpenHandle(*handler)};
7686    i::Handle<i::Object> result;
7687    // Do not call the built-in Promise.prototype.catch!
7688    // v8::Promise should not call out to a monkeypatched Promise.prototype.then
7689    // as the implementation of Promise.prototype.catch does.
7690    has_pending_exception =
7691        !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7692                                   arraysize(argv), argv)
7693             .ToHandle(&result);
7694    RETURN_ON_FAILED_EXECUTION(Promise);
7695    RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7696  }
7697  
Then(Local<Context> context,Local<Function> handler)7698  MaybeLocal<Promise> Promise::Then(Local<Context> context,
7699                                    Local<Function> handler) {
7700    PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7701    auto self = Utils::OpenHandle(this);
7702    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7703    i::Handle<i::Object> result;
7704    has_pending_exception =
7705        !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7706                                   arraysize(argv), argv)
7707             .ToHandle(&result);
7708    RETURN_ON_FAILED_EXECUTION(Promise);
7709    RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7710  }
7711  
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7712  MaybeLocal<Promise> Promise::Then(Local<Context> context,
7713                                    Local<Function> on_fulfilled,
7714                                    Local<Function> on_rejected) {
7715    PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7716    auto self = Utils::OpenHandle(this);
7717    i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7718                                   Utils::OpenHandle(*on_rejected)};
7719    i::Handle<i::Object> result;
7720    has_pending_exception =
7721        !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7722                                   arraysize(argv), argv)
7723             .ToHandle(&result);
7724    RETURN_ON_FAILED_EXECUTION(Promise);
7725    RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7726  }
7727  
HasHandler() const7728  bool Promise::HasHandler() const {
7729    i::JSReceiver promise = *Utils::OpenHandle(this);
7730    i::Isolate* isolate = promise.GetIsolate();
7731    API_RCS_SCOPE(isolate, Promise, HasRejectHandler);
7732    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7733    if (!promise.IsJSPromise()) return false;
7734    return i::JSPromise::cast(promise).has_handler();
7735  }
7736  
Result()7737  Local<Value> Promise::Result() {
7738    i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7739    i::Isolate* isolate = promise->GetIsolate();
7740    API_RCS_SCOPE(isolate, Promise, Result);
7741    i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7742    Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7743                    "Promise is still pending");
7744    i::Handle<i::Object> result(js_promise->result(), isolate);
7745    return Utils::ToLocal(result);
7746  }
7747  
State()7748  Promise::PromiseState Promise::State() {
7749    i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7750    API_RCS_SCOPE(promise->GetIsolate(), Promise, Status);
7751    i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7752    return static_cast<PromiseState>(js_promise->status());
7753  }
7754  
MarkAsHandled()7755  void Promise::MarkAsHandled() {
7756    i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7757    js_promise->set_has_handler(true);
7758  }
7759  
MarkAsSilent()7760  void Promise::MarkAsSilent() {
7761    i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7762    js_promise->set_is_silent(true);
7763  }
7764  
GetTarget()7765  Local<Value> Proxy::GetTarget() {
7766    i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7767    i::Handle<i::Object> target(self->target(), self->GetIsolate());
7768    return Utils::ToLocal(target);
7769  }
7770  
GetHandler()7771  Local<Value> Proxy::GetHandler() {
7772    i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7773    i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7774    return Utils::ToLocal(handler);
7775  }
7776  
IsRevoked() const7777  bool Proxy::IsRevoked() const {
7778    i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7779    return self->IsRevoked();
7780  }
7781  
Revoke()7782  void Proxy::Revoke() {
7783    i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7784    i::JSProxy::Revoke(self);
7785  }
7786  
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7787  MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7788                               Local<Object> local_handler) {
7789    PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7790    i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7791    i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7792    Local<Proxy> result;
7793    has_pending_exception =
7794        !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7795    RETURN_ON_FAILED_EXECUTION(Proxy);
7796    RETURN_ESCAPED(result);
7797  }
7798  
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7799  CompiledWasmModule::CompiledWasmModule(
7800      std::shared_ptr<internal::wasm::NativeModule> native_module,
7801      const char* source_url, size_t url_length)
7802      : native_module_(std::move(native_module)),
7803        source_url_(source_url, url_length) {
7804    CHECK_NOT_NULL(native_module_);
7805  }
7806  
Serialize()7807  OwnedBuffer CompiledWasmModule::Serialize() {
7808  #if V8_ENABLE_WEBASSEMBLY
7809    TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7810    i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7811    size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7812    std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7813    if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7814      return {};
7815    return {std::move(buffer), buffer_size};
7816  #else
7817    UNREACHABLE();
7818  #endif  // V8_ENABLE_WEBASSEMBLY
7819  }
7820  
GetWireBytesRef()7821  MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7822  #if V8_ENABLE_WEBASSEMBLY
7823    base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7824    return {bytes_vec.begin(), bytes_vec.size()};
7825  #else
7826    UNREACHABLE();
7827  #endif  // V8_ENABLE_WEBASSEMBLY
7828  }
7829  
Buffer()7830  Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() {
7831  #if V8_ENABLE_WEBASSEMBLY
7832    i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this);
7833    i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate());
7834    return Utils::ToLocal(buffer);
7835  #else
7836    UNREACHABLE();
7837  #endif  // V8_ENABLE_WEBASSEMBLY
7838  }
7839  
GetCompiledModule()7840  CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7841  #if V8_ENABLE_WEBASSEMBLY
7842    auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7843    auto url =
7844        i::handle(i::String::cast(obj->script().name()), obj->GetIsolate());
7845    int length;
7846    std::unique_ptr<char[]> cstring =
7847        url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7848    return CompiledWasmModule(std::move(obj->shared_native_module()),
7849                              cstring.get(), length);
7850  #else
7851    UNREACHABLE();
7852  #endif  // V8_ENABLE_WEBASSEMBLY
7853  }
7854  
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7855  MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7856      Isolate* isolate, const CompiledWasmModule& compiled_module) {
7857  #if V8_ENABLE_WEBASSEMBLY
7858    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7859    i::Handle<i::WasmModuleObject> module_object =
7860        i::wasm::GetWasmEngine()->ImportNativeModule(
7861            i_isolate, compiled_module.native_module_,
7862            base::VectorOf(compiled_module.source_url()));
7863    return Local<WasmModuleObject>::Cast(
7864        Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7865  #else
7866    UNREACHABLE();
7867  #endif  // V8_ENABLE_WEBASSEMBLY
7868  }
7869  
Compile(Isolate * isolate,MemorySpan<const uint8_t> wire_bytes)7870  MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
7871      Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) {
7872  #if V8_ENABLE_WEBASSEMBLY
7873    const uint8_t* start = wire_bytes.data();
7874    size_t length = wire_bytes.size();
7875    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7876    if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7877      return MaybeLocal<WasmModuleObject>();
7878    }
7879    i::MaybeHandle<i::JSObject> maybe_compiled;
7880    {
7881      i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
7882      auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
7883      maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
7884          i_isolate, enabled_features, &thrower,
7885          i::wasm::ModuleWireBytes(start, start + length));
7886    }
7887    CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception());
7888    if (maybe_compiled.is_null()) {
7889      i_isolate->OptionalRescheduleException(false);
7890      return MaybeLocal<WasmModuleObject>();
7891    }
7892    return Local<WasmModuleObject>::Cast(
7893        Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7894  #else
7895    Utils::ApiCheck(false, "WasmModuleObject::Compile",
7896                    "WebAssembly support is not enabled.");
7897    UNREACHABLE();
7898  #endif  // V8_ENABLE_WEBASSEMBLY
7899  }
7900  
WasmModuleObjectBuilderStreaming(Isolate * isolate)7901  WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7902      Isolate* isolate) {
7903    USE(isolate_);
7904  }
7905  
GetPromise()7906  Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7907  
OnBytesReceived(const uint8_t * bytes,size_t size)7908  void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7909                                                         size_t size) {}
7910  
Finish()7911  void WasmModuleObjectBuilderStreaming::Finish() {}
7912  
Abort(MaybeLocal<Value> exception)7913  void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7914  
Reallocate(void * data,size_t old_length,size_t new_length)7915  void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7916                                               size_t new_length) {
7917    if (old_length == new_length) return data;
7918    uint8_t* new_data =
7919        reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7920    if (new_data == nullptr) return nullptr;
7921    size_t bytes_to_copy = std::min(old_length, new_length);
7922    memcpy(new_data, data, bytes_to_copy);
7923    if (new_length > bytes_to_copy) {
7924      memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7925    }
7926    Free(data, old_length);
7927    return new_data;
7928  }
7929  
7930  // static
NewDefaultAllocator()7931  v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7932    return new ArrayBufferAllocator();
7933  }
7934  
IsDetachable() const7935  bool v8::ArrayBuffer::IsDetachable() const {
7936    return Utils::OpenHandle(this)->is_detachable();
7937  }
7938  
WasDetached() const7939  bool v8::ArrayBuffer::WasDetached() const {
7940    return Utils::OpenHandle(this)->was_detached();
7941  }
7942  
7943  namespace {
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7944  std::shared_ptr<i::BackingStore> ToInternal(
7945      std::shared_ptr<i::BackingStoreBase> backing_store) {
7946    return std::static_pointer_cast<i::BackingStore>(backing_store);
7947  }
7948  }  // namespace
7949  
Detach()7950  void v8::ArrayBuffer::Detach() {
7951    i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7952    i::Isolate* isolate = obj->GetIsolate();
7953    Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
7954                    "Only detachable ArrayBuffers can be detached");
7955    API_RCS_SCOPE(isolate, ArrayBuffer, Detach);
7956    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7957    obj->Detach();
7958  }
7959  
ByteLength() const7960  size_t v8::ArrayBuffer::ByteLength() const {
7961    i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7962    return obj->byte_length();
7963  }
7964  
New(Isolate * isolate,size_t byte_length)7965  Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7966    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7967    API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7968    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7969    i::MaybeHandle<i::JSArrayBuffer> result =
7970        i_isolate->factory()->NewJSArrayBufferAndBackingStore(
7971            byte_length, i::InitializedFlag::kZeroInitialized);
7972  
7973    i::Handle<i::JSArrayBuffer> array_buffer;
7974    if (!result.ToHandle(&array_buffer)) {
7975      // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7976      // version that throws an exception or otherwise does not crash.
7977      i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
7978    }
7979  
7980    return Utils::ToLocal(array_buffer);
7981  }
7982  
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7983  Local<ArrayBuffer> v8::ArrayBuffer::New(
7984      Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7985    CHECK_IMPLIES(backing_store->ByteLength() != 0,
7986                  backing_store->Data() != nullptr);
7987    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7988    API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7989    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7990    std::shared_ptr<i::BackingStore> i_backing_store(
7991        ToInternal(std::move(backing_store)));
7992    Utils::ApiCheck(
7993        !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
7994        "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
7995    i::Handle<i::JSArrayBuffer> obj =
7996        i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
7997    return Utils::ToLocal(obj);
7998  }
7999  
NewBackingStore(Isolate * isolate,size_t byte_length)8000  std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
8001      Isolate* isolate, size_t byte_length) {
8002    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8003    API_RCS_SCOPE(i_isolate, ArrayBuffer, NewBackingStore);
8004    CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8005    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8006    std::unique_ptr<i::BackingStoreBase> backing_store =
8007        i::BackingStore::Allocate(i_isolate, byte_length,
8008                                  i::SharedFlag::kNotShared,
8009                                  i::InitializedFlag::kZeroInitialized);
8010    if (!backing_store) {
8011      i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
8012    }
8013    return std::unique_ptr<v8::BackingStore>(
8014        static_cast<v8::BackingStore*>(backing_store.release()));
8015  }
8016  
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8017  std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
8018      void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8019      void* deleter_data) {
8020    CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8021    std::unique_ptr<i::BackingStoreBase> backing_store =
8022        i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8023                                        i::SharedFlag::kNotShared);
8024    return std::unique_ptr<v8::BackingStore>(
8025        static_cast<v8::BackingStore*>(backing_store.release()));
8026  }
8027  
Buffer()8028  Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
8029    i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8030    i::Handle<i::JSArrayBuffer> buffer;
8031    if (obj->IsJSDataView()) {
8032      i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
8033                                         obj->GetIsolate());
8034      DCHECK(data_view->buffer().IsJSArrayBuffer());
8035      buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
8036                         data_view->GetIsolate());
8037    } else {
8038      DCHECK(obj->IsJSTypedArray());
8039      buffer = i::JSTypedArray::cast(*obj).GetBuffer();
8040    }
8041    return Utils::ToLocal(buffer);
8042  }
8043  
CopyContents(void * dest,size_t byte_length)8044  size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
8045    i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8046    size_t bytes_to_copy = std::min(byte_length, self->byte_length());
8047    if (bytes_to_copy) {
8048      i::DisallowGarbageCollection no_gc;
8049      i::Isolate* isolate = self->GetIsolate();
8050      const char* source;
8051      if (self->IsJSTypedArray()) {
8052        i::Handle<i::JSTypedArray> array(i::JSTypedArray::cast(*self), isolate);
8053        source = reinterpret_cast<char*>(array->DataPtr());
8054      } else {
8055        DCHECK(self->IsJSDataView());
8056        i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*self), isolate);
8057        source = reinterpret_cast<char*>(data_view->data_pointer());
8058      }
8059      memcpy(dest, source, bytes_to_copy);
8060    }
8061    return bytes_to_copy;
8062  }
8063  
HasBuffer() const8064  bool v8::ArrayBufferView::HasBuffer() const {
8065    i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8066    if (!self->IsJSTypedArray()) return true;
8067    auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
8068    return !typed_array->is_on_heap();
8069  }
8070  
ByteOffset()8071  size_t v8::ArrayBufferView::ByteOffset() {
8072    i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8073    return obj->WasDetached() ? 0 : obj->byte_offset();
8074  }
8075  
ByteLength()8076  size_t v8::ArrayBufferView::ByteLength() {
8077    i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8078    return obj->WasDetached() ? 0 : obj->byte_length();
8079  }
8080  
Length()8081  size_t v8::TypedArray::Length() {
8082    i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8083    return obj->WasDetached() ? 0 : obj->length();
8084  }
8085  
8086  static_assert(
8087      v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
8088      "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
8089  
8090  #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype)                           \
8091    Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer,     \
8092                                        size_t byte_offset, size_t length) { \
8093      i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();  \
8094      API_RCS_SCOPE(isolate, Type##Array, New);                              \
8095      ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8096      if (!Utils::ApiCheck(length <= kMaxLength,                             \
8097                           "v8::" #Type                                      \
8098                           "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
8099                           "length exceeds max allowed value")) {            \
8100        return Local<Type##Array>();                                         \
8101      }                                                                      \
8102      i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
8103      i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8104          i::kExternal##Type##Array, buffer, byte_offset, length);           \
8105      return Utils::ToLocal##Type##Array(obj);                               \
8106    }                                                                        \
8107    Local<Type##Array> Type##Array::New(                                     \
8108        Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset,    \
8109        size_t length) {                                                     \
8110      CHECK(i::FLAG_harmony_sharedarraybuffer);                              \
8111      i::Isolate* isolate =                                                  \
8112          Utils::OpenHandle(*shared_array_buffer)->GetIsolate();             \
8113      API_RCS_SCOPE(isolate, Type##Array, New);                              \
8114      ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8115      if (!Utils::ApiCheck(                                                  \
8116              length <= kMaxLength,                                          \
8117              "v8::" #Type                                                   \
8118              "Array::New(Local<SharedArrayBuffer>, size_t, size_t)",        \
8119              "length exceeds max allowed value")) {                         \
8120        return Local<Type##Array>();                                         \
8121      }                                                                      \
8122      i::Handle<i::JSArrayBuffer> buffer =                                   \
8123          Utils::OpenHandle(*shared_array_buffer);                           \
8124      i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8125          i::kExternal##Type##Array, buffer, byte_offset, length);           \
8126      return Utils::ToLocal##Type##Array(obj);                               \
8127    }
8128  
TYPED_ARRAYS(TYPED_ARRAY_NEW)8129  TYPED_ARRAYS(TYPED_ARRAY_NEW)
8130  #undef TYPED_ARRAY_NEW
8131  
8132  Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
8133                                size_t byte_offset, size_t byte_length) {
8134    i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
8135    i::Isolate* isolate = buffer->GetIsolate();
8136    API_RCS_SCOPE(isolate, DataView, New);
8137    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8138    i::Handle<i::JSDataView> obj =
8139        isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8140    return Utils::ToLocal(obj);
8141  }
8142  
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)8143  Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
8144                                size_t byte_offset, size_t byte_length) {
8145    CHECK(i::FLAG_harmony_sharedarraybuffer);
8146    i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
8147    i::Isolate* isolate = buffer->GetIsolate();
8148    API_RCS_SCOPE(isolate, DataView, New);
8149    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8150    i::Handle<i::JSDataView> obj =
8151        isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8152    return Utils::ToLocal(obj);
8153  }
8154  
ByteLength() const8155  size_t v8::SharedArrayBuffer::ByteLength() const {
8156    i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8157    return obj->byte_length();
8158  }
8159  
New(Isolate * isolate,size_t byte_length)8160  Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
8161                                                      size_t byte_length) {
8162    CHECK(i::FLAG_harmony_sharedarraybuffer);
8163    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8164    API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8165    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8166  
8167    std::unique_ptr<i::BackingStore> backing_store =
8168        i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8169                                  i::InitializedFlag::kZeroInitialized);
8170  
8171    if (!backing_store) {
8172      // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8173      // version that throws an exception or otherwise does not crash.
8174      i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
8175    }
8176  
8177    i::Handle<i::JSArrayBuffer> obj =
8178        i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
8179    return Utils::ToLocalShared(obj);
8180  }
8181  
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8182  Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
8183      Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
8184    CHECK(i::FLAG_harmony_sharedarraybuffer);
8185    CHECK_IMPLIES(backing_store->ByteLength() != 0,
8186                  backing_store->Data() != nullptr);
8187    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8188    API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8189    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8190    std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
8191    Utils::ApiCheck(
8192        i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
8193        "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
8194    i::Handle<i::JSArrayBuffer> obj =
8195        i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
8196    return Utils::ToLocalShared(obj);
8197  }
8198  
NewBackingStore(Isolate * isolate,size_t byte_length)8199  std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8200      Isolate* isolate, size_t byte_length) {
8201    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8202    API_RCS_SCOPE(i_isolate, SharedArrayBuffer, NewBackingStore);
8203    CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8204    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8205    std::unique_ptr<i::BackingStoreBase> backing_store =
8206        i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8207                                  i::InitializedFlag::kZeroInitialized);
8208    if (!backing_store) {
8209      i::FatalProcessOutOfMemory(i_isolate,
8210                                 "v8::SharedArrayBuffer::NewBackingStore");
8211    }
8212    return std::unique_ptr<v8::BackingStore>(
8213        static_cast<v8::BackingStore*>(backing_store.release()));
8214  }
8215  
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8216  std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8217      void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8218      void* deleter_data) {
8219    CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8220    std::unique_ptr<i::BackingStoreBase> backing_store =
8221        i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8222                                        i::SharedFlag::kShared);
8223    return std::unique_ptr<v8::BackingStore>(
8224        static_cast<v8::BackingStore*>(backing_store.release()));
8225  }
8226  
New(Isolate * isolate,Local<String> name)8227  Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8228    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8229    API_RCS_SCOPE(i_isolate, Symbol, New);
8230    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8231    i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8232    if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8233    return Utils::ToLocal(result);
8234  }
8235  
For(Isolate * isolate,Local<String> name)8236  Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8237    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8238    i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8239    return Utils::ToLocal(
8240        i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8241  }
8242  
ForApi(Isolate * isolate,Local<String> name)8243  Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8244    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8245    i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8246    return Utils::ToLocal(
8247        i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8248  }
8249  
8250  #define WELL_KNOWN_SYMBOLS(V)                 \
8251    V(AsyncIterator, async_iterator)            \
8252    V(HasInstance, has_instance)                \
8253    V(IsConcatSpreadable, is_concat_spreadable) \
8254    V(Iterator, iterator)                       \
8255    V(Match, match)                             \
8256    V(Replace, replace)                         \
8257    V(Search, search)                           \
8258    V(Split, split)                             \
8259    V(ToPrimitive, to_primitive)                \
8260    V(ToStringTag, to_string_tag)               \
8261    V(Unscopables, unscopables)
8262  
8263  #define SYMBOL_GETTER(Name, name)                                   \
8264    Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) {           \
8265      i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8266      return Utils::ToLocal(i_isolate->factory()->name##_symbol());   \
8267    }
8268  
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8269  WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8270  
8271  #undef SYMBOL_GETTER
8272  #undef WELL_KNOWN_SYMBOLS
8273  
8274  Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8275    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8276    API_RCS_SCOPE(i_isolate, Private, New);
8277    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8278    i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8279    if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8280    Local<Symbol> result = Utils::ToLocal(symbol);
8281    return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8282  }
8283  
ForApi(Isolate * isolate,Local<String> name)8284  Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8285    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8286    i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8287    Local<Symbol> result = Utils::ToLocal(
8288        i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8289    return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8290  }
8291  
New(Isolate * isolate,double value)8292  Local<Number> v8::Number::New(Isolate* isolate, double value) {
8293    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8294    if (std::isnan(value)) {
8295      // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8296      value = std::numeric_limits<double>::quiet_NaN();
8297    }
8298    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8299    i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8300    return Utils::NumberToLocal(result);
8301  }
8302  
New(Isolate * isolate,int32_t value)8303  Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8304    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8305    if (i::Smi::IsValid(value)) {
8306      return Utils::IntegerToLocal(
8307          i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8308    }
8309    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8310    i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8311    return Utils::IntegerToLocal(result);
8312  }
8313  
NewFromUnsigned(Isolate * isolate,uint32_t value)8314  Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8315    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8316    bool fits_into_int32_t = (value & (1 << 31)) == 0;
8317    if (fits_into_int32_t) {
8318      return Integer::New(isolate, static_cast<int32_t>(value));
8319    }
8320    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8321    i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8322    return Utils::IntegerToLocal(result);
8323  }
8324  
New(Isolate * isolate,int64_t value)8325  Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8326    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8327    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8328    i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8329    return Utils::ToLocal(result);
8330  }
8331  
NewFromUnsigned(Isolate * isolate,uint64_t value)8332  Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8333    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8334    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8335    i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8336    return Utils::ToLocal(result);
8337  }
8338  
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8339  MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8340                                              int sign_bit, int word_count,
8341                                              const uint64_t* words) {
8342    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8343    ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8344                       MaybeLocal<BigInt>(), InternalEscapableScope);
8345    i::MaybeHandle<i::BigInt> result =
8346        i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8347    has_pending_exception = result.is_null();
8348    RETURN_ON_FAILED_EXECUTION(BigInt);
8349    RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8350  }
8351  
Uint64Value(bool * lossless) const8352  uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8353    i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8354    return handle->AsUint64(lossless);
8355  }
8356  
Int64Value(bool * lossless) const8357  int64_t v8::BigInt::Int64Value(bool* lossless) const {
8358    i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8359    return handle->AsInt64(lossless);
8360  }
8361  
WordCount() const8362  int BigInt::WordCount() const {
8363    i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8364    return handle->Words64Count();
8365  }
8366  
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8367  void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8368                            uint64_t* words) const {
8369    i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8370    return handle->ToWordsArray64(sign_bit, word_count, words);
8371  }
8372  
ReportExternalAllocationLimitReached()8373  void Isolate::ReportExternalAllocationLimitReached() {
8374    i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8375    if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8376    heap->ReportExternalMemoryPressure();
8377  }
8378  
GetHeapProfiler()8379  HeapProfiler* Isolate::GetHeapProfiler() {
8380    i::HeapProfiler* heap_profiler =
8381        reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8382    return reinterpret_cast<HeapProfiler*>(heap_profiler);
8383  }
8384  
SetIdle(bool is_idle)8385  void Isolate::SetIdle(bool is_idle) {
8386    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8387    isolate->SetIdle(is_idle);
8388  }
8389  
GetArrayBufferAllocator()8390  ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8391    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8392    return isolate->array_buffer_allocator();
8393  }
8394  
InContext()8395  bool Isolate::InContext() {
8396    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8397    return !isolate->context().is_null();
8398  }
8399  
ClearKeptObjects()8400  void Isolate::ClearKeptObjects() {
8401    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8402    isolate->ClearKeptObjects();
8403  }
8404  
GetCurrentContext()8405  v8::Local<v8::Context> Isolate::GetCurrentContext() {
8406    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8407    i::Context context = isolate->context();
8408    if (context.is_null()) return Local<Context>();
8409    i::Context native_context = context.native_context();
8410    if (native_context.is_null()) return Local<Context>();
8411    return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8412  }
8413  
GetEnteredOrMicrotaskContext()8414  v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8415    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8416    i::Handle<i::Object> last =
8417        isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8418    if (last.is_null()) return Local<Context>();
8419    DCHECK(last->IsNativeContext());
8420    return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8421  }
8422  
GetIncumbentContext()8423  v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8424    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8425    i::Handle<i::Context> context = isolate->GetIncumbentContext();
8426    return Utils::ToLocal(context);
8427  }
8428  
ThrowError(v8::Local<v8::String> message)8429  v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8430    return ThrowException(v8::Exception::Error(message));
8431  }
8432  
ThrowException(v8::Local<v8::Value> value)8433  v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8434    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8435    ENTER_V8_DO_NOT_USE(isolate);
8436    // If we're passed an empty handle, we throw an undefined exception
8437    // to deal more gracefully with out of memory situations.
8438    if (value.IsEmpty()) {
8439      isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8440    } else {
8441      isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8442    }
8443    return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8444  }
8445  
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8446  void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8447                                      GCType gc_type) {
8448    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8449    isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8450  }
8451  
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8452  void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8453                                         void* data) {
8454    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8455    isolate->heap()->RemoveGCPrologueCallback(callback, data);
8456  }
8457  
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8458  void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8459                                      GCType gc_type) {
8460    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8461    isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8462  }
8463  
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8464  void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8465                                         void* data) {
8466    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8467    isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8468  }
8469  
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8470  static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8471                                        GCCallbackFlags flags, void* data) {
8472    reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8473  }
8474  
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8475  void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8476    void* data = reinterpret_cast<void*>(callback);
8477    AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8478  }
8479  
RemoveGCPrologueCallback(GCCallback callback)8480  void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8481    void* data = reinterpret_cast<void*>(callback);
8482    RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8483  }
8484  
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8485  void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8486    void* data = reinterpret_cast<void*>(callback);
8487    AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8488  }
8489  
RemoveGCEpilogueCallback(GCCallback callback)8490  void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8491    void* data = reinterpret_cast<void*>(callback);
8492    RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8493  }
8494  
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8495  void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8496    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8497    CHECK_NULL(isolate->heap()->cpp_heap());
8498    isolate->heap()->SetEmbedderHeapTracer(tracer);
8499  }
8500  
GetEmbedderHeapTracer()8501  EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8502    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8503    return isolate->heap()->GetEmbedderHeapTracer();
8504  }
8505  
SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8506  void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8507    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8508    isolate->heap()->SetEmbedderRootsHandler(handler);
8509  }
8510  
AttachCppHeap(CppHeap * cpp_heap)8511  void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
8512    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8513    CHECK_NULL(GetEmbedderHeapTracer());
8514    isolate->heap()->AttachCppHeap(cpp_heap);
8515  }
8516  
DetachCppHeap()8517  void Isolate::DetachCppHeap() {
8518    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8519    isolate->heap()->DetachCppHeap();
8520  }
8521  
GetCppHeap() const8522  CppHeap* Isolate::GetCppHeap() const {
8523    const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8524    return isolate->heap()->cpp_heap();
8525  }
8526  
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8527  void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8528      GetExternallyAllocatedMemoryInBytesCallback callback) {
8529    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8530    isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8531  }
8532  
TerminateExecution()8533  void Isolate::TerminateExecution() {
8534    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8535    isolate->stack_guard()->RequestTerminateExecution();
8536  }
8537  
IsExecutionTerminating()8538  bool Isolate::IsExecutionTerminating() {
8539    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8540    return IsExecutionTerminatingCheck(isolate);
8541  }
8542  
CancelTerminateExecution()8543  void Isolate::CancelTerminateExecution() {
8544    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8545    isolate->stack_guard()->ClearTerminateExecution();
8546    isolate->CancelTerminateExecution();
8547  }
8548  
RequestInterrupt(InterruptCallback callback,void * data)8549  void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8550    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8551    isolate->RequestInterrupt(callback, data);
8552  }
8553  
HasPendingBackgroundTasks()8554  bool Isolate::HasPendingBackgroundTasks() {
8555  #if V8_ENABLE_WEBASSEMBLY
8556    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8557    return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate);
8558  #else
8559    return false;
8560  #endif  // V8_ENABLE_WEBASSEMBLY
8561  }
8562  
RequestGarbageCollectionForTesting(GarbageCollectionType type)8563  void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8564    Utils::ApiCheck(i::FLAG_expose_gc,
8565                    "v8::Isolate::RequestGarbageCollectionForTesting",
8566                    "Must use --expose-gc");
8567    if (type == kMinorGarbageCollection) {
8568      reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8569          i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8570          kGCCallbackFlagForced);
8571    } else {
8572      DCHECK_EQ(kFullGarbageCollection, type);
8573      reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8574          i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8575          kGCCallbackFlagForced);
8576    }
8577  }
8578  
RequestGarbageCollectionForTesting(GarbageCollectionType type,EmbedderHeapTracer::EmbedderStackState stack_state)8579  void Isolate::RequestGarbageCollectionForTesting(
8580      GarbageCollectionType type,
8581      EmbedderHeapTracer::EmbedderStackState stack_state) {
8582    base::Optional<i::EmbedderStackStateScope> stack_scope;
8583    if (type == kFullGarbageCollection) {
8584      stack_scope.emplace(reinterpret_cast<i::Isolate*>(this)->heap(),
8585                          i::EmbedderStackStateScope::kExplicitInvocation,
8586                          stack_state);
8587    }
8588    RequestGarbageCollectionForTesting(type);
8589  }
8590  
GetCurrent()8591  Isolate* Isolate::GetCurrent() {
8592    i::Isolate* isolate = i::Isolate::Current();
8593    return reinterpret_cast<Isolate*>(isolate);
8594  }
8595  
TryGetCurrent()8596  Isolate* Isolate::TryGetCurrent() {
8597    i::Isolate* isolate = i::Isolate::TryGetCurrent();
8598    return reinterpret_cast<Isolate*>(isolate);
8599  }
8600  
IsCurrent() const8601  bool Isolate::IsCurrent() const {
8602    return reinterpret_cast<const i::Isolate*>(this)->IsCurrent();
8603  }
8604  
8605  // static
Allocate()8606  Isolate* Isolate::Allocate() {
8607    return reinterpret_cast<Isolate*>(i::Isolate::New());
8608  }
8609  
8610  Isolate::CreateParams::CreateParams() = default;
8611  
8612  Isolate::CreateParams::~CreateParams() = default;
8613  
8614  // static
8615  // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8616  void Isolate::Initialize(Isolate* isolate,
8617                           const v8::Isolate::CreateParams& params) {
8618    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8619    TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.IsolateInitialize");
8620    if (auto allocator = params.array_buffer_allocator_shared) {
8621      CHECK(params.array_buffer_allocator == nullptr ||
8622            params.array_buffer_allocator == allocator.get());
8623      i_isolate->set_array_buffer_allocator(allocator.get());
8624      i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8625    } else {
8626      CHECK_NOT_NULL(params.array_buffer_allocator);
8627      i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8628    }
8629    if (params.snapshot_blob != nullptr) {
8630      i_isolate->set_snapshot_blob(params.snapshot_blob);
8631    } else {
8632      i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8633    }
8634  
8635    if (params.fatal_error_callback) {
8636      isolate->SetFatalErrorHandler(params.fatal_error_callback);
8637    }
8638  
8639    if (params.oom_error_callback) {
8640      isolate->SetOOMErrorHandler(params.oom_error_callback);
8641    }
8642  
8643    if (params.counter_lookup_callback) {
8644      isolate->SetCounterFunction(params.counter_lookup_callback);
8645    }
8646  
8647    if (params.create_histogram_callback) {
8648      isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8649    }
8650  
8651    if (params.add_histogram_sample_callback) {
8652      isolate->SetAddHistogramSampleFunction(
8653          params.add_histogram_sample_callback);
8654    }
8655  
8656    i_isolate->set_api_external_references(params.external_references);
8657    i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8658  
8659    i_isolate->heap()->ConfigureHeap(params.constraints);
8660    if (params.constraints.stack_limit() != nullptr) {
8661      uintptr_t limit =
8662          reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8663      i_isolate->stack_guard()->SetStackLimit(limit);
8664    }
8665  
8666    if (params.experimental_attach_to_shared_isolate != nullptr) {
8667      i_isolate->set_shared_isolate(reinterpret_cast<i::Isolate*>(
8668          params.experimental_attach_to_shared_isolate));
8669    }
8670  
8671    // TODO(v8:2487): Once we got rid of Isolate::Current(), we can remove this.
8672    Isolate::Scope isolate_scope(isolate);
8673    if (i_isolate->snapshot_blob() == nullptr) {
8674      FATAL(
8675          "V8 snapshot blob was not set during initialization. This can mean "
8676          "that the snapshot blob file is corrupted or missing.");
8677    }
8678    if (!i::Snapshot::Initialize(i_isolate)) {
8679      // If snapshot data was provided and we failed to deserialize it must
8680      // have been corrupted.
8681      FATAL(
8682          "Failed to deserialize the V8 snapshot blob. This can mean that the "
8683          "snapshot blob file is corrupted or missing.");
8684    }
8685  
8686    {
8687      // Set up code event handlers. Needs to be after i::Snapshot::Initialize
8688      // because that is where we add the isolate to WasmEngine.
8689      auto code_event_handler = params.code_event_handler;
8690      if (code_event_handler) {
8691        isolate->SetJitCodeEventHandler(kJitCodeEventEnumExisting,
8692                                        code_event_handler);
8693      }
8694    }
8695  
8696    i_isolate->set_only_terminate_in_safe_scope(
8697        params.only_terminate_in_safe_scope);
8698    i_isolate->set_embedder_wrapper_type_index(
8699        params.embedder_wrapper_type_index);
8700    i_isolate->set_embedder_wrapper_object_index(
8701        params.embedder_wrapper_object_index);
8702  
8703    if (!i::V8::GetCurrentPlatform()
8704             ->GetForegroundTaskRunner(isolate)
8705             ->NonNestableTasksEnabled()) {
8706      FATAL(
8707          "The current platform's foreground task runner does not have "
8708          "non-nestable tasks enabled. The embedder must provide one.");
8709    }
8710  }
8711  
New(const Isolate::CreateParams & params)8712  Isolate* Isolate::New(const Isolate::CreateParams& params) {
8713    Isolate* isolate = Allocate();
8714    Initialize(isolate, params);
8715    return isolate;
8716  }
8717  
Dispose()8718  void Isolate::Dispose() {
8719    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8720    if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8721                         "Disposing the isolate that is entered by a thread.")) {
8722      return;
8723    }
8724    i::Isolate::Delete(isolate);
8725  }
8726  
DumpAndResetStats()8727  void Isolate::DumpAndResetStats() {
8728    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8729    isolate->DumpAndResetStats();
8730  }
8731  
DiscardThreadSpecificMetadata()8732  void Isolate::DiscardThreadSpecificMetadata() {
8733    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8734    isolate->DiscardPerThreadDataForThisThread();
8735  }
8736  
Enter()8737  void Isolate::Enter() {
8738    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8739    isolate->Enter();
8740  }
8741  
Exit()8742  void Isolate::Exit() {
8743    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8744    isolate->Exit();
8745  }
8746  
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8747  void Isolate::SetAbortOnUncaughtExceptionCallback(
8748      AbortOnUncaughtExceptionCallback callback) {
8749    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8750    isolate->SetAbortOnUncaughtExceptionCallback(callback);
8751  }
8752  
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8753  void Isolate::SetHostImportModuleDynamicallyCallback(
8754      HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8755    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8756    isolate->SetHostImportModuleDynamicallyCallback(callback);
8757  }
8758  
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8759  void Isolate::SetHostImportModuleDynamicallyCallback(
8760      HostImportModuleDynamicallyCallback callback) {
8761    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8762    isolate->SetHostImportModuleDynamicallyCallback(callback);
8763  }
8764  
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8765  void Isolate::SetHostInitializeImportMetaObjectCallback(
8766      HostInitializeImportMetaObjectCallback callback) {
8767    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8768    isolate->SetHostInitializeImportMetaObjectCallback(callback);
8769  }
8770  
SetHostCreateShadowRealmContextCallback(HostCreateShadowRealmContextCallback callback)8771  void Isolate::SetHostCreateShadowRealmContextCallback(
8772      HostCreateShadowRealmContextCallback callback) {
8773    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8774    isolate->SetHostCreateShadowRealmContextCallback(callback);
8775  }
8776  
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8777  void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8778    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8779    isolate->SetPrepareStackTraceCallback(callback);
8780  }
8781  
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8782  Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8783      Isolate* isolate,
8784      Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8785      : on_failure_(on_failure), isolate_(isolate) {
8786    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8787    switch (on_failure_) {
8788      case CRASH_ON_FAILURE:
8789        i::DisallowJavascriptExecution::Open(i_isolate,
8790                                             &was_execution_allowed_assert_);
8791        break;
8792      case THROW_ON_FAILURE:
8793        i::ThrowOnJavascriptExecution::Open(i_isolate,
8794                                            &was_execution_allowed_throws_);
8795        break;
8796      case DUMP_ON_FAILURE:
8797        i::DumpOnJavascriptExecution::Open(i_isolate,
8798                                           &was_execution_allowed_dump_);
8799        break;
8800      default:
8801        UNREACHABLE();
8802    }
8803  }
8804  
~DisallowJavascriptExecutionScope()8805  Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8806    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8807    switch (on_failure_) {
8808      case CRASH_ON_FAILURE:
8809        i::DisallowJavascriptExecution::Close(i_isolate,
8810                                              was_execution_allowed_assert_);
8811        break;
8812      case THROW_ON_FAILURE:
8813        i::ThrowOnJavascriptExecution::Close(i_isolate,
8814                                             was_execution_allowed_throws_);
8815        break;
8816      case DUMP_ON_FAILURE:
8817        i::DumpOnJavascriptExecution::Close(i_isolate,
8818                                            was_execution_allowed_dump_);
8819        break;
8820      default:
8821        UNREACHABLE();
8822    }
8823  }
8824  
AllowJavascriptExecutionScope(Isolate * isolate)8825  Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8826      Isolate* isolate)
8827      : isolate_(isolate) {
8828    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8829    i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_);
8830    i::NoThrowOnJavascriptExecution::Open(i_isolate,
8831                                          &was_execution_allowed_throws_);
8832    i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_);
8833  }
8834  
~AllowJavascriptExecutionScope()8835  Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8836    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8837    i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_);
8838    i::NoThrowOnJavascriptExecution::Close(i_isolate,
8839                                           was_execution_allowed_throws_);
8840    i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_);
8841  }
8842  
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8843  Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8844      Isolate* isolate, MicrotaskQueue* microtask_queue)
8845      : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8846        microtask_queue_(microtask_queue
8847                             ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8848                             : isolate_->default_microtask_queue()) {
8849    isolate_->thread_local_top()->IncrementCallDepth(this);
8850    microtask_queue_->IncrementMicrotasksSuppressions();
8851  }
8852  
~SuppressMicrotaskExecutionScope()8853  Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8854    microtask_queue_->DecrementMicrotasksSuppressions();
8855    isolate_->thread_local_top()->DecrementCallDepth(this);
8856  }
8857  
SafeForTerminationScope(v8::Isolate * isolate)8858  Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8859      : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8860        prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8861    isolate_->set_next_v8_call_is_safe_for_termination(true);
8862  }
8863  
~SafeForTerminationScope()8864  Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8865    isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8866  }
8867  
GetDataFromSnapshotOnce(size_t index)8868  i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8869    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8870    i::FixedArray list = i_isolate->heap()->serialized_objects();
8871    return GetSerializedDataFromFixedArray(i_isolate, list, index);
8872  }
8873  
GetHeapStatistics(HeapStatistics * heap_statistics)8874  void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8875    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8876    i::Heap* heap = isolate->heap();
8877  
8878    // The order of acquiring memory statistics is important here. We query in
8879    // this order because of concurrent allocation: 1) used memory 2) comitted
8880    // physical memory 3) committed memory. Therefore the condition used <=
8881    // committed physical <= committed should hold.
8882    heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8883    heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8884    DCHECK_LE(heap_statistics->used_global_handles_size_,
8885              heap_statistics->total_global_handles_size_);
8886  
8887    heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8888    heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8889    heap_statistics->total_heap_size_ = heap->CommittedMemory();
8890  
8891    heap_statistics->total_available_size_ = heap->Available();
8892  
8893    if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8894      i::ReadOnlySpace* ro_space = heap->read_only_space();
8895      heap_statistics->used_heap_size_ += ro_space->Size();
8896      heap_statistics->total_physical_size_ +=
8897          ro_space->CommittedPhysicalMemory();
8898      heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8899    }
8900  
8901    // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8902    // this and add DCHECK.
8903    DCHECK_LE(heap_statistics->used_heap_size_,
8904              heap_statistics->total_heap_size_);
8905  
8906    heap_statistics->total_heap_size_executable_ =
8907        heap->CommittedMemoryExecutable();
8908    heap_statistics->heap_size_limit_ = heap->MaxReserved();
8909    // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8910    // API becomes available we should report the malloced memory separately. For
8911    // now we just add the values, thereby over-approximating the peak slightly.
8912    heap_statistics->malloced_memory_ =
8913        isolate->allocator()->GetCurrentMemoryUsage() +
8914        isolate->string_table()->GetCurrentMemoryUsage();
8915    // On 32-bit systems backing_store_bytes() might overflow size_t temporarily
8916    // due to concurrent array buffer sweeping.
8917    heap_statistics->external_memory_ =
8918        isolate->heap()->backing_store_bytes() < SIZE_MAX
8919            ? static_cast<size_t>(isolate->heap()->backing_store_bytes())
8920            : SIZE_MAX;
8921    heap_statistics->peak_malloced_memory_ =
8922        isolate->allocator()->GetMaxMemoryUsage();
8923    heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8924    heap_statistics->number_of_detached_contexts_ =
8925        heap->NumberOfDetachedContexts();
8926    heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8927  
8928  #if V8_ENABLE_WEBASSEMBLY
8929    heap_statistics->malloced_memory_ +=
8930        i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage();
8931    heap_statistics->peak_malloced_memory_ +=
8932        i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage();
8933  #endif  // V8_ENABLE_WEBASSEMBLY
8934  }
8935  
NumberOfHeapSpaces()8936  size_t Isolate::NumberOfHeapSpaces() {
8937    return i::LAST_SPACE - i::FIRST_SPACE + 1;
8938  }
8939  
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8940  bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8941                                       size_t index) {
8942    if (!space_statistics) return false;
8943    if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8944      return false;
8945  
8946    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8947    i::Heap* heap = isolate->heap();
8948  
8949    i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
8950    space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
8951  
8952    if (allocation_space == i::RO_SPACE) {
8953      if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8954        // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
8955        space_statistics->space_size_ = 0;
8956        space_statistics->space_used_size_ = 0;
8957        space_statistics->space_available_size_ = 0;
8958        space_statistics->physical_space_size_ = 0;
8959      } else {
8960        i::ReadOnlySpace* space = heap->read_only_space();
8961        space_statistics->space_size_ = space->CommittedMemory();
8962        space_statistics->space_used_size_ = space->Size();
8963        space_statistics->space_available_size_ = 0;
8964        space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8965      }
8966    } else {
8967      i::Space* space = heap->space(static_cast<int>(index));
8968      space_statistics->space_size_ = space ? space->CommittedMemory() : 0;
8969      space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0;
8970      space_statistics->space_available_size_ = space ? space->Available() : 0;
8971      space_statistics->physical_space_size_ =
8972          space ? space->CommittedPhysicalMemory() : 0;
8973    }
8974    return true;
8975  }
8976  
NumberOfTrackedHeapObjectTypes()8977  size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8978    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8979    i::Heap* heap = isolate->heap();
8980    return heap->NumberOfTrackedHeapObjectTypes();
8981  }
8982  
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8983  bool Isolate::GetHeapObjectStatisticsAtLastGC(
8984      HeapObjectStatistics* object_statistics, size_t type_index) {
8985    if (!object_statistics) return false;
8986    if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
8987  
8988    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8989    i::Heap* heap = isolate->heap();
8990    if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8991  
8992    const char* object_type;
8993    const char* object_sub_type;
8994    size_t object_count = heap->ObjectCountAtLastGC(type_index);
8995    size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8996    if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8997      // There should be no objects counted when the type is unknown.
8998      DCHECK_EQ(object_count, 0U);
8999      DCHECK_EQ(object_size, 0U);
9000      return false;
9001    }
9002  
9003    object_statistics->object_type_ = object_type;
9004    object_statistics->object_sub_type_ = object_sub_type;
9005    object_statistics->object_count_ = object_count;
9006    object_statistics->object_size_ = object_size;
9007    return true;
9008  }
9009  
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)9010  bool Isolate::GetHeapCodeAndMetadataStatistics(
9011      HeapCodeStatistics* code_statistics) {
9012    if (!code_statistics) return false;
9013  
9014    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9015    isolate->heap()->CollectCodeStatistics();
9016  
9017    code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
9018    code_statistics->bytecode_and_metadata_size_ =
9019        isolate->bytecode_and_metadata_size();
9020    code_statistics->external_script_source_size_ =
9021        isolate->external_script_source_size();
9022    code_statistics->cpu_profiler_metadata_size_ =
9023        i::CpuProfiler::GetAllProfilersMemorySize(
9024            reinterpret_cast<i::Isolate*>(isolate));
9025  
9026    return true;
9027  }
9028  
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)9029  bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
9030                              MeasureMemoryExecution execution) {
9031    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9032    return isolate->heap()->MeasureMemory(std::move(delegate), execution);
9033  }
9034  
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)9035  std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
9036      Isolate* isolate, Local<Context> context,
9037      Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
9038    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9039    i::Handle<i::NativeContext> native_context =
9040        handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
9041    i::Handle<i::JSPromise> js_promise =
9042        i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
9043    return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
9044                                                    mode);
9045  }
9046  
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)9047  void Isolate::GetStackSample(const RegisterState& state, void** frames,
9048                               size_t frames_limit, SampleInfo* sample_info) {
9049    RegisterState regs = state;
9050    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9051    if (i::TickSample::GetStackSample(isolate, &regs,
9052                                      i::TickSample::kSkipCEntryFrame, frames,
9053                                      frames_limit, sample_info)) {
9054      return;
9055    }
9056    sample_info->frames_count = 0;
9057    sample_info->vm_state = OTHER;
9058    sample_info->external_callback_entry = nullptr;
9059  }
9060  
NumberOfPhantomHandleResetsSinceLastCall()9061  size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
9062    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9063    return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
9064  }
9065  
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)9066  int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
9067      int64_t change_in_bytes) {
9068    // Try to check for unreasonably large or small values from the embedder.
9069    const int64_t kMaxReasonableBytes = int64_t(1) << 60;
9070    const int64_t kMinReasonableBytes = -kMaxReasonableBytes;
9071    STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength);
9072  
9073    CHECK(kMinReasonableBytes <= change_in_bytes &&
9074          change_in_bytes < kMaxReasonableBytes);
9075  
9076    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9077    int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
9078  
9079    if (change_in_bytes <= 0) return amount;
9080  
9081    if (amount > i_isolate->heap()->external_memory_limit()) {
9082      ReportExternalAllocationLimitReached();
9083    }
9084    return amount;
9085  }
9086  
SetEventLogger(LogEventCallback that)9087  void Isolate::SetEventLogger(LogEventCallback that) {
9088    // Do not overwrite the event logger if we want to log explicitly.
9089    if (i::FLAG_log_internal_timer_events) return;
9090    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9091    isolate->set_event_logger(that);
9092  }
9093  
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9094  void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
9095    if (callback == nullptr) return;
9096    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9097    isolate->AddBeforeCallEnteredCallback(callback);
9098  }
9099  
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9100  void Isolate::RemoveBeforeCallEnteredCallback(
9101      BeforeCallEnteredCallback callback) {
9102    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9103    isolate->RemoveBeforeCallEnteredCallback(callback);
9104  }
9105  
AddCallCompletedCallback(CallCompletedCallback callback)9106  void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
9107    if (callback == nullptr) return;
9108    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9109    isolate->AddCallCompletedCallback(callback);
9110  }
9111  
RemoveCallCompletedCallback(CallCompletedCallback callback)9112  void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
9113    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9114    isolate->RemoveCallCompletedCallback(callback);
9115  }
9116  
Wake()9117  void Isolate::AtomicsWaitWakeHandle::Wake() {
9118    reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
9119  }
9120  
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)9121  void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
9122    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9123    isolate->SetAtomicsWaitCallback(callback, data);
9124  }
9125  
SetPromiseHook(PromiseHook hook)9126  void Isolate::SetPromiseHook(PromiseHook hook) {
9127    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9128    isolate->SetPromiseHook(hook);
9129  }
9130  
SetPromiseRejectCallback(PromiseRejectCallback callback)9131  void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
9132    if (callback == nullptr) return;
9133    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9134    isolate->SetPromiseRejectCallback(callback);
9135  }
9136  
PerformMicrotaskCheckpoint()9137  void Isolate::PerformMicrotaskCheckpoint() {
9138    DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
9139    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9140    isolate->default_microtask_queue()->PerformCheckpoint(this);
9141  }
9142  
EnqueueMicrotask(Local<Function> v8_function)9143  void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
9144    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9145    i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
9146    i::Handle<i::NativeContext> handler_context;
9147    if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
9148            &handler_context))
9149      handler_context = isolate->native_context();
9150    MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
9151    if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
9152  }
9153  
EnqueueMicrotask(MicrotaskCallback callback,void * data)9154  void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
9155    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9156    isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
9157  }
9158  
SetMicrotasksPolicy(MicrotasksPolicy policy)9159  void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9160    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9161    isolate->default_microtask_queue()->set_microtasks_policy(policy);
9162  }
9163  
GetMicrotasksPolicy() const9164  MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
9165    i::Isolate* isolate =
9166        reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
9167    return isolate->default_microtask_queue()->microtasks_policy();
9168  }
9169  
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9170  void Isolate::AddMicrotasksCompletedCallback(
9171      MicrotasksCompletedCallbackWithData callback, void* data) {
9172    DCHECK(callback);
9173    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9174    isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
9175                                                                       data);
9176  }
9177  
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9178  void Isolate::RemoveMicrotasksCompletedCallback(
9179      MicrotasksCompletedCallbackWithData callback, void* data) {
9180    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9181    isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
9182        callback, data);
9183  }
9184  
SetUseCounterCallback(UseCounterCallback callback)9185  void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9186    reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9187  }
9188  
SetCounterFunction(CounterLookupCallback callback)9189  void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9190    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9191    isolate->counters()->ResetCounterFunction(callback);
9192  }
9193  
SetCreateHistogramFunction(CreateHistogramCallback callback)9194  void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9195    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9196    isolate->counters()->ResetCreateHistogramFunction(callback);
9197  }
9198  
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)9199  void Isolate::SetAddHistogramSampleFunction(
9200      AddHistogramSampleCallback callback) {
9201    reinterpret_cast<i::Isolate*>(this)
9202        ->counters()
9203        ->SetAddHistogramSampleFunction(callback);
9204  }
9205  
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)9206  void Isolate::SetMetricsRecorder(
9207      const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
9208    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9209    isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder);
9210  }
9211  
SetAddCrashKeyCallback(AddCrashKeyCallback callback)9212  void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
9213    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9214    isolate->SetAddCrashKeyCallback(callback);
9215  }
9216  
IdleNotificationDeadline(double deadline_in_seconds)9217  bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
9218    // Returning true tells the caller that it need not
9219    // continue to call IdleNotification.
9220    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9221    if (!i::FLAG_use_idle_notification) return true;
9222    return isolate->heap()->IdleNotification(deadline_in_seconds);
9223  }
9224  
LowMemoryNotification()9225  void Isolate::LowMemoryNotification() {
9226    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9227    {
9228      i::NestedTimedHistogramScope idle_notification_scope(
9229          isolate->counters()->gc_low_memory_notification());
9230      TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9231      isolate->heap()->CollectAllAvailableGarbage(
9232          i::GarbageCollectionReason::kLowMemoryNotification);
9233    }
9234  }
9235  
ContextDisposedNotification(bool dependant_context)9236  int Isolate::ContextDisposedNotification(bool dependant_context) {
9237    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9238  #if V8_ENABLE_WEBASSEMBLY
9239    if (!dependant_context) {
9240      if (!isolate->context().is_null()) {
9241        // We left the current context, we can abort all WebAssembly compilations
9242        // of that context.
9243        // A handle scope for the native context.
9244        i::HandleScope handle_scope(isolate);
9245        i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext(
9246            isolate->native_context());
9247      }
9248    }
9249  #endif  // V8_ENABLE_WEBASSEMBLY
9250    // TODO(ahaas): move other non-heap activity out of the heap call.
9251    return isolate->heap()->NotifyContextDisposed(dependant_context);
9252  }
9253  
IsolateInForegroundNotification()9254  void Isolate::IsolateInForegroundNotification() {
9255    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9256    return isolate->IsolateInForegroundNotification();
9257  }
9258  
IsolateInBackgroundNotification()9259  void Isolate::IsolateInBackgroundNotification() {
9260    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9261    return isolate->IsolateInBackgroundNotification();
9262  }
9263  
MemoryPressureNotification(MemoryPressureLevel level)9264  void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9265    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9266    bool on_isolate_thread =
9267        isolate->was_locker_ever_used()
9268            ? isolate->thread_manager()->IsLockedByCurrentThread()
9269            : i::ThreadId::Current() == isolate->thread_id();
9270    isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9271  }
9272  
ClearCachesForTesting()9273  void Isolate::ClearCachesForTesting() {
9274    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9275    isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9276    isolate->ClearSerializerData();
9277  }
9278  
EnableMemorySavingsMode()9279  void Isolate::EnableMemorySavingsMode() {
9280    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9281    isolate->EnableMemorySavingsMode();
9282  }
9283  
DisableMemorySavingsMode()9284  void Isolate::DisableMemorySavingsMode() {
9285    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9286    isolate->DisableMemorySavingsMode();
9287  }
9288  
SetRAILMode(RAILMode rail_mode)9289  void Isolate::SetRAILMode(RAILMode rail_mode) {
9290    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9291    return isolate->SetRAILMode(rail_mode);
9292  }
9293  
UpdateLoadStartTime()9294  void Isolate::UpdateLoadStartTime() {
9295    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9296    isolate->UpdateLoadStartTime();
9297  }
9298  
IncreaseHeapLimitForDebugging()9299  void Isolate::IncreaseHeapLimitForDebugging() {
9300    // No-op.
9301  }
9302  
RestoreOriginalHeapLimit()9303  void Isolate::RestoreOriginalHeapLimit() {
9304    // No-op.
9305  }
9306  
IsHeapLimitIncreasedForDebugging()9307  bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9308  
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9309  void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9310                                       JitCodeEventHandler event_handler) {
9311    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9312    // Ensure that logging is initialized for our isolate.
9313    isolate->InitializeLoggingAndCounters();
9314    isolate->logger()->SetCodeEventHandler(options, event_handler);
9315  }
9316  
SetStackLimit(uintptr_t stack_limit)9317  void Isolate::SetStackLimit(uintptr_t stack_limit) {
9318    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9319    CHECK(stack_limit);
9320    isolate->stack_guard()->SetStackLimit(stack_limit);
9321  }
9322  
GetCodeRange(void ** start,size_t * length_in_bytes)9323  void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9324    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9325    const base::AddressRegion& code_region = isolate->heap()->code_region();
9326    *start = reinterpret_cast<void*>(code_region.begin());
9327    *length_in_bytes = code_region.size();
9328  }
9329  
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9330  void Isolate::GetEmbeddedCodeRange(const void** start,
9331                                     size_t* length_in_bytes) {
9332    // Note, we should return the embedded code rande from the .text section here.
9333    i::EmbeddedData d = i::EmbeddedData::FromBlob();
9334    *start = reinterpret_cast<const void*>(d.code());
9335    *length_in_bytes = d.code_size();
9336  }
9337  
GetJSEntryStubs()9338  JSEntryStubs Isolate::GetJSEntryStubs() {
9339    JSEntryStubs entry_stubs;
9340  
9341    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9342    std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = {
9343        {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub},
9344         {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9345         {i::Builtin::kJSRunMicrotasksEntry,
9346          &entry_stubs.js_run_microtasks_entry_stub}}};
9347    for (auto& pair : stubs) {
9348      i::Code js_entry = FromCodeT(isolate->builtins()->code(pair.first));
9349      pair.second->code.start =
9350          reinterpret_cast<const void*>(js_entry.InstructionStart());
9351      pair.second->code.length_in_bytes = js_entry.InstructionSize();
9352    }
9353  
9354    return entry_stubs;
9355  }
9356  
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9357  size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9358  #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9359    // Not implemented on other platforms.
9360    UNREACHABLE();
9361  #else
9362  
9363    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9364    std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9365  
9366    DCHECK_NOT_NULL(code_pages);
9367  
9368    // Copy as many elements into the output vector as we can. If the
9369    // caller-provided buffer is not big enough, we fill it, and the caller can
9370    // provide a bigger one next time. We do it this way because allocation is not
9371    // allowed in signal handlers.
9372    size_t limit = std::min(capacity, code_pages->size());
9373    for (size_t i = 0; i < limit; i++) {
9374      code_pages_out[i] = code_pages->at(i);
9375    }
9376    return code_pages->size();
9377  #endif
9378  }
9379  
9380  #define CALLBACK_SETTER(ExternalName, Type, InternalName)      \
9381    void Isolate::Set##ExternalName(Type callback) {             \
9382      i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9383      isolate->set_##InternalName(callback);                     \
9384    }
9385  
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9386  CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9387  CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9388  CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9389                  ModifyCodeGenerationFromStringsCallback2,
9390                  modify_code_gen_callback2)
9391  CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9392                  AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9393  
9394  CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9395  CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9396  
9397  CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9398                  wasm_streaming_callback)
9399  
9400  CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9401                  wasm_load_source_map_callback)
9402  
9403  CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9404                  wasm_simd_enabled_callback)
9405  
9406  CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9407                  wasm_exceptions_enabled_callback)
9408  
9409  CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9410                  WasmDynamicTieringEnabledCallback,
9411                  wasm_dynamic_tiering_enabled_callback)
9412  
9413  CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9414                  SharedArrayBufferConstructorEnabledCallback,
9415                  sharedarraybuffer_constructor_enabled_callback)
9416  
9417  void Isolate::InstallConditionalFeatures(Local<Context> context) {
9418    v8::HandleScope handle_scope(this);
9419    v8::Context::Scope context_scope(context);
9420    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9421    isolate->InstallConditionalFeatures(Utils::OpenHandle(*context));
9422  #if V8_ENABLE_WEBASSEMBLY
9423    if (i::FLAG_expose_wasm) {
9424      i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context));
9425    }
9426  #endif  // V8_ENABLE_WEBASSEMBLY
9427  }
9428  
AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9429  void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9430                                         void* data) {
9431    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9432    isolate->heap()->AddNearHeapLimitCallback(callback, data);
9433  }
9434  
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9435  void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9436                                            size_t heap_limit) {
9437    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9438    isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9439  }
9440  
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9441  void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9442    DCHECK_GT(threshold_percent, 0.0);
9443    DCHECK_LT(threshold_percent, 1.0);
9444    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9445    isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9446  }
9447  
IsDead()9448  bool Isolate::IsDead() {
9449    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9450    return isolate->IsDead();
9451  }
9452  
AddMessageListener(MessageCallback that,Local<Value> data)9453  bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9454    return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9455  }
9456  
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9457  bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9458                                                 int message_levels,
9459                                                 Local<Value> data) {
9460    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9461    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9462    i::HandleScope scope(isolate);
9463    i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9464    i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9465    i::Handle<i::Foreign> foreign =
9466        isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9467    listener->set(0, *foreign);
9468    listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9469                                    : *Utils::OpenHandle(*data));
9470    listener->set(2, i::Smi::FromInt(message_levels));
9471    list = i::TemplateList::Add(isolate, list, listener);
9472    isolate->heap()->SetMessageListeners(*list);
9473    return true;
9474  }
9475  
RemoveMessageListeners(MessageCallback that)9476  void Isolate::RemoveMessageListeners(MessageCallback that) {
9477    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9478    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9479    i::HandleScope scope(isolate);
9480    i::DisallowGarbageCollection no_gc;
9481    i::TemplateList listeners = isolate->heap()->message_listeners();
9482    for (int i = 0; i < listeners.length(); i++) {
9483      if (listeners.get(i).IsUndefined(isolate)) continue;  // skip deleted ones
9484      i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9485      i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9486      if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9487        listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9488      }
9489    }
9490  }
9491  
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9492  void Isolate::SetFailedAccessCheckCallbackFunction(
9493      FailedAccessCheckCallback callback) {
9494    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9495    isolate->SetFailedAccessCheckCallback(callback);
9496  }
9497  
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9498  void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9499      bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9500    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9501    isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9502                                                       options);
9503  }
9504  
VisitExternalResources(ExternalResourceVisitor * visitor)9505  void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9506    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9507    isolate->heap()->VisitExternalResources(visitor);
9508  }
9509  
IsInUse()9510  bool Isolate::IsInUse() {
9511    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9512    return isolate->IsInUse();
9513  }
9514  
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9515  void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9516    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9517    i::DisallowGarbageCollection no_gc;
9518    isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9519  }
9520  
VisitWeakHandles(PersistentHandleVisitor * visitor)9521  void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9522    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9523    i::DisallowGarbageCollection no_gc;
9524    isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9525  }
9526  
SetAllowAtomicsWait(bool allow)9527  void Isolate::SetAllowAtomicsWait(bool allow) {
9528    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9529    isolate->set_allow_atomics_wait(allow);
9530  }
9531  
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9532  void v8::Isolate::DateTimeConfigurationChangeNotification(
9533      TimeZoneDetection time_zone_detection) {
9534    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9535    API_RCS_SCOPE(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9536    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9537    i_isolate->date_cache()->ResetDateCache(
9538        static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9539  #ifdef V8_INTL_SUPPORT
9540    i_isolate->clear_cached_icu_object(
9541        i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9542    i_isolate->clear_cached_icu_object(
9543        i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9544    i_isolate->clear_cached_icu_object(
9545        i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9546  #endif  // V8_INTL_SUPPORT
9547  }
9548  
LocaleConfigurationChangeNotification()9549  void v8::Isolate::LocaleConfigurationChangeNotification() {
9550    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9551    API_RCS_SCOPE(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9552    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9553  
9554  #ifdef V8_INTL_SUPPORT
9555    i_isolate->ResetDefaultLocale();
9556  #endif  // V8_INTL_SUPPORT
9557  }
9558  
IsCodeLike(v8::Isolate * isolate) const9559  bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
9560    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9561    API_RCS_SCOPE(i_isolate, Object, IsCodeLike);
9562    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9563    i::HandleScope scope(i_isolate);
9564    return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9565  }
9566  
9567  // static
New(Isolate * isolate,MicrotasksPolicy policy)9568  std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9569                                                      MicrotasksPolicy policy) {
9570    auto microtask_queue =
9571        i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9572    microtask_queue->set_microtasks_policy(policy);
9573    std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9574    return ret;
9575  }
9576  
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9577  MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9578      : MicrotasksScope(isolate, nullptr, type) {}
9579  
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9580  MicrotasksScope::MicrotasksScope(Isolate* isolate,
9581                                   MicrotaskQueue* microtask_queue,
9582                                   MicrotasksScope::Type type)
9583      : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9584        microtask_queue_(microtask_queue
9585                             ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9586                             : isolate_->default_microtask_queue()),
9587        run_(type == MicrotasksScope::kRunMicrotasks) {
9588    if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9589  #ifdef DEBUG
9590    if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9591  #endif
9592  }
9593  
~MicrotasksScope()9594  MicrotasksScope::~MicrotasksScope() {
9595    if (run_) {
9596      microtask_queue_->DecrementMicrotasksScopeDepth();
9597      if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9598          !isolate_->has_scheduled_exception()) {
9599        DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9600                       isolate_->scheduled_exception() ==
9601                           i::ReadOnlyRoots(isolate_).termination_exception());
9602        microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9603      }
9604    }
9605  #ifdef DEBUG
9606    if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9607  #endif
9608  }
9609  
9610  // static
PerformCheckpoint(Isolate * v8_isolate)9611  void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9612    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9613    auto* microtask_queue = isolate->default_microtask_queue();
9614    microtask_queue->PerformCheckpoint(v8_isolate);
9615  }
9616  
9617  // static
GetCurrentDepth(Isolate * v8_isolate)9618  int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9619    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9620    auto* microtask_queue = isolate->default_microtask_queue();
9621    return microtask_queue->GetMicrotasksScopeDepth();
9622  }
9623  
9624  // static
IsRunningMicrotasks(Isolate * v8_isolate)9625  bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9626    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9627    auto* microtask_queue = isolate->default_microtask_queue();
9628    return microtask_queue->IsRunningMicrotasks();
9629  }
9630  
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9631  String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9632      : str_(nullptr), length_(0) {
9633    if (obj.IsEmpty()) return;
9634    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9635    ENTER_V8_DO_NOT_USE(i_isolate);
9636    i::HandleScope scope(i_isolate);
9637    Local<Context> context = isolate->GetCurrentContext();
9638    TryCatch try_catch(isolate);
9639    Local<String> str;
9640    if (!obj->ToString(context).ToLocal(&str)) return;
9641    length_ = str->Utf8Length(isolate);
9642    str_ = i::NewArray<char>(length_ + 1);
9643    str->WriteUtf8(isolate, str_);
9644  }
9645  
~Utf8Value()9646  String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9647  
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9648  String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9649      : str_(nullptr), length_(0) {
9650    if (obj.IsEmpty()) return;
9651    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9652    ENTER_V8_DO_NOT_USE(i_isolate);
9653    i::HandleScope scope(i_isolate);
9654    Local<Context> context = isolate->GetCurrentContext();
9655    TryCatch try_catch(isolate);
9656    Local<String> str;
9657    if (!obj->ToString(context).ToLocal(&str)) return;
9658    length_ = str->Length();
9659    str_ = i::NewArray<uint16_t>(length_ + 1);
9660    str->Write(isolate, str_);
9661  }
9662  
~Value()9663  String::Value::~Value() { i::DeleteArray(str_); }
9664  
9665  #define DEFINE_ERROR(NAME, name)                                         \
9666    Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) {      \
9667      i::Isolate* isolate = i::Isolate::Current();                         \
9668      API_RCS_SCOPE(isolate, NAME, New);                                   \
9669      ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                            \
9670      i::Object error;                                                     \
9671      {                                                                    \
9672        i::HandleScope scope(isolate);                                     \
9673        i::Handle<i::String> message = Utils::OpenHandle(*raw_message);    \
9674        i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9675        error = *isolate->factory()->NewError(constructor, message);       \
9676      }                                                                    \
9677      i::Handle<i::Object> result(error, isolate);                         \
9678      return Utils::ToLocal(result);                                       \
9679    }
9680  
DEFINE_ERROR(RangeError,range_error)9681  DEFINE_ERROR(RangeError, range_error)
9682  DEFINE_ERROR(ReferenceError, reference_error)
9683  DEFINE_ERROR(SyntaxError, syntax_error)
9684  DEFINE_ERROR(TypeError, type_error)
9685  DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9686  DEFINE_ERROR(WasmLinkError, wasm_link_error)
9687  DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9688  DEFINE_ERROR(Error, error)
9689  
9690  #undef DEFINE_ERROR
9691  
9692  Local<Message> Exception::CreateMessage(Isolate* isolate,
9693                                          Local<Value> exception) {
9694    i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9695    i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9696    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9697    i::HandleScope scope(i_isolate);
9698    return Utils::MessageToLocal(
9699        scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9700  }
9701  
GetStackTrace(Local<Value> exception)9702  Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9703    i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9704    if (!obj->IsJSObject()) return Local<StackTrace>();
9705    i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9706    i::Isolate* isolate = js_obj->GetIsolate();
9707    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9708    return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9709  }
9710  
PreviewEntries(bool * is_key_value)9711  v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
9712    if (IsMap()) {
9713      *is_key_value = true;
9714      return Map::Cast(this)->AsArray();
9715    }
9716    if (IsSet()) {
9717      *is_key_value = false;
9718      return Set::Cast(this)->AsArray();
9719    }
9720  
9721    i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
9722    i::Isolate* isolate = object->GetIsolate();
9723    Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
9724    ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9725    if (object->IsJSWeakCollection()) {
9726      *is_key_value = object->IsJSWeakMap();
9727      return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9728          i::Handle<i::JSWeakCollection>::cast(object), 0));
9729    }
9730    if (object->IsJSMapIterator()) {
9731      i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
9732      MapAsArrayKind const kind =
9733          static_cast<MapAsArrayKind>(it->map().instance_type());
9734      *is_key_value = kind == MapAsArrayKind::kEntries;
9735      if (!it->HasMore()) return v8::Array::New(v8_isolate);
9736      return Utils::ToLocal(
9737          MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9738    }
9739    if (object->IsJSSetIterator()) {
9740      i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9741      SetAsArrayKind const kind =
9742          static_cast<SetAsArrayKind>(it->map().instance_type());
9743      *is_key_value = kind == SetAsArrayKind::kEntries;
9744      if (!it->HasMore()) return v8::Array::New(v8_isolate);
9745      return Utils::ToLocal(
9746          SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9747    }
9748    return v8::MaybeLocal<v8::Array>();
9749  }
9750  
GetFunctionName() const9751  Local<String> CpuProfileNode::GetFunctionName() const {
9752    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9753    i::Isolate* isolate = node->isolate();
9754    const i::CodeEntry* entry = node->entry();
9755    i::Handle<i::String> name =
9756        isolate->factory()->InternalizeUtf8String(entry->name());
9757    return ToApiHandle<String>(name);
9758  }
9759  
GetFunctionNameStr() const9760  const char* CpuProfileNode::GetFunctionNameStr() const {
9761    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9762    return node->entry()->name();
9763  }
9764  
GetScriptId() const9765  int CpuProfileNode::GetScriptId() const {
9766    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9767    const i::CodeEntry* entry = node->entry();
9768    return entry->script_id();
9769  }
9770  
GetScriptResourceName() const9771  Local<String> CpuProfileNode::GetScriptResourceName() const {
9772    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9773    i::Isolate* isolate = node->isolate();
9774    return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9775        node->entry()->resource_name()));
9776  }
9777  
GetScriptResourceNameStr() const9778  const char* CpuProfileNode::GetScriptResourceNameStr() const {
9779    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9780    return node->entry()->resource_name();
9781  }
9782  
IsScriptSharedCrossOrigin() const9783  bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9784    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9785    return node->entry()->is_shared_cross_origin();
9786  }
9787  
GetLineNumber() const9788  int CpuProfileNode::GetLineNumber() const {
9789    return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9790  }
9791  
GetColumnNumber() const9792  int CpuProfileNode::GetColumnNumber() const {
9793    return reinterpret_cast<const i::ProfileNode*>(this)
9794        ->entry()
9795        ->column_number();
9796  }
9797  
GetHitLineCount() const9798  unsigned int CpuProfileNode::GetHitLineCount() const {
9799    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9800    return node->GetHitLineCount();
9801  }
9802  
GetLineTicks(LineTick * entries,unsigned int length) const9803  bool CpuProfileNode::GetLineTicks(LineTick* entries,
9804                                    unsigned int length) const {
9805    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9806    return node->GetLineTicks(entries, length);
9807  }
9808  
GetBailoutReason() const9809  const char* CpuProfileNode::GetBailoutReason() const {
9810    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9811    return node->entry()->bailout_reason();
9812  }
9813  
GetHitCount() const9814  unsigned CpuProfileNode::GetHitCount() const {
9815    return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9816  }
9817  
GetNodeId() const9818  unsigned CpuProfileNode::GetNodeId() const {
9819    return reinterpret_cast<const i::ProfileNode*>(this)->id();
9820  }
9821  
GetSourceType() const9822  CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9823    return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9824  }
9825  
GetChildrenCount() const9826  int CpuProfileNode::GetChildrenCount() const {
9827    return static_cast<int>(
9828        reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9829  }
9830  
GetChild(int index) const9831  const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9832    const i::ProfileNode* child =
9833        reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9834    return reinterpret_cast<const CpuProfileNode*>(child);
9835  }
9836  
GetParent() const9837  const CpuProfileNode* CpuProfileNode::GetParent() const {
9838    const i::ProfileNode* parent =
9839        reinterpret_cast<const i::ProfileNode*>(this)->parent();
9840    return reinterpret_cast<const CpuProfileNode*>(parent);
9841  }
9842  
GetDeoptInfos() const9843  const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9844    const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9845    return node->deopt_infos();
9846  }
9847  
Delete()9848  void CpuProfile::Delete() {
9849    i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9850    i::CpuProfiler* profiler = profile->cpu_profiler();
9851    DCHECK_NOT_NULL(profiler);
9852    profiler->DeleteProfile(profile);
9853  }
9854  
GetTitle() const9855  Local<String> CpuProfile::GetTitle() const {
9856    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9857    i::Isolate* isolate = profile->top_down()->isolate();
9858    return ToApiHandle<String>(
9859        isolate->factory()->InternalizeUtf8String(profile->title()));
9860  }
9861  
GetTopDownRoot() const9862  const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9863    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9864    return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9865  }
9866  
GetSample(int index) const9867  const CpuProfileNode* CpuProfile::GetSample(int index) const {
9868    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9869    return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
9870  }
9871  
9872  const int CpuProfileNode::kNoLineNumberInfo;
9873  const int CpuProfileNode::kNoColumnNumberInfo;
9874  
GetSampleTimestamp(int index) const9875  int64_t CpuProfile::GetSampleTimestamp(int index) const {
9876    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9877    return profile->sample(index).timestamp.since_origin().InMicroseconds();
9878  }
9879  
GetSampleState(int index) const9880  StateTag CpuProfile::GetSampleState(int index) const {
9881    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9882    return profile->sample(index).state_tag;
9883  }
9884  
GetSampleEmbedderState(int index) const9885  EmbedderStateTag CpuProfile::GetSampleEmbedderState(int index) const {
9886    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9887    return profile->sample(index).embedder_state_tag;
9888  }
9889  
GetStartTime() const9890  int64_t CpuProfile::GetStartTime() const {
9891    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9892    return profile->start_time().since_origin().InMicroseconds();
9893  }
9894  
GetEndTime() const9895  int64_t CpuProfile::GetEndTime() const {
9896    const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9897    return profile->end_time().since_origin().InMicroseconds();
9898  }
9899  
ToInternal(const CpuProfile * profile)9900  static i::CpuProfile* ToInternal(const CpuProfile* profile) {
9901    return const_cast<i::CpuProfile*>(
9902        reinterpret_cast<const i::CpuProfile*>(profile));
9903  }
9904  
Serialize(OutputStream * stream,CpuProfile::SerializationFormat format) const9905  void CpuProfile::Serialize(OutputStream* stream,
9906                             CpuProfile::SerializationFormat format) const {
9907    Utils::ApiCheck(format == kJSON, "v8::CpuProfile::Serialize",
9908                    "Unknown serialization format");
9909    Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::CpuProfile::Serialize",
9910                    "Invalid stream chunk size");
9911    i::CpuProfileJSONSerializer serializer(ToInternal(this));
9912    serializer.Serialize(stream);
9913  }
9914  
GetSamplesCount() const9915  int CpuProfile::GetSamplesCount() const {
9916    return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9917  }
9918  
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)9919  CpuProfiler* CpuProfiler::New(Isolate* isolate,
9920                                CpuProfilingNamingMode naming_mode,
9921                                CpuProfilingLoggingMode logging_mode) {
9922    return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
9923        reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
9924  }
9925  
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)9926  CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
9927                                           unsigned max_samples,
9928                                           int sampling_interval_us,
9929                                           MaybeLocal<Context> filter_context)
9930      : mode_(mode),
9931        max_samples_(max_samples),
9932        sampling_interval_us_(sampling_interval_us) {
9933    if (!filter_context.IsEmpty()) {
9934      Local<Context> local_filter_context = filter_context.ToLocalChecked();
9935      filter_context_.Reset(local_filter_context->GetIsolate(),
9936                            local_filter_context);
9937      filter_context_.SetWeak();
9938    }
9939  }
9940  
raw_filter_context() const9941  void* CpuProfilingOptions::raw_filter_context() const {
9942    return reinterpret_cast<void*>(
9943        i::Context::cast(*Utils::OpenPersistent(filter_context_))
9944            .native_context()
9945            .address());
9946  }
9947  
Dispose()9948  void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9949  
9950  // static
CollectSample(Isolate * isolate)9951  void CpuProfiler::CollectSample(Isolate* isolate) {
9952    i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
9953  }
9954  
SetSamplingInterval(int us)9955  void CpuProfiler::SetSamplingInterval(int us) {
9956    DCHECK_GE(us, 0);
9957    return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
9958        base::TimeDelta::FromMicroseconds(us));
9959  }
9960  
SetUsePreciseSampling(bool use_precise_sampling)9961  void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
9962    reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
9963        use_precise_sampling);
9964  }
9965  
Start(CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9966  CpuProfilingResult CpuProfiler::Start(
9967      CpuProfilingOptions options,
9968      std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9969    return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9970        options, std::move(delegate));
9971  }
9972  
Start(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9973  CpuProfilingResult CpuProfiler::Start(
9974      Local<String> title, CpuProfilingOptions options,
9975      std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9976    return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9977        *Utils::OpenHandle(*title), options, std::move(delegate));
9978  }
9979  
Start(Local<String> title,bool record_samples)9980  CpuProfilingResult CpuProfiler::Start(Local<String> title,
9981                                        bool record_samples) {
9982    CpuProfilingOptions options(
9983        kLeafNodeLineNumbers,
9984        record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
9985    return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9986        *Utils::OpenHandle(*title), options);
9987  }
9988  
Start(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9989  CpuProfilingResult CpuProfiler::Start(Local<String> title,
9990                                        CpuProfilingMode mode,
9991                                        bool record_samples,
9992                                        unsigned max_samples) {
9993    CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
9994    return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9995        *Utils::OpenHandle(*title), options);
9996  }
9997  
StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9998  CpuProfilingStatus CpuProfiler::StartProfiling(
9999      Local<String> title, CpuProfilingOptions options,
10000      std::unique_ptr<DiscardedSamplesDelegate> delegate) {
10001    return Start(title, options, std::move(delegate)).status;
10002  }
10003  
StartProfiling(Local<String> title,bool record_samples)10004  CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10005                                                 bool record_samples) {
10006    return Start(title, record_samples).status;
10007  }
10008  
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)10009  CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10010                                                 CpuProfilingMode mode,
10011                                                 bool record_samples,
10012                                                 unsigned max_samples) {
10013    return Start(title, mode, record_samples, max_samples).status;
10014  }
10015  
StopProfiling(Local<String> title)10016  CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
10017    return reinterpret_cast<CpuProfile*>(
10018        reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
10019            *Utils::OpenHandle(*title)));
10020  }
10021  
Stop(ProfilerId id)10022  CpuProfile* CpuProfiler::Stop(ProfilerId id) {
10023    return reinterpret_cast<CpuProfile*>(
10024        reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id));
10025  }
10026  
UseDetailedSourcePositionsForProfiling(Isolate * isolate)10027  void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
10028    reinterpret_cast<i::Isolate*>(isolate)
10029        ->SetDetailedSourcePositionsForProfiling(true);
10030  }
10031  
GetCodeStartAddress()10032  uintptr_t CodeEvent::GetCodeStartAddress() {
10033    return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10034  }
10035  
GetCodeSize()10036  size_t CodeEvent::GetCodeSize() {
10037    return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10038  }
10039  
GetFunctionName()10040  Local<String> CodeEvent::GetFunctionName() {
10041    return ToApiHandle<String>(
10042        reinterpret_cast<i::CodeEvent*>(this)->function_name);
10043  }
10044  
GetScriptName()10045  Local<String> CodeEvent::GetScriptName() {
10046    return ToApiHandle<String>(
10047        reinterpret_cast<i::CodeEvent*>(this)->script_name);
10048  }
10049  
GetScriptLine()10050  int CodeEvent::GetScriptLine() {
10051    return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10052  }
10053  
GetScriptColumn()10054  int CodeEvent::GetScriptColumn() {
10055    return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10056  }
10057  
GetCodeType()10058  CodeEventType CodeEvent::GetCodeType() {
10059    return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10060  }
10061  
GetComment()10062  const char* CodeEvent::GetComment() {
10063    return reinterpret_cast<i::CodeEvent*>(this)->comment;
10064  }
10065  
GetPreviousCodeStartAddress()10066  uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10067    return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10068  }
10069  
GetCodeEventTypeName(CodeEventType code_event_type)10070  const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
10071    switch (code_event_type) {
10072      case kUnknownType:
10073        return "Unknown";
10074  #define V(Name)       \
10075    case k##Name##Type: \
10076      return #Name;
10077        CODE_EVENTS_LIST(V)
10078  #undef V
10079    }
10080    // The execution should never pass here
10081    UNREACHABLE();
10082  }
10083  
CodeEventHandler(Isolate * isolate)10084  CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10085    internal_listener_ =
10086        new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10087  }
10088  
~CodeEventHandler()10089  CodeEventHandler::~CodeEventHandler() {
10090    delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10091  }
10092  
Enable()10093  void CodeEventHandler::Enable() {
10094    reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10095        ->StartListening(this);
10096  }
10097  
Disable()10098  void CodeEventHandler::Disable() {
10099    reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10100        ->StopListening();
10101  }
10102  
ToInternal(const HeapGraphEdge * edge)10103  static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10104    return const_cast<i::HeapGraphEdge*>(
10105        reinterpret_cast<const i::HeapGraphEdge*>(edge));
10106  }
10107  
GetType() const10108  HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10109    return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10110  }
10111  
GetName() const10112  Local<Value> HeapGraphEdge::GetName() const {
10113    i::HeapGraphEdge* edge = ToInternal(this);
10114    i::Isolate* isolate = edge->isolate();
10115    switch (edge->type()) {
10116      case i::HeapGraphEdge::kContextVariable:
10117      case i::HeapGraphEdge::kInternal:
10118      case i::HeapGraphEdge::kProperty:
10119      case i::HeapGraphEdge::kShortcut:
10120      case i::HeapGraphEdge::kWeak:
10121        return ToApiHandle<String>(
10122            isolate->factory()->InternalizeUtf8String(edge->name()));
10123      case i::HeapGraphEdge::kElement:
10124      case i::HeapGraphEdge::kHidden:
10125        return ToApiHandle<Number>(
10126            isolate->factory()->NewNumberFromInt(edge->index()));
10127      default:
10128        UNREACHABLE();
10129    }
10130  }
10131  
GetFromNode() const10132  const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10133    const i::HeapEntry* from = ToInternal(this)->from();
10134    return reinterpret_cast<const HeapGraphNode*>(from);
10135  }
10136  
GetToNode() const10137  const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10138    const i::HeapEntry* to = ToInternal(this)->to();
10139    return reinterpret_cast<const HeapGraphNode*>(to);
10140  }
10141  
ToInternal(const HeapGraphNode * entry)10142  static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10143    return const_cast<i::HeapEntry*>(
10144        reinterpret_cast<const i::HeapEntry*>(entry));
10145  }
10146  
GetType() const10147  HeapGraphNode::Type HeapGraphNode::GetType() const {
10148    return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10149  }
10150  
GetName() const10151  Local<String> HeapGraphNode::GetName() const {
10152    i::Isolate* isolate = ToInternal(this)->isolate();
10153    return ToApiHandle<String>(
10154        isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10155  }
10156  
GetId() const10157  SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10158  
GetShallowSize() const10159  size_t HeapGraphNode::GetShallowSize() const {
10160    return ToInternal(this)->self_size();
10161  }
10162  
GetChildrenCount() const10163  int HeapGraphNode::GetChildrenCount() const {
10164    return ToInternal(this)->children_count();
10165  }
10166  
GetChild(int index) const10167  const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10168    return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10169  }
10170  
ToInternal(const HeapSnapshot * snapshot)10171  static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10172    return const_cast<i::HeapSnapshot*>(
10173        reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10174  }
10175  
Delete()10176  void HeapSnapshot::Delete() {
10177    i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10178    if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
10179        isolate->heap_profiler()->IsTakingSnapshot()) {
10180      ToInternal(this)->Delete();
10181    } else {
10182      // If this is the last snapshot, clean up all accessory data as well.
10183      isolate->heap_profiler()->DeleteAllSnapshots();
10184    }
10185  }
10186  
GetRoot() const10187  const HeapGraphNode* HeapSnapshot::GetRoot() const {
10188    return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10189  }
10190  
GetNodeById(SnapshotObjectId id) const10191  const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10192    return reinterpret_cast<const HeapGraphNode*>(
10193        ToInternal(this)->GetEntryById(id));
10194  }
10195  
GetNodesCount() const10196  int HeapSnapshot::GetNodesCount() const {
10197    return static_cast<int>(ToInternal(this)->entries().size());
10198  }
10199  
GetNode(int index) const10200  const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10201    return reinterpret_cast<const HeapGraphNode*>(
10202        &ToInternal(this)->entries().at(index));
10203  }
10204  
GetMaxSnapshotJSObjectId() const10205  SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10206    return ToInternal(this)->max_snapshot_js_object_id();
10207  }
10208  
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10209  void HeapSnapshot::Serialize(OutputStream* stream,
10210                               HeapSnapshot::SerializationFormat format) const {
10211    Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
10212                    "Unknown serialization format");
10213    Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
10214                    "Invalid stream chunk size");
10215    i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10216    serializer.Serialize(stream);
10217  }
10218  
10219  // static
10220  STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10221      HeapProfiler::kUnknownObjectId;
10222  
GetSnapshotCount()10223  int HeapProfiler::GetSnapshotCount() {
10224    return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10225  }
10226  
GetHeapSnapshot(int index)10227  const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10228    return reinterpret_cast<const HeapSnapshot*>(
10229        reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10230  }
10231  
GetObjectId(Local<Value> value)10232  SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10233    i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10234    return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10235  }
10236  
GetObjectId(NativeObject value)10237  SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10238    return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10239  }
10240  
FindObjectById(SnapshotObjectId id)10241  Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10242    i::Handle<i::Object> obj =
10243        reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10244    if (obj.is_null()) return Local<Value>();
10245    return Utils::ToLocal(obj);
10246  }
10247  
ClearObjectIds()10248  void HeapProfiler::ClearObjectIds() {
10249    reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10250  }
10251  
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)10252  const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
10253      ActivityControl* control, ObjectNameResolver* resolver,
10254      bool treat_global_objects_as_roots, bool capture_numeric_value) {
10255    return reinterpret_cast<const HeapSnapshot*>(
10256        reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
10257            control, resolver, treat_global_objects_as_roots,
10258            capture_numeric_value));
10259  }
10260  
StartTrackingHeapObjects(bool track_allocations)10261  void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10262    reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10263        track_allocations);
10264  }
10265  
StopTrackingHeapObjects()10266  void HeapProfiler::StopTrackingHeapObjects() {
10267    reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10268  }
10269  
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)10270  SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
10271                                              int64_t* timestamp_us) {
10272    i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
10273    return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
10274  }
10275  
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)10276  bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
10277                                               int stack_depth,
10278                                               SamplingFlags flags) {
10279    return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
10280        sample_interval, stack_depth, flags);
10281  }
10282  
StopSamplingHeapProfiler()10283  void HeapProfiler::StopSamplingHeapProfiler() {
10284    reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10285  }
10286  
GetAllocationProfile()10287  AllocationProfile* HeapProfiler::GetAllocationProfile() {
10288    return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10289  }
10290  
DeleteAllHeapSnapshots()10291  void HeapProfiler::DeleteAllHeapSnapshots() {
10292    reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10293  }
10294  
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10295  void HeapProfiler::AddBuildEmbedderGraphCallback(
10296      BuildEmbedderGraphCallback callback, void* data) {
10297    reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10298        callback, data);
10299  }
10300  
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10301  void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10302      BuildEmbedderGraphCallback callback, void* data) {
10303    reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10304        callback, data);
10305  }
10306  
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10307  void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10308                                                void* data) {
10309    reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10310                                                                         data);
10311  }
10312  
SetStackStart(void * stack_start)10313  void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10314    CHECK(isolate_);
10315    reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10316        stack_start);
10317  }
10318  
FinalizeTracing()10319  void EmbedderHeapTracer::FinalizeTracing() {
10320    if (isolate_) {
10321      i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10322      if (isolate->heap()->incremental_marking()->IsMarking()) {
10323        isolate->heap()->FinalizeIncrementalMarkingAtomically(
10324            i::GarbageCollectionReason::kExternalFinalize);
10325      }
10326    }
10327  }
10328  
IncreaseAllocatedSize(size_t bytes)10329  void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
10330    if (isolate_) {
10331      i::LocalEmbedderHeapTracer* const tracer =
10332          reinterpret_cast<i::Isolate*>(isolate_)
10333              ->heap()
10334              ->local_embedder_heap_tracer();
10335      DCHECK_NOT_NULL(tracer);
10336      tracer->IncreaseAllocatedSize(bytes);
10337    }
10338  }
10339  
DecreaseAllocatedSize(size_t bytes)10340  void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
10341    if (isolate_) {
10342      i::LocalEmbedderHeapTracer* const tracer =
10343          reinterpret_cast<i::Isolate*>(isolate_)
10344              ->heap()
10345              ->local_embedder_heap_tracer();
10346      DCHECK_NOT_NULL(tracer);
10347      tracer->DecreaseAllocatedSize(bytes);
10348    }
10349  }
10350  
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10351  void EmbedderHeapTracer::RegisterEmbedderReference(
10352      const BasicTracedReference<v8::Data>& ref) {
10353    if (ref.IsEmpty()) return;
10354  
10355    i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10356    heap->RegisterExternallyReferencedObject(
10357        reinterpret_cast<i::Address*>(ref.val_));
10358  }
10359  
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10360  void EmbedderHeapTracer::IterateTracedGlobalHandles(
10361      TracedGlobalHandleVisitor* visitor) {
10362    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10363    i::DisallowGarbageCollection no_gc;
10364    isolate->global_handles()->IterateTracedNodes(visitor);
10365  }
10366  
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10367  bool EmbedderHeapTracer::IsRootForNonTracingGC(
10368      const v8::TracedReference<v8::Value>& handle) {
10369    return true;
10370  }
10371  
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10372  void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10373      const v8::TracedReference<v8::Value>& handle) {
10374    UNREACHABLE();
10375  }
10376  
EmbedderStateScope(Isolate * isolate,Local<v8::Context> context,EmbedderStateTag tag)10377  EmbedderStateScope::EmbedderStateScope(Isolate* isolate,
10378                                         Local<v8::Context> context,
10379                                         EmbedderStateTag tag)
10380      : embedder_state_(new internal::EmbedderState(isolate, context, tag)) {}
10381  
10382  // std::unique_ptr's destructor is not compatible with Forward declared
10383  // EmbedderState class.
10384  // Default destructor must be defined in implementation file.
10385  EmbedderStateScope::~EmbedderStateScope() = default;
10386  
CheckValue() const10387  void TracedReferenceBase::CheckValue() const {
10388  #ifdef V8_HOST_ARCH_64_BIT
10389    if (!val_) return;
10390  
10391    CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_));
10392  #endif  // V8_HOST_ARCH_64_BIT
10393  }
10394  
CFunction(const void * address,const CFunctionInfo * type_info)10395  CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
10396      : address_(address), type_info_(type_info) {
10397    CHECK_NOT_NULL(address_);
10398    CHECK_NOT_NULL(type_info_);
10399  }
10400  
CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10401  CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info,
10402                               unsigned int arg_count, const CTypeInfo* arg_info)
10403      : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) {
10404    if (arg_count_ > 0) {
10405      for (unsigned int i = 0; i < arg_count_ - 1; ++i) {
10406        DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType);
10407      }
10408    }
10409  }
10410  
ArgumentInfo(unsigned int index) const10411  const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10412    DCHECK_LT(index, ArgumentCount());
10413    return arg_info_[index];
10414  }
10415  
ValidateIndex(size_t index) const10416  void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10417    DCHECK_LT(index, length_);
10418  }
10419  
RegisterState()10420  RegisterState::RegisterState()
10421      : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10422  RegisterState::~RegisterState() = default;
10423  
RegisterState(const RegisterState & other)10424  RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10425  
operator =(const RegisterState & other)10426  RegisterState& RegisterState::operator=(const RegisterState& other) {
10427    if (&other != this) {
10428      pc = other.pc;
10429      sp = other.sp;
10430      fp = other.fp;
10431      lr = other.lr;
10432      if (other.callee_saved) {
10433        // Make a deep copy if {other.callee_saved} is non-null.
10434        callee_saved =
10435            std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
10436      } else {
10437        // Otherwise, set {callee_saved} to null to match {other}.
10438        callee_saved.reset();
10439      }
10440    }
10441    return *this;
10442  }
10443  
10444  #if !V8_ENABLE_WEBASSEMBLY
10445  // If WebAssembly is disabled, we still need to provide an implementation of the
10446  // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all
10447  // methods are unreachable.
10448  
10449  class WasmStreaming::WasmStreamingImpl {};
10450  
WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10451  WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10452    UNREACHABLE();
10453  }
10454  
10455  WasmStreaming::~WasmStreaming() = default;
10456  
OnBytesReceived(const uint8_t * bytes,size_t size)10457  void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10458    UNREACHABLE();
10459  }
10460  
Finish(bool can_use_compiled_module)10461  void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); }
10462  
Abort(MaybeLocal<Value> exception)10463  void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10464  
SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10465  bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10466    UNREACHABLE();
10467  }
10468  
SetClient(std::shared_ptr<Client> client)10469  void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10470  
SetUrl(const char * url,size_t length)10471  void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10472  
10473  // static
Unpack(Isolate * isolate,Local<Value> value)10474  std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10475                                                       Local<Value> value) {
10476    FATAL("WebAssembly is disabled");
10477  }
10478  #endif  // !V8_ENABLE_WEBASSEMBLY
10479  
10480  namespace internal {
10481  
10482  const size_t HandleScopeImplementer::kEnteredContextsOffset =
10483      offsetof(HandleScopeImplementer, entered_contexts_);
10484  const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10485      offsetof(HandleScopeImplementer, is_microtask_context_);
10486  
FreeThreadResources()10487  void HandleScopeImplementer::FreeThreadResources() { Free(); }
10488  
ArchiveThread(char * storage)10489  char* HandleScopeImplementer::ArchiveThread(char* storage) {
10490    HandleScopeData* current = isolate_->handle_scope_data();
10491    handle_scope_data_ = *current;
10492    MemCopy(storage, this, sizeof(*this));
10493  
10494    ResetAfterArchive();
10495    current->Initialize();
10496  
10497    return storage + ArchiveSpacePerThread();
10498  }
10499  
ArchiveSpacePerThread()10500  int HandleScopeImplementer::ArchiveSpacePerThread() {
10501    return sizeof(HandleScopeImplementer);
10502  }
10503  
RestoreThread(char * storage)10504  char* HandleScopeImplementer::RestoreThread(char* storage) {
10505    MemCopy(this, storage, sizeof(*this));
10506    *isolate_->handle_scope_data() = handle_scope_data_;
10507    return storage + ArchiveSpacePerThread();
10508  }
10509  
IterateThis(RootVisitor * v)10510  void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10511  #ifdef DEBUG
10512    bool found_block_before_deferred = false;
10513  #endif
10514    // Iterate over all handles in the blocks except for the last.
10515    for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10516      Address* block = blocks()->at(i);
10517      // Cast possibly-unrelated pointers to plain Address before comparing them
10518      // to avoid undefined behavior.
10519      if (last_handle_before_deferred_block_ != nullptr &&
10520          (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
10521           reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
10522          (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
10523           reinterpret_cast<Address>(block))) {
10524        v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10525                             FullObjectSlot(last_handle_before_deferred_block_));
10526        DCHECK(!found_block_before_deferred);
10527  #ifdef DEBUG
10528        found_block_before_deferred = true;
10529  #endif
10530      } else {
10531        v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10532                             FullObjectSlot(&block[kHandleBlockSize]));
10533      }
10534    }
10535  
10536    DCHECK(last_handle_before_deferred_block_ == nullptr ||
10537           found_block_before_deferred);
10538  
10539    // Iterate over live handles in the last block (if any).
10540    if (!blocks()->empty()) {
10541      v->VisitRootPointers(Root::kHandleScope, nullptr,
10542                           FullObjectSlot(blocks()->back()),
10543                           FullObjectSlot(handle_scope_data_.next));
10544    }
10545  
10546    DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
10547                                                   &entered_contexts_};
10548    for (unsigned i = 0; i < arraysize(context_lists); i++) {
10549      context_lists[i]->shrink_to_fit();
10550      if (context_lists[i]->empty()) continue;
10551      FullObjectSlot start(&context_lists[i]->front());
10552      v->VisitRootPointers(Root::kHandleScope, nullptr, start,
10553                           start + static_cast<int>(context_lists[i]->size()));
10554    }
10555    // The shape of |entered_contexts_| and |is_microtask_context_| stacks must
10556    // be in sync.
10557    is_microtask_context_.shrink_to_fit();
10558    DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
10559    DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
10560  }
10561  
Iterate(RootVisitor * v)10562  void HandleScopeImplementer::Iterate(RootVisitor* v) {
10563    HandleScopeData* current = isolate_->handle_scope_data();
10564    handle_scope_data_ = *current;
10565    IterateThis(v);
10566  }
10567  
Iterate(RootVisitor * v,char * storage)10568  char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10569    HandleScopeImplementer* scope_implementer =
10570        reinterpret_cast<HandleScopeImplementer*>(storage);
10571    scope_implementer->IterateThis(v);
10572    return storage + ArchiveSpacePerThread();
10573  }
10574  
DetachPersistent(Address * prev_limit)10575  std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
10576      Address* prev_limit) {
10577    std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
10578    DCHECK_NOT_NULL(prev_limit);
10579  
10580    while (!blocks_.empty()) {
10581      Address* block_start = blocks_.back();
10582      Address* block_limit = &block_start[kHandleBlockSize];
10583      // We should not need to check for SealHandleScope here. Assert this.
10584      DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
10585                     prev_limit == block_limit);
10586      if (prev_limit == block_limit) break;
10587      ph->blocks_.push_back(blocks_.back());
10588  #if DEBUG
10589      ph->ordered_blocks_.insert(blocks_.back());
10590  #endif
10591      blocks_.pop_back();
10592    }
10593  
10594    // ph->blocks_ now contains the blocks installed on the
10595    // HandleScope stack since BeginDeferredScope was called, but in
10596    // reverse order.
10597  
10598    // Switch first and last blocks, such that the last block is the one
10599    // that is potentially half full.
10600    DCHECK(!blocks_.empty() && !ph->blocks_.empty());
10601    std::swap(ph->blocks_.front(), ph->blocks_.back());
10602  
10603    ph->block_next_ = isolate()->handle_scope_data()->next;
10604    Address* block_start = ph->blocks_.back();
10605    ph->block_limit_ = block_start + kHandleBlockSize;
10606  
10607    DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10608    last_handle_before_deferred_block_ = nullptr;
10609    return ph;
10610  }
10611  
BeginDeferredScope()10612  void HandleScopeImplementer::BeginDeferredScope() {
10613    DCHECK_NULL(last_handle_before_deferred_block_);
10614    last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10615  }
10616  
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10617  void InvokeAccessorGetterCallback(
10618      v8::Local<v8::Name> property,
10619      const v8::PropertyCallbackInfo<v8::Value>& info,
10620      v8::AccessorNameGetterCallback getter) {
10621    // Leaving JavaScript.
10622    Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10623    RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
10624    Address getter_address = reinterpret_cast<Address>(getter);
10625    ExternalCallbackScope call_scope(isolate, getter_address);
10626    getter(property, info);
10627  }
10628  
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10629  void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10630                              v8::FunctionCallback callback) {
10631    Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10632    RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
10633    Address callback_address = reinterpret_cast<Address>(callback);
10634    ExternalCallbackScope call_scope(isolate, callback_address);
10635    callback(info);
10636  }
10637  
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10638  void InvokeFinalizationRegistryCleanupFromTask(
10639      Handle<Context> context,
10640      Handle<JSFinalizationRegistry> finalization_registry,
10641      Handle<Object> callback) {
10642    Isolate* isolate = finalization_registry->native_context().GetIsolate();
10643    RCS_SCOPE(isolate,
10644              RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
10645    // Do not use ENTER_V8 because this is always called from a running
10646    // FinalizationRegistryCleanupTask within V8 and we should not log it as an
10647    // API call. This method is implemented here to avoid duplication of the
10648    // exception handling and microtask running logic in CallDepthScope.
10649    if (IsExecutionTerminatingCheck(isolate)) return;
10650    Local<v8::Context> api_context = Utils::ToLocal(context);
10651    CallDepthScope<true> call_depth_scope(isolate, api_context);
10652    VMState<OTHER> state(isolate);
10653    Handle<Object> argv[] = {callback};
10654    if (Execution::CallBuiltin(isolate,
10655                               isolate->finalization_registry_cleanup_some(),
10656                               finalization_registry, arraysize(argv), argv)
10657            .is_null()) {
10658      call_depth_scope.Escape();
10659    }
10660  }
10661  
10662  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10663  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10664  int32_t ConvertDouble(double d) {
10665    return internal::DoubleToInt32(d);
10666  }
10667  
10668  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10669  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10670  uint32_t ConvertDouble(double d) {
10671    return internal::DoubleToUint32(d);
10672  }
10673  
10674  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10675  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10676  float ConvertDouble(double d) {
10677    return internal::DoubleToFloat32(d);
10678  }
10679  
10680  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10681  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10682  double ConvertDouble(double d) {
10683    return d;
10684  }
10685  
10686  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10687  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10688  int64_t ConvertDouble(double d) {
10689    return internal::DoubleToWebIDLInt64(d);
10690  }
10691  
10692  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10693  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10694  uint64_t ConvertDouble(double d) {
10695    return internal::DoubleToWebIDLUint64(d);
10696  }
10697  
10698  template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10699  EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10700  bool ConvertDouble(double d) {
10701    // Implements https://tc39.es/ecma262/#sec-toboolean.
10702    return !std::isnan(d) && d != 0;
10703  }
10704  
10705  // Undefine macros for jumbo build.
10706  #undef SET_FIELD_WRAPPED
10707  #undef NEW_STRING
10708  #undef CALLBACK_SETTER
10709  
10710  }  // namespace internal
10711  
10712  template <>
10713  bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10714  TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
10715                                      int32_t>(Local<Array> src, int32_t* dst,
10716                                               uint32_t max_length) {
10717    return CopyAndConvertArrayToCppBuffer<
10718        CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence)
10719            .GetId(),
10720        int32_t>(src, dst, max_length);
10721  }
10722  
10723  template <>
10724  bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10725  TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
10726                                      uint32_t>(Local<Array> src, uint32_t* dst,
10727                                                uint32_t max_length) {
10728    return CopyAndConvertArrayToCppBuffer<
10729        CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence)
10730            .GetId(),
10731        uint32_t>(src, dst, max_length);
10732  }
10733  
10734  template <>
10735  bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10736  TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
10737                                      float>(Local<Array> src, float* dst,
10738                                             uint32_t max_length) {
10739    return CopyAndConvertArrayToCppBuffer<
10740        CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence)
10741            .GetId(),
10742        float>(src, dst, max_length);
10743  }
10744  
10745  template <>
10746  bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10747  TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
10748                                      double>(Local<Array> src, double* dst,
10749                                              uint32_t max_length) {
10750    return CopyAndConvertArrayToCppBuffer<
10751        CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence)
10752            .GetId(),
10753        double>(src, dst, max_length);
10754  }
10755  
10756  }  // namespace v8
10757  
10758  #undef TRACE_BS
10759  #include "src/api/api-macros-undef.h"
10760