xref: /third_party/node/deps/v8/src/api/api.cc (revision 1cb0ef41)
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
169namespace v8 {
170
171static OOMErrorCallback g_oom_error_callback = nullptr;
172
173static 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
193Local<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
206void 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.
212void 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
311void 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
327void 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
354void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
355  i::V8::SetSnapshotBlob(snapshot_blob);
356}
357
358namespace {
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.
366class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
367 public:
368  ArrayBufferAllocator() { CHECK(page_allocator_); }
369
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
376  void* AllocateUninitialized(size_t length) override {
377    return Allocate(length);
378  }
379
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
391class 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
434struct SnapshotCreatorData {
435  explicit SnapshotCreatorData(Isolate* isolate)
436      : isolate_(isolate),
437        default_context_(),
438        contexts_(isolate),
439        created_(false) {}
440
441  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
456SnapshotCreator::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
479SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
480                                 StartupData* existing_snapshot)
481    : SnapshotCreator(Isolate::Allocate(), external_references,
482                      existing_snapshot) {}
483
484SnapshotCreator::~SnapshotCreator() {
485  SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
486  Isolate* isolate = data->isolate_;
487  isolate->Exit();
488  isolate->Dispose();
489  delete data;
490}
491
492Isolate* SnapshotCreator::GetIsolate() {
493  return SnapshotCreatorData::cast(data_)->isolate_;
494}
495
496void 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
508size_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
521size_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
541size_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
561namespace {
562void 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
575void 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
588StartupData 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
686bool StartupData::CanBeRehashed() const {
687  DCHECK(i::Snapshot::VerifyChecksum(this));
688  return i::Snapshot::ExtractRehashability(this);
689}
690
691bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
692
693void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
694  v8::base::SetDcheckFunction(that);
695}
696
697void V8::SetFlagsFromString(const char* str) {
698  SetFlagsFromString(str, strlen(str));
699}
700
701void V8::SetFlagsFromString(const char* str, size_t length) {
702  i::FlagList::SetFlagsFromString(str, length);
703  i::FlagList::EnforceFlagImplications();
704}
705
706void 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
712RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
713
714RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
715    : extension_(std::move(extension)) {}
716
717// static
718void 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
726void 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
736namespace {
737class ExtensionResource : public String::ExternalOneByteStringResource {
738 public:
739  ExtensionResource() : data_(nullptr), length_(0) {}
740  ExtensionResource(const char* data, size_t length)
741      : data_(data), length_(length) {}
742  const char* data() const override { return data_; }
743  size_t length() const override { return length_; }
744  void Dispose() override {}
745
746 private:
747  const char* data_;
748  size_t length_;
749};
750}  // anonymous namespace
751
752void RegisterExtension(std::unique_ptr<Extension> extension) {
753  RegisteredExtension::Register(std::move(extension));
754}
755
756Extension::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
769void 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
795void 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
811namespace internal {
812
813i::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
831void MoveTracedReference(internal::Address** from, internal::Address** to) {
832  GlobalHandles::MoveTracedReference(from, to);
833}
834
835void CopyTracedReference(const internal::Address* const* from,
836                         internal::Address** to) {
837  GlobalHandles::CopyTracedReference(from, to);
838}
839
840void DisposeTracedReference(internal::Address* location) {
841  GlobalHandles::DestroyTracedReference(location);
842}
843
844}  // namespace internal
845
846namespace api_internal {
847
848i::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
859i::Address* CopyGlobalReference(i::Address* from) {
860  i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
861  return result.location();
862}
863
864void MoveGlobalReference(internal::Address** from, internal::Address** to) {
865  i::GlobalHandles::MoveGlobal(from, to);
866}
867
868void 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
874void MakeWeak(i::Address** location_addr) {
875  i::GlobalHandles::MakeWeak(location_addr);
876}
877
878void* ClearWeak(i::Address* location) {
879  return i::GlobalHandles::ClearWeakness(location);
880}
881
882void AnnotateStrongRetainer(i::Address* location, const char* label) {
883  i::GlobalHandles::AnnotateStrongRetainer(location, label);
884}
885
886void DisposeGlobal(i::Address* location) {
887  i::GlobalHandles::Destroy(location);
888}
889
890Value* 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
899void FromJustIsNothing() {
900  Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
901}
902
903void ToLocalEmpty() {
904  Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
905}
906
907void 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
917HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
918
919void 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
939HandleScope::~HandleScope() {
940  i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
941}
942
943void* HandleScope::operator new(size_t) { base::OS::Abort(); }
944void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
945void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
946void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
947
948int HandleScope::NumberOfHandles(Isolate* isolate) {
949  return i::HandleScope::NumberOfHandles(
950      reinterpret_cast<i::Isolate*>(isolate));
951}
952
953i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
954  return i::HandleScope::CreateHandle(isolate, value);
955}
956
957EscapableHandleScope::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
964i::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
976void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
977void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
978void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
979void EscapableHandleScope::operator delete[](void*, size_t) {
980  base::OS::Abort();
981}
982
983SealHandleScope::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
992SealHandleScope::~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
1000void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
1001void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
1002void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1003void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1004
1005bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
1006bool Data::IsFixedArray() const {
1007  return Utils::OpenHandle(this)->IsFixedArray();
1008}
1009
1010bool 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
1022bool Data::IsPrivate() const {
1023  return Utils::OpenHandle(this)->IsPrivateSymbol();
1024}
1025
1026bool Data::IsObjectTemplate() const {
1027  return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1028}
1029
1030bool Data::IsFunctionTemplate() const {
1031  return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1032}
1033
1034bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1035
1036void 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
1046void 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
1059Context::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
1074Context::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
1083STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1084
1085static 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
1108uint32_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
1119v8::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
1130void 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
1141void* 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
1155void 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
1168static 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
1177void 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
1201void 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
1207void 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 ---
1227static 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
1233static Local<ObjectTemplate> ObjectTemplateNew(
1234    i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1235    bool do_not_cache);
1236
1237Local<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
1251void 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
1268static 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
1275void 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
1287static 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
1331Local<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
1359Local<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
1381Local<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
1393Local<Signature> Signature::New(Isolate* isolate,
1394                                Local<FunctionTemplate> receiver) {
1395  return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1396}
1397
1398Local<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
1409void 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
1452namespace {
1453
1454template <typename Getter, typename Setter>
1455i::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
1499Local<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
1519void 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
1527void 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
1535void 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
1543void 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
1551void 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
1561Local<ObjectTemplate> ObjectTemplate::New(
1562    Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1563  return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1564}
1565
1566static 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
1588Local<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.
1595static 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
1611template <typename Getter, typename Setter, typename Data, typename Template>
1612static 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
1636void 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
1649void 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
1660void 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
1673void 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
1684void 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
1696void 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
1707void 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
1720void 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
1733void 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
1746void 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
1759template <typename Getter, typename Setter, typename Query, typename Descriptor,
1760          typename Deleter, typename Enumerator, typename Definer>
1761static 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
1796template <typename Getter, typename Setter, typename Query, typename Descriptor,
1797          typename Deleter, typename Enumerator, typename Definer>
1798static 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
1809template <typename Getter, typename Setter, typename Query, typename Descriptor,
1810          typename Deleter, typename Enumerator, typename Definer>
1811static 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
1822template <typename Getter, typename Setter, typename Query, typename Descriptor,
1823          typename Deleter, typename Enumerator, typename Definer>
1824static 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
1839void 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
1847void 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
1856void 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
1882void 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
1921void 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
1935void 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
1952int ObjectTemplate::InternalFieldCount() const {
1953  return Utils::OpenHandle(this)->embedder_field_count();
1954}
1955
1956void 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
1973bool ObjectTemplate::IsImmutableProto() const {
1974  return Utils::OpenHandle(this)->immutable_proto();
1975}
1976
1977void 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
1984bool ObjectTemplate::IsCodeLike() const {
1985  return Utils::OpenHandle(this)->code_like();
1986}
1987
1988void 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
2000ScriptCompiler::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
2007ScriptCompiler::CachedData::~CachedData() {
2008  if (buffer_policy == BufferOwned) {
2009    delete[] data;
2010  }
2011}
2012
2013ScriptCompiler::StreamedSource::StreamedSource(
2014    std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2015    : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2016
2017ScriptCompiler::StreamedSource::~StreamedSource() = default;
2018
2019Local<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
2031int 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
2037int 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
2051Local<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
2065Local<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
2079Local<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
2093MaybeLocal<Value> Script::Run(Local<Context> context) {
2094  return Run(context, Local<Data>());
2095}
2096
2097MaybeLocal<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
2166Local<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
2174Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2175  return HostDefinedOptions().As<PrimitiveArray>();
2176}
2177
2178Local<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
2186Local<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
2194Local<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
2205Local<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
2214int PrimitiveArray::Length() const {
2215  i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2216  return array->length();
2217}
2218
2219void 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
2232Local<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
2244void 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
2252int FixedArray::Length() const {
2253  i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2254  return self->length();
2255}
2256
2257Local<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
2265Local<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
2271int ModuleRequest::GetSourceOffset() const {
2272  return Utils::OpenHandle(this)->position();
2273}
2274
2275Local<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
2281Module::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
2302Local<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
2311Local<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
2327Location 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
2342Local<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
2354Local<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
2366int 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
2374bool 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
2384bool Module::IsSourceTextModule() const {
2385  return Utils::OpenHandle(this)->IsSourceTextModule();
2386}
2387
2388bool Module::IsSyntheticModule() const {
2389  return Utils::OpenHandle(this)->IsSyntheticModule();
2390}
2391
2392int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2393
2394Maybe<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
2405MaybeLocal<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
2425Local<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
2444Maybe<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
2466namespace {
2467
2468i::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
2488MaybeLocal<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
2542MaybeLocal<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
2552MaybeLocal<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
2568MaybeLocal<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
2587V8_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
2598MaybeLocal<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
2609MaybeLocal<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
2700void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2701
2702ScriptCompiler::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
2714ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2715    std::unique_ptr<i::BackgroundDeserializeTask> impl)
2716    : impl_(std::move(impl)) {}
2717
2718ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2719
2720void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2721
2722ScriptCompiler::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
2732namespace {
2733i::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
2748MaybeLocal<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
2769MaybeLocal<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
2787uint32_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
2793ScriptCompiler::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
2804ScriptCompiler::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
2814ScriptCompiler::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
2827MaybeLocal<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
2839v8::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
2854v8::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
2883void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
2884void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
2885void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
2886void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2887
2888bool v8::TryCatch::HasCaught() const {
2889  return !i::Object(reinterpret_cast<i::Address>(exception_))
2890              .IsTheHole(isolate_);
2891}
2892
2893bool v8::TryCatch::CanContinue() const { return can_continue_; }
2894
2895bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2896
2897v8::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
2903v8::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
2913MaybeLocal<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
2931MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2932  if (!HasCaught()) return v8::Local<Value>();
2933  return StackTrace(context, Exception());
2934}
2935
2936v8::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
2946void 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
2956void 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
2962void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2963
2964bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2965
2966void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2967
2968// --- M e s s a g e ---
2969
2970Local<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
2981v8::Isolate* Message::GetIsolate() const {
2982  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983  return reinterpret_cast<Isolate*>(isolate);
2984}
2985
2986ScriptOrigin 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
2994void 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
3009v8::Local<Value> Message::GetScriptResourceName() const {
3010  ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
3011  return GetScriptOrigin().ResourceName();
3012}
3013
3014v8::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
3025Maybe<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
3034int 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
3043int 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
3052int Message::ErrorLevel() const {
3053  auto self = Utils::OpenHandle(this);
3054  ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3055  return self->error_level();
3056}
3057
3058int 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
3067int 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
3091Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3092  return Just(GetStartColumn());
3093}
3094
3095int 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
3108Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3109  return Just(GetEndColumn());
3110}
3111
3112bool 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
3119bool 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
3126MaybeLocal<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
3135MaybeLocal<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
3144void 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
3152Local<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
3160int StackTrace::GetFrameCount() const {
3161  return Utils::OpenHandle(this)->length();
3162}
3163
3164Local<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
3174Local<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
3184Location 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
3201int StackFrame::GetScriptId() const {
3202  return Utils::OpenHandle(this)->script().id();
3203}
3204
3205Local<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
3213Local<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
3222Local<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
3231Local<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
3240Local<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
3248bool 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
3253bool StackFrame::IsConstructor() const {
3254  return Utils::OpenHandle(this)->is_constructor();
3255}
3256
3257bool StackFrame::IsWasm() const { return !IsUserJavaScript(); }
3258
3259bool StackFrame::IsUserJavaScript() const {
3260  return Utils::OpenHandle(this)->script().IsUserJavaScript();
3261}
3262
3263// --- J S O N ---
3264
3265MaybeLocal<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
3280MaybeLocal<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
3302Maybe<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
3311Maybe<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
3320Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3321    Isolate* v8_isolate, Local<WasmModuleObject> module) {
3322  return Nothing<uint32_t>();
3323}
3324
3325bool ValueSerializer::Delegate::SupportsSharedValues() const { return false; }
3326
3327Maybe<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
3336void* 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
3343void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3344  return base::Free(buffer);
3345}
3346
3347struct ValueSerializer::PrivateData {
3348  explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3349      : isolate(i), serializer(i, delegate) {}
3350  i::Isolate* isolate;
3351  i::ValueSerializer serializer;
3352};
3353
3354ValueSerializer::ValueSerializer(Isolate* isolate)
3355    : ValueSerializer(isolate, nullptr) {}
3356
3357ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3358    : private_(
3359          new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3360
3361ValueSerializer::~ValueSerializer() { delete private_; }
3362
3363void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3364
3365void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3366  private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3367}
3368
3369Maybe<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
3381std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3382  return private_->serializer.Release();
3383}
3384
3385void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3386                                          Local<ArrayBuffer> array_buffer) {
3387  private_->serializer.TransferArrayBuffer(transfer_id,
3388                                           Utils::OpenHandle(*array_buffer));
3389}
3390
3391void ValueSerializer::WriteUint32(uint32_t value) {
3392  private_->serializer.WriteUint32(value);
3393}
3394
3395void ValueSerializer::WriteUint64(uint64_t value) {
3396  private_->serializer.WriteUint64(value);
3397}
3398
3399void ValueSerializer::WriteDouble(double value) {
3400  private_->serializer.WriteDouble(value);
3401}
3402
3403void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3404  private_->serializer.WriteRawBytes(source, length);
3405}
3406
3407MaybeLocal<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
3416MaybeLocal<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
3425bool ValueDeserializer::Delegate::SupportsSharedValues() const { return false; }
3426
3427MaybeLocal<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
3436MaybeLocal<SharedArrayBuffer>
3437ValueDeserializer::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
3446struct ValueDeserializer::PrivateData {
3447  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
3455ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3456                                     size_t size)
3457    : ValueDeserializer(isolate, data, size, nullptr) {}
3458
3459ValueDeserializer::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
3465ValueDeserializer::~ValueDeserializer() { delete private_; }
3466
3467Maybe<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
3489void ValueDeserializer::SetSupportsLegacyWireFormat(
3490    bool supports_legacy_wire_format) {
3491  private_->supports_legacy_wire_format = supports_legacy_wire_format;
3492}
3493
3494uint32_t ValueDeserializer::GetWireFormatVersion() const {
3495  return private_->deserializer.GetWireFormatVersion();
3496}
3497
3498MaybeLocal<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
3513void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3514                                            Local<ArrayBuffer> array_buffer) {
3515  private_->deserializer.TransferArrayBuffer(transfer_id,
3516                                             Utils::OpenHandle(*array_buffer));
3517}
3518
3519void 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
3525bool ValueDeserializer::ReadUint32(uint32_t* value) {
3526  return private_->deserializer.ReadUint32(value);
3527}
3528
3529bool ValueDeserializer::ReadUint64(uint64_t* value) {
3530  return private_->deserializer.ReadUint64(value);
3531}
3532
3533bool ValueDeserializer::ReadDouble(double* value) {
3534  return private_->deserializer.ReadDouble(value);
3535}
3536
3537bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3538  return private_->deserializer.ReadRawBytes(length, data);
3539}
3540
3541// --- D a t a ---
3542
3543bool 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
3550bool 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
3557bool Value::IsTrue() const {
3558  i::Object object = *Utils::OpenHandle(this);
3559  if (object.IsSmi()) return false;
3560  return object.IsTrue();
3561}
3562
3563bool Value::IsFalse() const {
3564  i::Object object = *Utils::OpenHandle(this);
3565  if (object.IsSmi()) return false;
3566  return object.IsFalse();
3567}
3568
3569bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3570
3571bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3572
3573bool Value::FullIsString() const {
3574  bool result = Utils::OpenHandle(this)->IsString();
3575  DCHECK_EQ(result, QuickIsString());
3576  return result;
3577}
3578
3579bool Value::IsSymbol() const {
3580  return Utils::OpenHandle(this)->IsPublicSymbol();
3581}
3582
3583bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3584
3585bool 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
3591bool Value::IsArrayBufferView() const {
3592  return Utils::OpenHandle(this)->IsJSArrayBufferView();
3593}
3594
3595bool 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
3606TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3607
3608#undef VALUE_IS_TYPED_ARRAY
3609
3610bool Value::IsDataView() const {
3611  return Utils::OpenHandle(this)->IsJSDataView();
3612}
3613
3614bool 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
3620bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3621
3622bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3623
3624bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3625
3626bool 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
3634VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3635VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3636VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3637VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3638VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3639VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3640VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3641VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3642VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3643#if V8_ENABLE_WEBASSEMBLY
3644VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3645VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3646#else
3647bool Value::IsWasmMemoryObject() const { return false; }
3648bool Value::IsWasmModuleObject() const { return false; }
3649#endif  // V8_ENABLE_WEBASSEMBLY
3650VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3651VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3652
3653#undef VALUE_IS_SPECIFIC_TYPE
3654
3655bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3656
3657bool Value::IsExternal() const {
3658  i::Object obj = *Utils::OpenHandle(this);
3659  return obj.IsJSExternalObject();
3660}
3661
3662bool 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
3671bool 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
3682bool Value::IsNativeError() const {
3683  return Utils::OpenHandle(this)->IsJSError();
3684}
3685
3686bool Value::IsRegExp() const {
3687  i::Handle<i::Object> obj = Utils::OpenHandle(this);
3688  return obj->IsJSRegExp();
3689}
3690
3691bool 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
3698bool 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
3706bool Value::IsGeneratorObject() const {
3707  return Utils::OpenHandle(this)->IsJSGeneratorObject();
3708}
3709
3710bool Value::IsMapIterator() const {
3711  return Utils::OpenHandle(this)->IsJSMapIterator();
3712}
3713
3714bool Value::IsSetIterator() const {
3715  return Utils::OpenHandle(this)->IsJSSetIterator();
3716}
3717
3718bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3719
3720bool Value::IsModuleNamespaceObject() const {
3721  return Utils::OpenHandle(this)->IsJSModuleNamespace();
3722}
3723
3724MaybeLocal<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
3735MaybeLocal<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
3745MaybeLocal<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
3756MaybeLocal<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
3767bool Value::BooleanValue(Isolate* v8_isolate) const {
3768  return Utils::OpenHandle(this)->BooleanValue(
3769      reinterpret_cast<i::Isolate*>(v8_isolate));
3770}
3771
3772Local<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
3779MaybeLocal<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
3790MaybeLocal<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
3801MaybeLocal<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
3812MaybeLocal<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
3823i::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
3829i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3830  return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3831}
3832
3833bool i::ShouldThrowOnError(i::Isolate* isolate) {
3834  return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3835         i::ShouldThrow::kThrowOnError;
3836}
3837
3838bool 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
3845void 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
3852void v8::Value::CheckCast(Data* that) {
3853  Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3854}
3855
3856void External::CheckCast(v8::Value* that) {
3857  Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3858                  "Value is not an External");
3859}
3860
3861void 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
3867void 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
3873void 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
3879void 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
3884void 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
3889void 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
3894void 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
3901void 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
3907void 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
3913void 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
3918void 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
3924void 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
3930void 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
3935void 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
3940void v8::BigInt::CheckCast(v8::Data* that) {
3941  Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3942                  "Value is not a BigInt");
3943}
3944
3945void 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
3951void 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
3956void 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
3961void 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
3966void v8::Promise::CheckCast(Value* that) {
3967  Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3968                  "Value is not a Promise");
3969}
3970
3971void v8::Promise::Resolver::CheckCast(Value* that) {
3972  Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3973                  "Value is not a Promise::Resolver");
3974}
3975
3976void v8::Proxy::CheckCast(Value* that) {
3977  Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3978}
3979
3980void v8::WasmMemoryObject::CheckCast(Value* that) {
3981  Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3982                  "Value is not a WasmMemoryObject");
3983}
3984
3985void v8::WasmModuleObject::CheckCast(Value* that) {
3986  Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3987                  "Value is not a WasmModuleObject");
3988}
3989
3990v8::BackingStore::~BackingStore() {
3991  auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3992  i_this->~BackingStore();  // manually call internal destructor
3993}
3994
3995void* v8::BackingStore::Data() const {
3996  return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3997}
3998
3999size_t v8::BackingStore::ByteLength() const {
4000  return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
4001}
4002
4003bool v8::BackingStore::IsShared() const {
4004  return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
4005}
4006
4007// static
4008std::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
4025void v8::BackingStore::EmptyDeleter(void* data, size_t length,
4026                                    void* deleter_data) {
4027  DCHECK_NULL(deleter_data);
4028}
4029
4030std::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
4041void* v8::ArrayBuffer::Data() const {
4042  i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4043  return self->backing_store();
4044}
4045
4046std::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
4056void* v8::SharedArrayBuffer::Data() const {
4057  i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4058  return self->backing_store();
4059}
4060
4061void 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
4068void 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
4074constexpr size_t v8::TypedArray::kMaxLength;
4075
4076void 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
4091TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4092
4093#undef CHECK_TYPED_ARRAY_CAST
4094
4095void 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
4101void 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
4108void 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
4113void 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
4119void 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
4125void 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
4131void 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
4137void 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
4143void 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
4149Maybe<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
4161Maybe<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
4175Maybe<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
4188Maybe<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
4201MaybeLocal<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
4226Maybe<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
4237bool 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
4243bool 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
4249Local<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
4256Maybe<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
4270Maybe<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
4286Maybe<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
4299Maybe<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
4328Maybe<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
4355struct v8::PropertyDescriptor::PrivateData {
4356  PrivateData() : desc() {}
4357  i::PropertyDescriptor desc;
4358};
4359
4360v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4361
4362// DataDescriptor
4363v8::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
4369v8::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
4377v8::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
4386v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4387
4388v8::Local<Value> v8::PropertyDescriptor::value() const {
4389  DCHECK(private_->desc.has_value());
4390  return Utils::ToLocal(private_->desc.value());
4391}
4392
4393v8::Local<Value> v8::PropertyDescriptor::get() const {
4394  DCHECK(private_->desc.has_get());
4395  return Utils::ToLocal(private_->desc.get());
4396}
4397
4398v8::Local<Value> v8::PropertyDescriptor::set() const {
4399  DCHECK(private_->desc.has_set());
4400  return Utils::ToLocal(private_->desc.set());
4401}
4402
4403bool v8::PropertyDescriptor::has_value() const {
4404  return private_->desc.has_value();
4405}
4406bool v8::PropertyDescriptor::has_get() const {
4407  return private_->desc.has_get();
4408}
4409bool v8::PropertyDescriptor::has_set() const {
4410  return private_->desc.has_set();
4411}
4412
4413bool v8::PropertyDescriptor::writable() const {
4414  DCHECK(private_->desc.has_writable());
4415  return private_->desc.writable();
4416}
4417
4418bool v8::PropertyDescriptor::has_writable() const {
4419  return private_->desc.has_writable();
4420}
4421
4422void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4423  private_->desc.set_enumerable(enumerable);
4424}
4425
4426bool v8::PropertyDescriptor::enumerable() const {
4427  DCHECK(private_->desc.has_enumerable());
4428  return private_->desc.enumerable();
4429}
4430
4431bool v8::PropertyDescriptor::has_enumerable() const {
4432  return private_->desc.has_enumerable();
4433}
4434
4435void v8::PropertyDescriptor::set_configurable(bool configurable) {
4436  private_->desc.set_configurable(configurable);
4437}
4438
4439bool v8::PropertyDescriptor::configurable() const {
4440  DCHECK(private_->desc.has_configurable());
4441  return private_->desc.configurable();
4442}
4443
4444bool v8::PropertyDescriptor::has_configurable() const {
4445  return private_->desc.has_configurable();
4446}
4447
4448Maybe<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
4483Maybe<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
4499Maybe<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
4526MaybeLocal<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
4538MaybeLocal<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
4548MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4549                                         Local<Private> key) {
4550  return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4551}
4552
4553Maybe<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
4575MaybeLocal<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
4592Local<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
4599Maybe<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
4628Local<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
4643MaybeLocal<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
4650MaybeLocal<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
4673MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4674  return GetOwnPropertyNames(
4675      context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4676}
4677
4678MaybeLocal<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
4685MaybeLocal<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
4697Local<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
4706Maybe<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
4721Maybe<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
4745Maybe<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
4761Maybe<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
4783Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4784  return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4785}
4786
4787Maybe<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
4797Maybe<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
4807template <typename Getter, typename Setter, typename Data>
4808static 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
4843Maybe<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
4856void 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
4875Maybe<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
4886Maybe<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
4897Maybe<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
4910Maybe<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
4921Maybe<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
4936Maybe<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
4950Maybe<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
4965bool 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
4971bool 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
4977MaybeLocal<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
4998Maybe<PropertyAttribute>
4999v8::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
5024MaybeLocal<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
5039Maybe<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
5060Local<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
5068namespace {
5069Local<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
5079Local<v8::Context> v8::Object::CreationContext() {
5080  auto self = Utils::OpenHandle(this);
5081  return CreationContextImpl(self);
5082}
5083
5084Local<v8::Context> v8::Object::CreationContext(
5085    const PersistentBase<Object>& object) {
5086  auto self = Utils::OpenHandle(object.val_);
5087  return CreationContextImpl(self);
5088}
5089
5090MaybeLocal<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
5099Local<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
5107int 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
5116bool v8::Object::IsCallable() const {
5117  auto self = Utils::OpenHandle(this);
5118  return self->IsCallable();
5119}
5120
5121bool v8::Object::IsConstructor() const {
5122  auto self = Utils::OpenHandle(this);
5123  return self->IsConstructor();
5124}
5125
5126bool 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
5132bool v8::Object::IsUndetectable() const {
5133  auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5134  return self->IsUndetectable();
5135}
5136
5137MaybeLocal<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
5158MaybeLocal<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
5177MaybeLocal<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
5190MaybeLocal<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
5196MaybeLocal<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
5247MaybeLocal<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
5270void 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
5278Local<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
5296Local<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
5307Local<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
5318ScriptOrigin 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
5331const int Function::kLineOffsetNotFound = -1;
5332
5333int 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
5347int 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
5361MaybeLocal<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
5369int 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
5377Local<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
5388MaybeLocal<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
5400int Name::GetIdentityHash() {
5401  auto self = Utils::OpenHandle(this);
5402  return static_cast<int>(self->EnsureHash());
5403}
5404
5405int String::Length() const {
5406  i::Handle<i::String> str = Utils::OpenHandle(this);
5407  return str->length();
5408}
5409
5410bool String::IsOneByte() const {
5411  i::Handle<i::String> str = Utils::OpenHandle(this);
5412  return str->IsOneByteRepresentation();
5413}
5414
5415// Helpers for ContainsOnlyOneByteHelper
5416template <size_t size>
5417struct OneByteMask;
5418template <>
5419struct OneByteMask<4> {
5420  static const uint32_t value = 0xFF00FF00;
5421};
5422template <>
5423struct OneByteMask<8> {
5424  static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5425};
5426static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5427static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
5428static inline bool Unaligned(const uint16_t* chars) {
5429  return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5430}
5431
5432static inline const uint16_t* Align(const uint16_t* chars) {
5433  return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5434                                     ~kAlignmentMask);
5435}
5436
5437class ContainsOnlyOneByteHelper {
5438 public:
5439  ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5440  ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5441  ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5442      delete;
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  }
5448  void VisitOneByteString(const uint8_t* chars, int length) {
5449    // Nothing to do.
5450  }
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:
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
5525bool 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
5532int 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
5556namespace {
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.
5566template <typename Char>
5567static 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
5684int 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
5702template <typename CharType>
5703static 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
5723int 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
5729int 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
5735bool v8::String::IsExternal() const {
5736  i::Handle<i::String> str = Utils::OpenHandle(this);
5737  return i::StringShape(*str).IsExternal();
5738}
5739
5740bool v8::String::IsExternalTwoByte() const {
5741  i::Handle<i::String> str = Utils::OpenHandle(this);
5742  return i::StringShape(*str).IsExternalTwoByte();
5743}
5744
5745bool v8::String::IsExternalOneByte() const {
5746  i::Handle<i::String> str = Utils::OpenHandle(this);
5747  return i::StringShape(*str).IsExternalOneByte();
5748}
5749
5750void 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
5769void 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
5797String::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
5816void String::ExternalStringResource::UpdateDataCache() {
5817  DCHECK(IsCacheable());
5818  cached_data_ = data();
5819}
5820
5821void String::ExternalStringResource::CheckCachedDataInvariants() const {
5822  DCHECK(IsCacheable() && cached_data_ != nullptr);
5823}
5824
5825void String::ExternalOneByteStringResource::UpdateDataCache() {
5826  DCHECK(IsCacheable());
5827  cached_data_ = data();
5828}
5829
5830void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5831  DCHECK(IsCacheable() && cached_data_ != nullptr);
5832}
5833
5834String::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
5860const v8::String::ExternalOneByteStringResource*
5861v8::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
5875Local<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
5882Local<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
5891double Number::Value() const {
5892  i::Handle<i::Object> obj = Utils::OpenHandle(this);
5893  return obj->Number();
5894}
5895
5896bool Boolean::Value() const {
5897  i::Handle<i::Object> obj = Utils::OpenHandle(this);
5898  return obj->IsTrue();
5899}
5900
5901int64_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
5910int32_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
5919uint32_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
5928int 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
5934static 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
5942Local<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
5951template<typename T>
5952void 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
5960void 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 */
5968void v8::Object::SetInternalFieldForNodeCore(int index,
5969                                             v8::Local<Module> value) {
5970  SetInternalFieldImpl(this, index, value);
5971}
5972
5973void v8::Object::SetInternalFieldForNodeCore(int index,
5974                                             v8::Local<UnboundScript> value) {
5975  SetInternalFieldImpl(this, index, value);
5976}
5977
5978void* 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
5989void 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
6012void 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
6046void v8::V8::InitializePlatform(Platform* platform) {
6047  i::V8::InitializePlatform(platform);
6048}
6049
6050#ifdef V8_SANDBOX
6051bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); }
6052#endif
6053
6054void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); }
6055
6056bool 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
6100bool 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
6111bool 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
6120bool 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)
6129void 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
6140void v8::V8::SetFatalMemoryErrorCallback(
6141    v8::OOMErrorCallback oom_error_callback) {
6142  g_oom_error_callback = oom_error_callback;
6143}
6144
6145void v8::V8::SetEntropySource(EntropySource entropy_source) {
6146  base::RandomNumberGenerator::SetEntropySource(entropy_source);
6147}
6148
6149void v8::V8::SetReturnAddressLocationResolver(
6150    ReturnAddressLocationResolver return_address_resolver) {
6151  i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6152}
6153
6154bool v8::V8::Dispose() {
6155  i::V8::Dispose();
6156  return true;
6157}
6158
6159SharedMemoryStatistics::SharedMemoryStatistics()
6160    : read_only_space_size_(0),
6161      read_only_space_used_size_(0),
6162      read_only_space_physical_size_(0) {}
6163
6164HeapStatistics::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
6178HeapSpaceStatistics::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
6185HeapObjectStatistics::HeapObjectStatistics()
6186    : object_type_(nullptr),
6187      object_sub_type_(nullptr),
6188      object_count_(0),
6189      object_size_(0) {}
6190
6191HeapCodeStatistics::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
6197bool v8::V8::InitializeICU(const char* icu_data_file) {
6198  return i::InitializeICU(icu_data_file);
6199}
6200
6201bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6202                                          const char* icu_data_file) {
6203  return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6204}
6205
6206void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6207  i::InitializeExternalStartupData(directory_path);
6208}
6209
6210// static
6211void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6212  i::InitializeExternalStartupDataFromFile(snapshot_blob);
6213}
6214
6215const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6216
6217#ifdef V8_SANDBOX
6218VirtualAddressSpace* 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
6225PageAllocator* 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
6232size_t v8::V8::GetSandboxSizeInBytes() {
6233  if (!i::GetProcessWideSandbox()->is_initialized()) {
6234    return 0;
6235  } else {
6236    return i::GetProcessWideSandbox()->size();
6237  }
6238}
6239
6240bool 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
6252void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6253  i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6254}
6255
6256template <typename ObjectType>
6257struct InvokeBootstrapper;
6258
6259template <>
6260struct InvokeBootstrapper<i::Context> {
6261  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
6273template <>
6274struct InvokeBootstrapper<i::JSGlobalProxy> {
6275  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
6288template <typename ObjectType>
6289static 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
6393Local<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
6420Local<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
6431MaybeLocal<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
6447MaybeLocal<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
6474void 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
6480void v8::Context::UseDefaultSecurityToken() {
6481  i::Handle<i::Context> env = Utils::OpenHandle(this);
6482  env->set_security_token(env->global_object());
6483}
6484
6485Local<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
6493v8::Isolate* Context::GetIsolate() {
6494  i::Handle<i::Context> env = Utils::OpenHandle(this);
6495  return reinterpret_cast<Isolate*>(env->GetIsolate());
6496}
6497
6498v8::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
6505v8::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
6518void 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
6525Local<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
6532void 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
6541bool Context::IsCodeGenerationFromStringsAllowed() const {
6542  i::Context context = *Utils::OpenHandle(this);
6543  return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6544}
6545
6546void 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
6552void 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
6565Local<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
6574void 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
6583void 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
6627MaybeLocal<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
6633metrics::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
6641metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6642  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6643  return *i_isolate->GetCurrentLongTaskStats();
6644}
6645
6646namespace {
6647i::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
6667i::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
6674MaybeLocal<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
6684void 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
6690void 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
6696void 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
6702void 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
6708MaybeLocal<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
6718MaybeLocal<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
6745bool 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
6764bool 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
6774Local<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
6788void* 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
6794namespace {
6795
6796inline 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
6802inline int StringLength(const uint8_t* string) {
6803  return StringLength(reinterpret_cast<const char*>(string));
6804}
6805
6806inline 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
6813V8_WARN_UNUSED_RESULT
6814inline 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
6823V8_WARN_UNUSED_RESULT
6824inline 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
6833V8_WARN_UNUSED_RESULT
6834inline 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
6843STATIC_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
6867Local<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
6880MaybeLocal<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
6886MaybeLocal<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
6892MaybeLocal<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
6899Local<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
6917MaybeLocal<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
6939MaybeLocal<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
6961bool 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
6987bool 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
7013bool 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
7028bool 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
7034Isolate* v8::Object::GetIsolate() {
7035  i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7036  return reinterpret_cast<Isolate*>(i_isolate);
7037}
7038
7039Local<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
7048namespace {
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.
7054template <typename T>
7055i::Handle<T> ToHandle(i::Handle<T> h) {
7056  return h;
7057}
7058template <typename T>
7059i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
7060  return h.ToHandleChecked();
7061}
7062
7063template <typename Dictionary>
7064void 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
7105Local<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
7146Local<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
7156double 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
7164Local<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
7174Local<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
7184Local<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
7197bool 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
7205Local<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
7216Local<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
7226Local<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
7236Local<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
7246MaybeLocal<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
7260double 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));
7273TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
7274TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7275#undef TIME_ZONE_DETECTION_ASSERT_EQ
7276
7277MaybeLocal<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
7289MaybeLocal<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
7308Local<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))
7318REGEXP_FLAG_ASSERT_EQ(kNone);
7319REGEXP_FLAG_ASSERT_EQ(kGlobal);
7320REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7321REGEXP_FLAG_ASSERT_EQ(kMultiline);
7322REGEXP_FLAG_ASSERT_EQ(kSticky);
7323REGEXP_FLAG_ASSERT_EQ(kUnicode);
7324REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7325REGEXP_FLAG_ASSERT_EQ(kLinear);
7326#undef REGEXP_FLAG_ASSERT_EQ
7327
7328v8::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
7333MaybeLocal<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
7354Local<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
7366Local<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
7384uint32_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
7394Local<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
7402size_t v8::Map::Size() const {
7403  i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7404  return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7405}
7406
7407void 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
7415MaybeLocal<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
7428MaybeLocal<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
7443Maybe<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
7457Maybe<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
7471namespace {
7472
7473enum 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
7479enum class SetAsArrayKind {
7480  kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7481  kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7482};
7483
7484i::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
7518Local<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
7527Local<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
7535size_t v8::Set::Size() const {
7536  i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7537  return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7538}
7539
7540void 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
7548MaybeLocal<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
7561Maybe<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
7575Maybe<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
7589namespace {
7590i::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
7621Local<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
7630MaybeLocal<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
7639Local<Promise> Promise::Resolver::GetPromise() {
7640  i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7641  return Local<Promise>::Cast(Utils::ToLocal(promise));
7642}
7643
7644Maybe<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
7662Maybe<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
7680MaybeLocal<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
7698MaybeLocal<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
7712MaybeLocal<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
7728bool 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
7737Local<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
7748Promise::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
7755void Promise::MarkAsHandled() {
7756  i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7757  js_promise->set_has_handler(true);
7758}
7759
7760void Promise::MarkAsSilent() {
7761  i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7762  js_promise->set_is_silent(true);
7763}
7764
7765Local<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
7771Local<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
7777bool Proxy::IsRevoked() const {
7778  i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7779  return self->IsRevoked();
7780}
7781
7782void Proxy::Revoke() {
7783  i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7784  i::JSProxy::Revoke(self);
7785}
7786
7787MaybeLocal<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
7799CompiledWasmModule::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
7807OwnedBuffer 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
7821MemorySpan<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
7830Local<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
7840CompiledWasmModule 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
7855MaybeLocal<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
7870MaybeLocal<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
7901WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7902    Isolate* isolate) {
7903  USE(isolate_);
7904}
7905
7906Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7907
7908void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7909                                                       size_t size) {}
7910
7911void WasmModuleObjectBuilderStreaming::Finish() {}
7912
7913void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7914
7915void* 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
7931v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7932  return new ArrayBufferAllocator();
7933}
7934
7935bool v8::ArrayBuffer::IsDetachable() const {
7936  return Utils::OpenHandle(this)->is_detachable();
7937}
7938
7939bool v8::ArrayBuffer::WasDetached() const {
7940  return Utils::OpenHandle(this)->was_detached();
7941}
7942
7943namespace {
7944std::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
7950void 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
7960size_t v8::ArrayBuffer::ByteLength() const {
7961  i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7962  return obj->byte_length();
7963}
7964
7965Local<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
7983Local<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
8000std::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
8017std::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
8028Local<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
8044size_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
8064bool 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
8071size_t v8::ArrayBufferView::ByteOffset() {
8072  i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8073  return obj->WasDetached() ? 0 : obj->byte_offset();
8074}
8075
8076size_t v8::ArrayBufferView::ByteLength() {
8077  i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8078  return obj->WasDetached() ? 0 : obj->byte_length();
8079}
8080
8081size_t v8::TypedArray::Length() {
8082  i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8083  return obj->WasDetached() ? 0 : obj->length();
8084}
8085
8086static_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
8129TYPED_ARRAYS(TYPED_ARRAY_NEW)
8130#undef TYPED_ARRAY_NEW
8131
8132Local<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
8143Local<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
8155size_t v8::SharedArrayBuffer::ByteLength() const {
8156  i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8157  return obj->byte_length();
8158}
8159
8160Local<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
8182Local<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
8199std::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
8216std::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
8227Local<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
8236Local<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
8243Local<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
8269WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8270
8271#undef SYMBOL_GETTER
8272#undef WELL_KNOWN_SYMBOLS
8273
8274Local<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
8284Local<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
8292Local<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
8303Local<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
8314Local<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
8325Local<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
8332Local<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
8339MaybeLocal<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
8352uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8353  i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8354  return handle->AsUint64(lossless);
8355}
8356
8357int64_t v8::BigInt::Int64Value(bool* lossless) const {
8358  i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8359  return handle->AsInt64(lossless);
8360}
8361
8362int BigInt::WordCount() const {
8363  i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8364  return handle->Words64Count();
8365}
8366
8367void 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
8373void 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
8379HeapProfiler* Isolate::GetHeapProfiler() {
8380  i::HeapProfiler* heap_profiler =
8381      reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8382  return reinterpret_cast<HeapProfiler*>(heap_profiler);
8383}
8384
8385void Isolate::SetIdle(bool is_idle) {
8386  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8387  isolate->SetIdle(is_idle);
8388}
8389
8390ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8391  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8392  return isolate->array_buffer_allocator();
8393}
8394
8395bool Isolate::InContext() {
8396  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8397  return !isolate->context().is_null();
8398}
8399
8400void Isolate::ClearKeptObjects() {
8401  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8402  isolate->ClearKeptObjects();
8403}
8404
8405v8::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
8414v8::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
8423v8::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
8429v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8430  return ThrowException(v8::Exception::Error(message));
8431}
8432
8433v8::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
8446void 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
8452void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8453                                       void* data) {
8454  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8455  isolate->heap()->RemoveGCPrologueCallback(callback, data);
8456}
8457
8458void 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
8464void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8465                                       void* data) {
8466  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8467  isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8468}
8469
8470static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8471                                      GCCallbackFlags flags, void* data) {
8472  reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8473}
8474
8475void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8476  void* data = reinterpret_cast<void*>(callback);
8477  AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8478}
8479
8480void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8481  void* data = reinterpret_cast<void*>(callback);
8482  RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8483}
8484
8485void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8486  void* data = reinterpret_cast<void*>(callback);
8487  AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8488}
8489
8490void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8491  void* data = reinterpret_cast<void*>(callback);
8492  RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8493}
8494
8495void 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
8501EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8502  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8503  return isolate->heap()->GetEmbedderHeapTracer();
8504}
8505
8506void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8507  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8508  isolate->heap()->SetEmbedderRootsHandler(handler);
8509}
8510
8511void 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
8517void Isolate::DetachCppHeap() {
8518  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8519  isolate->heap()->DetachCppHeap();
8520}
8521
8522CppHeap* Isolate::GetCppHeap() const {
8523  const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8524  return isolate->heap()->cpp_heap();
8525}
8526
8527void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8528    GetExternallyAllocatedMemoryInBytesCallback callback) {
8529  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8530  isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8531}
8532
8533void Isolate::TerminateExecution() {
8534  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8535  isolate->stack_guard()->RequestTerminateExecution();
8536}
8537
8538bool Isolate::IsExecutionTerminating() {
8539  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8540  return IsExecutionTerminatingCheck(isolate);
8541}
8542
8543void Isolate::CancelTerminateExecution() {
8544  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8545  isolate->stack_guard()->ClearTerminateExecution();
8546  isolate->CancelTerminateExecution();
8547}
8548
8549void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8550  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8551  isolate->RequestInterrupt(callback, data);
8552}
8553
8554bool 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
8563void 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
8579void 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
8591Isolate* Isolate::GetCurrent() {
8592  i::Isolate* isolate = i::Isolate::Current();
8593  return reinterpret_cast<Isolate*>(isolate);
8594}
8595
8596Isolate* Isolate::TryGetCurrent() {
8597  i::Isolate* isolate = i::Isolate::TryGetCurrent();
8598  return reinterpret_cast<Isolate*>(isolate);
8599}
8600
8601bool Isolate::IsCurrent() const {
8602  return reinterpret_cast<const i::Isolate*>(this)->IsCurrent();
8603}
8604
8605// static
8606Isolate* Isolate::Allocate() {
8607  return reinterpret_cast<Isolate*>(i::Isolate::New());
8608}
8609
8610Isolate::CreateParams::CreateParams() = default;
8611
8612Isolate::CreateParams::~CreateParams() = default;
8613
8614// static
8615// This is separate so that tests can provide a different |isolate|.
8616void 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
8712Isolate* Isolate::New(const Isolate::CreateParams& params) {
8713  Isolate* isolate = Allocate();
8714  Initialize(isolate, params);
8715  return isolate;
8716}
8717
8718void 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
8727void Isolate::DumpAndResetStats() {
8728  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8729  isolate->DumpAndResetStats();
8730}
8731
8732void Isolate::DiscardThreadSpecificMetadata() {
8733  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8734  isolate->DiscardPerThreadDataForThisThread();
8735}
8736
8737void Isolate::Enter() {
8738  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8739  isolate->Enter();
8740}
8741
8742void Isolate::Exit() {
8743  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8744  isolate->Exit();
8745}
8746
8747void Isolate::SetAbortOnUncaughtExceptionCallback(
8748    AbortOnUncaughtExceptionCallback callback) {
8749  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8750  isolate->SetAbortOnUncaughtExceptionCallback(callback);
8751}
8752
8753void Isolate::SetHostImportModuleDynamicallyCallback(
8754    HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8755  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8756  isolate->SetHostImportModuleDynamicallyCallback(callback);
8757}
8758
8759void Isolate::SetHostImportModuleDynamicallyCallback(
8760    HostImportModuleDynamicallyCallback callback) {
8761  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8762  isolate->SetHostImportModuleDynamicallyCallback(callback);
8763}
8764
8765void Isolate::SetHostInitializeImportMetaObjectCallback(
8766    HostInitializeImportMetaObjectCallback callback) {
8767  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8768  isolate->SetHostInitializeImportMetaObjectCallback(callback);
8769}
8770
8771void Isolate::SetHostCreateShadowRealmContextCallback(
8772    HostCreateShadowRealmContextCallback callback) {
8773  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8774  isolate->SetHostCreateShadowRealmContextCallback(callback);
8775}
8776
8777void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8778  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8779  isolate->SetPrepareStackTraceCallback(callback);
8780}
8781
8782Isolate::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
8805Isolate::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
8825Isolate::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
8835Isolate::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
8843Isolate::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
8853Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8854  microtask_queue_->DecrementMicrotasksSuppressions();
8855  isolate_->thread_local_top()->DecrementCallDepth(this);
8856}
8857
8858Isolate::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
8864Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8865  isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8866}
8867
8868i::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
8874void 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
8936size_t Isolate::NumberOfHeapSpaces() {
8937  return i::LAST_SPACE - i::FIRST_SPACE + 1;
8938}
8939
8940bool 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
8977size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8978  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8979  i::Heap* heap = isolate->heap();
8980  return heap->NumberOfTrackedHeapObjectTypes();
8981}
8982
8983bool 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
9010bool 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
9029bool 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
9035std::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
9047void 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
9061size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
9062  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9063  return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
9064}
9065
9066int64_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
9087void 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
9094void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
9095  if (callback == nullptr) return;
9096  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9097  isolate->AddBeforeCallEnteredCallback(callback);
9098}
9099
9100void Isolate::RemoveBeforeCallEnteredCallback(
9101    BeforeCallEnteredCallback callback) {
9102  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9103  isolate->RemoveBeforeCallEnteredCallback(callback);
9104}
9105
9106void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
9107  if (callback == nullptr) return;
9108  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9109  isolate->AddCallCompletedCallback(callback);
9110}
9111
9112void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
9113  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9114  isolate->RemoveCallCompletedCallback(callback);
9115}
9116
9117void Isolate::AtomicsWaitWakeHandle::Wake() {
9118  reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
9119}
9120
9121void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
9122  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9123  isolate->SetAtomicsWaitCallback(callback, data);
9124}
9125
9126void Isolate::SetPromiseHook(PromiseHook hook) {
9127  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9128  isolate->SetPromiseHook(hook);
9129}
9130
9131void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
9132  if (callback == nullptr) return;
9133  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9134  isolate->SetPromiseRejectCallback(callback);
9135}
9136
9137void 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
9143void 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
9154void 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
9159void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9160  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9161  isolate->default_microtask_queue()->set_microtasks_policy(policy);
9162}
9163
9164MicrotasksPolicy 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
9170void 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
9178void 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
9185void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9186  reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9187}
9188
9189void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9190  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9191  isolate->counters()->ResetCounterFunction(callback);
9192}
9193
9194void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9195  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9196  isolate->counters()->ResetCreateHistogramFunction(callback);
9197}
9198
9199void Isolate::SetAddHistogramSampleFunction(
9200    AddHistogramSampleCallback callback) {
9201  reinterpret_cast<i::Isolate*>(this)
9202      ->counters()
9203      ->SetAddHistogramSampleFunction(callback);
9204}
9205
9206void 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
9212void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
9213  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9214  isolate->SetAddCrashKeyCallback(callback);
9215}
9216
9217bool 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
9225void 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
9236int 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
9254void Isolate::IsolateInForegroundNotification() {
9255  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9256  return isolate->IsolateInForegroundNotification();
9257}
9258
9259void Isolate::IsolateInBackgroundNotification() {
9260  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9261  return isolate->IsolateInBackgroundNotification();
9262}
9263
9264void 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
9273void Isolate::ClearCachesForTesting() {
9274  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9275  isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9276  isolate->ClearSerializerData();
9277}
9278
9279void Isolate::EnableMemorySavingsMode() {
9280  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9281  isolate->EnableMemorySavingsMode();
9282}
9283
9284void Isolate::DisableMemorySavingsMode() {
9285  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9286  isolate->DisableMemorySavingsMode();
9287}
9288
9289void Isolate::SetRAILMode(RAILMode rail_mode) {
9290  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9291  return isolate->SetRAILMode(rail_mode);
9292}
9293
9294void Isolate::UpdateLoadStartTime() {
9295  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9296  isolate->UpdateLoadStartTime();
9297}
9298
9299void Isolate::IncreaseHeapLimitForDebugging() {
9300  // No-op.
9301}
9302
9303void Isolate::RestoreOriginalHeapLimit() {
9304  // No-op.
9305}
9306
9307bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9308
9309void 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
9317void 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
9323void 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
9330void 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
9338JSEntryStubs 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
9357size_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
9386CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9387CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9388CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9389                ModifyCodeGenerationFromStringsCallback2,
9390                modify_code_gen_callback2)
9391CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9392                AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9393
9394CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9395CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9396
9397CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9398                wasm_streaming_callback)
9399
9400CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9401                wasm_load_source_map_callback)
9402
9403CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9404                wasm_simd_enabled_callback)
9405
9406CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9407                wasm_exceptions_enabled_callback)
9408
9409CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9410                WasmDynamicTieringEnabledCallback,
9411                wasm_dynamic_tiering_enabled_callback)
9412
9413CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9414                SharedArrayBufferConstructorEnabledCallback,
9415                sharedarraybuffer_constructor_enabled_callback)
9416
9417void 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
9429void 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
9435void 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
9441void 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
9448bool Isolate::IsDead() {
9449  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9450  return isolate->IsDead();
9451}
9452
9453bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9454  return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9455}
9456
9457bool 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
9476void 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
9492void Isolate::SetFailedAccessCheckCallbackFunction(
9493    FailedAccessCheckCallback callback) {
9494  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9495  isolate->SetFailedAccessCheckCallback(callback);
9496}
9497
9498void 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
9505void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9506  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9507  isolate->heap()->VisitExternalResources(visitor);
9508}
9509
9510bool Isolate::IsInUse() {
9511  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9512  return isolate->IsInUse();
9513}
9514
9515void 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
9521void 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
9527void Isolate::SetAllowAtomicsWait(bool allow) {
9528  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9529  isolate->set_allow_atomics_wait(allow);
9530}
9531
9532void 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
9549void 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
9559bool 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
9568std::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
9577MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9578    : MicrotasksScope(isolate, nullptr, type) {}
9579
9580MicrotasksScope::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
9594MicrotasksScope::~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
9611void 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
9618int 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
9625bool 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
9631String::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
9646String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9647
9648String::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
9663String::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
9681DEFINE_ERROR(RangeError, range_error)
9682DEFINE_ERROR(ReferenceError, reference_error)
9683DEFINE_ERROR(SyntaxError, syntax_error)
9684DEFINE_ERROR(TypeError, type_error)
9685DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9686DEFINE_ERROR(WasmLinkError, wasm_link_error)
9687DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9688DEFINE_ERROR(Error, error)
9689
9690#undef DEFINE_ERROR
9691
9692Local<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
9702Local<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
9711v8::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
9751Local<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
9760const char* CpuProfileNode::GetFunctionNameStr() const {
9761  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9762  return node->entry()->name();
9763}
9764
9765int 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
9771Local<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
9778const char* CpuProfileNode::GetScriptResourceNameStr() const {
9779  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9780  return node->entry()->resource_name();
9781}
9782
9783bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9784  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9785  return node->entry()->is_shared_cross_origin();
9786}
9787
9788int CpuProfileNode::GetLineNumber() const {
9789  return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9790}
9791
9792int CpuProfileNode::GetColumnNumber() const {
9793  return reinterpret_cast<const i::ProfileNode*>(this)
9794      ->entry()
9795      ->column_number();
9796}
9797
9798unsigned int CpuProfileNode::GetHitLineCount() const {
9799  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9800  return node->GetHitLineCount();
9801}
9802
9803bool 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
9809const char* CpuProfileNode::GetBailoutReason() const {
9810  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9811  return node->entry()->bailout_reason();
9812}
9813
9814unsigned CpuProfileNode::GetHitCount() const {
9815  return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9816}
9817
9818unsigned CpuProfileNode::GetNodeId() const {
9819  return reinterpret_cast<const i::ProfileNode*>(this)->id();
9820}
9821
9822CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9823  return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9824}
9825
9826int CpuProfileNode::GetChildrenCount() const {
9827  return static_cast<int>(
9828      reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9829}
9830
9831const 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
9837const 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
9843const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9844  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9845  return node->deopt_infos();
9846}
9847
9848void 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
9855Local<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
9862const 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
9867const 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
9872const int CpuProfileNode::kNoLineNumberInfo;
9873const int CpuProfileNode::kNoColumnNumberInfo;
9874
9875int64_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
9880StateTag 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
9885EmbedderStateTag 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
9890int64_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
9895int64_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
9900static i::CpuProfile* ToInternal(const CpuProfile* profile) {
9901  return const_cast<i::CpuProfile*>(
9902      reinterpret_cast<const i::CpuProfile*>(profile));
9903}
9904
9905void 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
9915int CpuProfile::GetSamplesCount() const {
9916  return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9917}
9918
9919CpuProfiler* 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
9926CpuProfilingOptions::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
9941void* 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
9948void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9949
9950// static
9951void CpuProfiler::CollectSample(Isolate* isolate) {
9952  i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
9953}
9954
9955void 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
9961void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
9962  reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
9963      use_precise_sampling);
9964}
9965
9966CpuProfilingResult 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
9973CpuProfilingResult 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
9980CpuProfilingResult 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
9989CpuProfilingResult 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
9998CpuProfilingStatus 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
10004CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10005                                               bool record_samples) {
10006  return Start(title, record_samples).status;
10007}
10008
10009CpuProfilingStatus 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
10016CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
10017  return reinterpret_cast<CpuProfile*>(
10018      reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
10019          *Utils::OpenHandle(*title)));
10020}
10021
10022CpuProfile* CpuProfiler::Stop(ProfilerId id) {
10023  return reinterpret_cast<CpuProfile*>(
10024      reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id));
10025}
10026
10027void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
10028  reinterpret_cast<i::Isolate*>(isolate)
10029      ->SetDetailedSourcePositionsForProfiling(true);
10030}
10031
10032uintptr_t CodeEvent::GetCodeStartAddress() {
10033  return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10034}
10035
10036size_t CodeEvent::GetCodeSize() {
10037  return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10038}
10039
10040Local<String> CodeEvent::GetFunctionName() {
10041  return ToApiHandle<String>(
10042      reinterpret_cast<i::CodeEvent*>(this)->function_name);
10043}
10044
10045Local<String> CodeEvent::GetScriptName() {
10046  return ToApiHandle<String>(
10047      reinterpret_cast<i::CodeEvent*>(this)->script_name);
10048}
10049
10050int CodeEvent::GetScriptLine() {
10051  return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10052}
10053
10054int CodeEvent::GetScriptColumn() {
10055  return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10056}
10057
10058CodeEventType CodeEvent::GetCodeType() {
10059  return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10060}
10061
10062const char* CodeEvent::GetComment() {
10063  return reinterpret_cast<i::CodeEvent*>(this)->comment;
10064}
10065
10066uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10067  return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10068}
10069
10070const 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
10084CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10085  internal_listener_ =
10086      new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10087}
10088
10089CodeEventHandler::~CodeEventHandler() {
10090  delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10091}
10092
10093void CodeEventHandler::Enable() {
10094  reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10095      ->StartListening(this);
10096}
10097
10098void CodeEventHandler::Disable() {
10099  reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10100      ->StopListening();
10101}
10102
10103static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10104  return const_cast<i::HeapGraphEdge*>(
10105      reinterpret_cast<const i::HeapGraphEdge*>(edge));
10106}
10107
10108HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10109  return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10110}
10111
10112Local<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
10132const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10133  const i::HeapEntry* from = ToInternal(this)->from();
10134  return reinterpret_cast<const HeapGraphNode*>(from);
10135}
10136
10137const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10138  const i::HeapEntry* to = ToInternal(this)->to();
10139  return reinterpret_cast<const HeapGraphNode*>(to);
10140}
10141
10142static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10143  return const_cast<i::HeapEntry*>(
10144      reinterpret_cast<const i::HeapEntry*>(entry));
10145}
10146
10147HeapGraphNode::Type HeapGraphNode::GetType() const {
10148  return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10149}
10150
10151Local<String> HeapGraphNode::GetName() const {
10152  i::Isolate* isolate = ToInternal(this)->isolate();
10153  return ToApiHandle<String>(
10154      isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10155}
10156
10157SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10158
10159size_t HeapGraphNode::GetShallowSize() const {
10160  return ToInternal(this)->self_size();
10161}
10162
10163int HeapGraphNode::GetChildrenCount() const {
10164  return ToInternal(this)->children_count();
10165}
10166
10167const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10168  return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10169}
10170
10171static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10172  return const_cast<i::HeapSnapshot*>(
10173      reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10174}
10175
10176void 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
10187const HeapGraphNode* HeapSnapshot::GetRoot() const {
10188  return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10189}
10190
10191const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10192  return reinterpret_cast<const HeapGraphNode*>(
10193      ToInternal(this)->GetEntryById(id));
10194}
10195
10196int HeapSnapshot::GetNodesCount() const {
10197  return static_cast<int>(ToInternal(this)->entries().size());
10198}
10199
10200const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10201  return reinterpret_cast<const HeapGraphNode*>(
10202      &ToInternal(this)->entries().at(index));
10203}
10204
10205SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10206  return ToInternal(this)->max_snapshot_js_object_id();
10207}
10208
10209void 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
10220STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10221    HeapProfiler::kUnknownObjectId;
10222
10223int HeapProfiler::GetSnapshotCount() {
10224  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10225}
10226
10227const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10228  return reinterpret_cast<const HeapSnapshot*>(
10229      reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10230}
10231
10232SnapshotObjectId 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
10237SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10238  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10239}
10240
10241Local<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
10248void HeapProfiler::ClearObjectIds() {
10249  reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10250}
10251
10252const 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
10261void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10262  reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10263      track_allocations);
10264}
10265
10266void HeapProfiler::StopTrackingHeapObjects() {
10267  reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10268}
10269
10270SnapshotObjectId 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
10276bool 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
10283void HeapProfiler::StopSamplingHeapProfiler() {
10284  reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10285}
10286
10287AllocationProfile* HeapProfiler::GetAllocationProfile() {
10288  return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10289}
10290
10291void HeapProfiler::DeleteAllHeapSnapshots() {
10292  reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10293}
10294
10295void HeapProfiler::AddBuildEmbedderGraphCallback(
10296    BuildEmbedderGraphCallback callback, void* data) {
10297  reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10298      callback, data);
10299}
10300
10301void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10302    BuildEmbedderGraphCallback callback, void* data) {
10303  reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10304      callback, data);
10305}
10306
10307void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10308                                              void* data) {
10309  reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10310                                                                       data);
10311}
10312
10313void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10314  CHECK(isolate_);
10315  reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10316      stack_start);
10317}
10318
10319void 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
10329void 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
10340void 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
10351void 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
10360void 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
10367bool EmbedderHeapTracer::IsRootForNonTracingGC(
10368    const v8::TracedReference<v8::Value>& handle) {
10369  return true;
10370}
10371
10372void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10373    const v8::TracedReference<v8::Value>& handle) {
10374  UNREACHABLE();
10375}
10376
10377EmbedderStateScope::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.
10385EmbedderStateScope::~EmbedderStateScope() = default;
10386
10387void 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
10395CFunction::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
10401CFunctionInfo::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
10411const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10412  DCHECK_LT(index, ArgumentCount());
10413  return arg_info_[index];
10414}
10415
10416void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10417  DCHECK_LT(index, length_);
10418}
10419
10420RegisterState::RegisterState()
10421    : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10422RegisterState::~RegisterState() = default;
10423
10424RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10425
10426RegisterState& 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
10449class WasmStreaming::WasmStreamingImpl {};
10450
10451WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10452  UNREACHABLE();
10453}
10454
10455WasmStreaming::~WasmStreaming() = default;
10456
10457void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10458  UNREACHABLE();
10459}
10460
10461void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); }
10462
10463void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10464
10465bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10466  UNREACHABLE();
10467}
10468
10469void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10470
10471void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10472
10473// static
10474std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10475                                                     Local<Value> value) {
10476  FATAL("WebAssembly is disabled");
10477}
10478#endif  // !V8_ENABLE_WEBASSEMBLY
10479
10480namespace internal {
10481
10482const size_t HandleScopeImplementer::kEnteredContextsOffset =
10483    offsetof(HandleScopeImplementer, entered_contexts_);
10484const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10485    offsetof(HandleScopeImplementer, is_microtask_context_);
10486
10487void HandleScopeImplementer::FreeThreadResources() { Free(); }
10488
10489char* 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
10500int HandleScopeImplementer::ArchiveSpacePerThread() {
10501  return sizeof(HandleScopeImplementer);
10502}
10503
10504char* HandleScopeImplementer::RestoreThread(char* storage) {
10505  MemCopy(this, storage, sizeof(*this));
10506  *isolate_->handle_scope_data() = handle_scope_data_;
10507  return storage + ArchiveSpacePerThread();
10508}
10509
10510void 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
10562void HandleScopeImplementer::Iterate(RootVisitor* v) {
10563  HandleScopeData* current = isolate_->handle_scope_data();
10564  handle_scope_data_ = *current;
10565  IterateThis(v);
10566}
10567
10568char* 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
10575std::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
10612void HandleScopeImplementer::BeginDeferredScope() {
10613  DCHECK_NULL(last_handle_before_deferred_block_);
10614  last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10615}
10616
10617void 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
10629void 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
10638void 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
10662template <>
10663EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10664int32_t ConvertDouble(double d) {
10665  return internal::DoubleToInt32(d);
10666}
10667
10668template <>
10669EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10670uint32_t ConvertDouble(double d) {
10671  return internal::DoubleToUint32(d);
10672}
10673
10674template <>
10675EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10676float ConvertDouble(double d) {
10677  return internal::DoubleToFloat32(d);
10678}
10679
10680template <>
10681EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10682double ConvertDouble(double d) {
10683  return d;
10684}
10685
10686template <>
10687EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10688int64_t ConvertDouble(double d) {
10689  return internal::DoubleToWebIDLInt64(d);
10690}
10691
10692template <>
10693EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10694uint64_t ConvertDouble(double d) {
10695  return internal::DoubleToWebIDLUint64(d);
10696}
10697
10698template <>
10699EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10700bool 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
10712template <>
10713bool V8_EXPORT V8_WARN_UNUSED_RESULT
10714TryToCopyAndConvertArrayToCppBuffer<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
10723template <>
10724bool V8_EXPORT V8_WARN_UNUSED_RESULT
10725TryToCopyAndConvertArrayToCppBuffer<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
10734template <>
10735bool V8_EXPORT V8_WARN_UNUSED_RESULT
10736TryToCopyAndConvertArrayToCppBuffer<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
10745template <>
10746bool V8_EXPORT V8_WARN_UNUSED_RESULT
10747TryToCopyAndConvertArrayToCppBuffer<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