• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/api/api.h"
6 
7 #include <algorithm>  // For min
8 #include <cmath>      // For isnan.
9 #include <limits>
10 #include <sstream>
11 #include <string>
12 #include <utility>  // For move
13 #include <vector>
14 
15 #include "include/v8-callbacks.h"
16 #include "include/v8-cppgc.h"
17 #include "include/v8-date.h"
18 #include "include/v8-embedder-state-scope.h"
19 #include "include/v8-extension.h"
20 #include "include/v8-fast-api-calls.h"
21 #include "include/v8-function.h"
22 #include "include/v8-json.h"
23 #include "include/v8-locker.h"
24 #include "include/v8-primitive-object.h"
25 #include "include/v8-profiler.h"
26 #include "include/v8-unwinder-state.h"
27 #include "include/v8-util.h"
28 #include "include/v8-wasm.h"
29 #include "src/api/api-inl.h"
30 #include "src/api/api-natives.h"
31 #include "src/base/functional.h"
32 #include "src/base/logging.h"
33 #include "src/base/platform/platform.h"
34 #include "src/base/platform/time.h"
35 #include "src/base/safe_conversions.h"
36 #include "src/base/utils/random-number-generator.h"
37 #include "src/baseline/baseline-batch-compiler.h"
38 #include "src/builtins/accessors.h"
39 #include "src/builtins/builtins-utils.h"
40 #include "src/codegen/compiler.h"
41 #include "src/codegen/cpu-features.h"
42 #include "src/codegen/script-details.h"
43 #include "src/common/assert-scope.h"
44 #include "src/common/globals.h"
45 #include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
46 #include "src/date/date.h"
47 #include "src/objects/primitive-heap-object.h"
48 #if V8_ENABLE_WEBASSEMBLY
49 #include "src/debug/debug-wasm-objects.h"
50 #endif  // V8_ENABLE_WEBASSEMBLY
51 #include "src/debug/liveedit.h"
52 #include "src/deoptimizer/deoptimizer.h"
53 #include "src/execution/embedder-state.h"
54 #include "src/execution/execution.h"
55 #include "src/execution/frames-inl.h"
56 #include "src/execution/isolate-inl.h"
57 #include "src/execution/messages.h"
58 #include "src/execution/microtask-queue.h"
59 #include "src/execution/simulator.h"
60 #include "src/execution/v8threads.h"
61 #include "src/execution/vm-state-inl.h"
62 #include "src/handles/global-handles.h"
63 #include "src/handles/persistent-handles.h"
64 #include "src/heap/embedder-tracing.h"
65 #include "src/heap/heap-inl.h"
66 #include "src/heap/heap-write-barrier.h"
67 #include "src/heap/safepoint.h"
68 #include "src/init/bootstrapper.h"
69 #include "src/init/icu_util.h"
70 #include "src/init/startup-data-util.h"
71 #include "src/init/v8.h"
72 #include "src/json/json-parser.h"
73 #include "src/json/json-stringifier.h"
74 #include "src/logging/counters-scopes.h"
75 #include "src/logging/metrics.h"
76 #include "src/logging/runtime-call-stats-scope.h"
77 #include "src/logging/tracing-flags.h"
78 #include "src/numbers/conversions-inl.h"
79 #include "src/objects/api-callbacks.h"
80 #include "src/objects/contexts.h"
81 #include "src/objects/embedder-data-array-inl.h"
82 #include "src/objects/embedder-data-slot-inl.h"
83 #include "src/objects/hash-table-inl.h"
84 #include "src/objects/heap-object.h"
85 #include "src/objects/js-array-buffer-inl.h"
86 #include "src/objects/js-array-inl.h"
87 #include "src/objects/js-collection-inl.h"
88 #include "src/objects/js-promise-inl.h"
89 #include "src/objects/js-regexp-inl.h"
90 #include "src/objects/js-weak-refs-inl.h"
91 #include "src/objects/module-inl.h"
92 #include "src/objects/objects-inl.h"
93 #include "src/objects/oddball.h"
94 #include "src/objects/ordered-hash-table-inl.h"
95 #include "src/objects/property-descriptor.h"
96 #include "src/objects/property-details.h"
97 #include "src/objects/property.h"
98 #include "src/objects/prototype.h"
99 #include "src/objects/shared-function-info.h"
100 #include "src/objects/slots.h"
101 #include "src/objects/smi.h"
102 #include "src/objects/synthetic-module-inl.h"
103 #include "src/objects/templates.h"
104 #include "src/objects/value-serializer.h"
105 #include "src/parsing/parse-info.h"
106 #include "src/parsing/parser.h"
107 #include "src/parsing/pending-compilation-error-handler.h"
108 #include "src/parsing/scanner-character-streams.h"
109 #include "src/profiler/cpu-profiler.h"
110 #include "src/profiler/heap-profiler.h"
111 #include "src/profiler/heap-snapshot-generator-inl.h"
112 #include "src/profiler/profile-generator-inl.h"
113 #include "src/profiler/tick-sample.h"
114 #include "src/regexp/regexp-utils.h"
115 #include "src/runtime/runtime.h"
116 #include "src/sandbox/external-pointer.h"
117 #include "src/sandbox/sandbox.h"
118 #include "src/snapshot/code-serializer.h"
119 #include "src/snapshot/embedded/embedded-data.h"
120 #include "src/snapshot/snapshot.h"
121 #include "src/snapshot/startup-serializer.h"  // For SerializedHandleChecker.
122 #include "src/strings/char-predicates-inl.h"
123 #include "src/strings/string-hasher.h"
124 #include "src/strings/unicode-inl.h"
125 #include "src/tracing/trace-event.h"
126 #include "src/utils/detachable-vector.h"
127 #include "src/utils/version.h"
128 #include "src/web-snapshot/web-snapshot.h"
129 
130 #if V8_ENABLE_WEBASSEMBLY
131 #include "src/trap-handler/trap-handler.h"
132 #include "src/wasm/streaming-decoder.h"
133 #include "src/wasm/value-type.h"
134 #include "src/wasm/wasm-engine.h"
135 #include "src/wasm/wasm-js.h"
136 #include "src/wasm/wasm-objects-inl.h"
137 #include "src/wasm/wasm-result.h"
138 #include "src/wasm/wasm-serialization.h"
139 #endif  // V8_ENABLE_WEBASSEMBLY
140 
141 #if V8_OS_LINUX || V8_OS_DARWIN || V8_OS_FREEBSD
142 #include <signal.h>
143 #include "include/v8-wasm-trap-handler-posix.h"
144 #include "src/trap-handler/handler-inside-posix.h"
145 #endif
146 
147 #if V8_OS_WIN
148 #include <windows.h>
149 
150 // This has to come after windows.h.
151 #include <versionhelpers.h>
152 
153 #include "include/v8-wasm-trap-handler-win.h"
154 #include "src/trap-handler/handler-inside-win.h"
155 #if defined(V8_OS_WIN64)
156 #include "src/base/platform/wrappers.h"
157 #include "src/diagnostics/unwinding-info-win64.h"
158 #endif  // V8_OS_WIN64
159 #endif  // V8_OS_WIN
160 
161 // Has to be the last include (doesn't have include guards):
162 #include "src/api/api-macros.h"
163 
164 #define TRACE_BS(...)                                     \
165   do {                                                    \
166     if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \
167   } while (false)
168 
169 namespace v8 {
170 
171 static OOMErrorCallback g_oom_error_callback = nullptr;
172 
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)173 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
174                                              i::Handle<i::Script> script) {
175   i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
176   i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
177   i::Handle<i::Object> host_defined_options(script->host_defined_options(),
178                                             isolate);
179   ScriptOriginOptions options(script->origin_options());
180   bool is_wasm = false;
181 #if V8_ENABLE_WEBASSEMBLY
182   is_wasm = script->type() == i::Script::TYPE_WASM;
183 #endif  // V8_ENABLE_WEBASSEMBLY
184   v8::ScriptOrigin origin(
185       reinterpret_cast<v8::Isolate*>(isolate), Utils::ToLocal(scriptName),
186       script->line_offset(), script->column_offset(),
187       options.IsSharedCrossOrigin(), script->id(),
188       Utils::ToLocal(source_map_url), options.IsOpaque(), is_wasm,
189       options.IsModule(), Utils::ToLocal(host_defined_options));
190   return origin;
191 }
192 
HostDefinedOptions() const193 Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
194   // TODO(cbruni, chromium:1244145): remove once migrated to the context.
195   Utils::ApiCheck(!host_defined_options_->IsFixedArray(),
196                   "ScriptOrigin::HostDefinedOptions",
197                   "HostDefinedOptions is not a PrimitiveArray, please use "
198                   "ScriptOrigin::GetHostDefinedOptions()");
199   i::Handle<i::FixedArray> options =
200       Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
201   return Utils::PrimitiveArrayToLocal(options);
202 }
203 
204 // --- E x c e p t i o n   B e h a v i o r ---
205 
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location)206 void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
207   i::V8::FatalProcessOutOfMemory(isolate, location, false);
208 }
209 
210 // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
211 // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location,bool is_heap_oom)212 void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
213                                     bool is_heap_oom) {
214   char last_few_messages[Heap::kTraceRingBufferSize + 1];
215   char js_stacktrace[Heap::kStacktraceBufferSize + 1];
216   i::HeapStats heap_stats;
217 
218   if (isolate == nullptr) {
219     isolate = Isolate::TryGetCurrent();
220   }
221 
222   if (isolate == nullptr) {
223     // If the Isolate is not available for the current thread we cannot retrieve
224     // memory information from the Isolate. Write easy-to-recognize values on
225     // the stack.
226     memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
227     memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
228     memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
229     // Give the embedder a chance to handle the condition. If it doesn't,
230     // just crash.
231     if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
232     FATAL("Fatal process out of memory: %s", location);
233     UNREACHABLE();
234   }
235 
236   memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
237   memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
238 
239   intptr_t start_marker;
240   heap_stats.start_marker = &start_marker;
241   size_t ro_space_size;
242   heap_stats.ro_space_size = &ro_space_size;
243   size_t ro_space_capacity;
244   heap_stats.ro_space_capacity = &ro_space_capacity;
245   size_t new_space_size;
246   heap_stats.new_space_size = &new_space_size;
247   size_t new_space_capacity;
248   heap_stats.new_space_capacity = &new_space_capacity;
249   size_t old_space_size;
250   heap_stats.old_space_size = &old_space_size;
251   size_t old_space_capacity;
252   heap_stats.old_space_capacity = &old_space_capacity;
253   size_t code_space_size;
254   heap_stats.code_space_size = &code_space_size;
255   size_t code_space_capacity;
256   heap_stats.code_space_capacity = &code_space_capacity;
257   size_t map_space_size;
258   heap_stats.map_space_size = &map_space_size;
259   size_t map_space_capacity;
260   heap_stats.map_space_capacity = &map_space_capacity;
261   size_t lo_space_size;
262   heap_stats.lo_space_size = &lo_space_size;
263   size_t code_lo_space_size;
264   heap_stats.code_lo_space_size = &code_lo_space_size;
265   size_t global_handle_count;
266   heap_stats.global_handle_count = &global_handle_count;
267   size_t weak_global_handle_count;
268   heap_stats.weak_global_handle_count = &weak_global_handle_count;
269   size_t pending_global_handle_count;
270   heap_stats.pending_global_handle_count = &pending_global_handle_count;
271   size_t near_death_global_handle_count;
272   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
273   size_t free_global_handle_count;
274   heap_stats.free_global_handle_count = &free_global_handle_count;
275   size_t memory_allocator_size;
276   heap_stats.memory_allocator_size = &memory_allocator_size;
277   size_t memory_allocator_capacity;
278   heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
279   size_t malloced_memory;
280   heap_stats.malloced_memory = &malloced_memory;
281   size_t malloced_peak_memory;
282   heap_stats.malloced_peak_memory = &malloced_peak_memory;
283   size_t objects_per_type[LAST_TYPE + 1] = {0};
284   heap_stats.objects_per_type = objects_per_type;
285   size_t size_per_type[LAST_TYPE + 1] = {0};
286   heap_stats.size_per_type = size_per_type;
287   int os_error;
288   heap_stats.os_error = &os_error;
289   heap_stats.last_few_messages = last_few_messages;
290   heap_stats.js_stacktrace = js_stacktrace;
291   intptr_t end_marker;
292   heap_stats.end_marker = &end_marker;
293   if (isolate->heap()->HasBeenSetUp()) {
294     // BUG(1718): Don't use the take_snapshot since we don't support
295     // HeapObjectIterator here without doing a special GC.
296     isolate->heap()->RecordStats(&heap_stats, false);
297     if (!FLAG_correctness_fuzzer_suppressions) {
298       char* first_newline = strchr(last_few_messages, '\n');
299       if (first_newline == nullptr || first_newline[1] == '\0')
300         first_newline = last_few_messages;
301       base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline);
302       base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
303     }
304   }
305   Utils::ReportOOMFailure(isolate, location, is_heap_oom);
306   if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
307   // If the fatal error handler returns, we stop execution.
308   FATAL("API fatal error handler returned after process out of memory");
309 }
310 
ReportApiFailure(const char * location,const char * message)311 void Utils::ReportApiFailure(const char* location, const char* message) {
312   i::Isolate* isolate = i::Isolate::TryGetCurrent();
313   FatalErrorCallback callback = nullptr;
314   if (isolate != nullptr) {
315     callback = isolate->exception_behavior();
316   }
317   if (callback == nullptr) {
318     base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
319                          message);
320     base::OS::Abort();
321   } else {
322     callback(location, message);
323   }
324   isolate->SignalFatalError();
325 }
326 
ReportOOMFailure(i::Isolate * isolate,const char * location,bool is_heap_oom)327 void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location,
328                              bool is_heap_oom) {
329   OOMErrorCallback oom_callback = isolate->oom_behavior();
330   if (oom_callback == nullptr) {
331     // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
332     // crbug.com/614440.
333     FatalErrorCallback fatal_callback = isolate->exception_behavior();
334     if (fatal_callback == nullptr) {
335       base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
336                            is_heap_oom ? "javascript" : "process", location);
337 #ifdef V8_FUZZILLI
338       exit(0);
339 #else
340       base::OS::Abort();
341 #endif  // V8_FUZZILLI
342     } else {
343       fatal_callback(location,
344                      is_heap_oom
345                          ? "Allocation failed - JavaScript heap out of memory"
346                          : "Allocation failed - process out of memory");
347     }
348   } else {
349     oom_callback(location, is_heap_oom);
350   }
351   isolate->SignalFatalError();
352 }
353 
SetSnapshotDataBlob(StartupData * snapshot_blob)354 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
355   i::V8::SetSnapshotBlob(snapshot_blob);
356 }
357 
358 namespace {
359 
360 #ifdef V8_SANDBOXED_POINTERS
361 // ArrayBufferAllocator to use when sandboxed pointers are used in which case
362 // all ArrayBuffer backing stores need to be allocated inside the sandbox.
363 // Note, the current implementation is extremely inefficient as it uses the
364 // BoundedPageAllocator. In the future, we'll need a proper allocator
365 // implementation.
366 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
367  public:
ArrayBufferAllocator()368   ArrayBufferAllocator() { CHECK(page_allocator_); }
369 
Allocate(size_t length)370   void* Allocate(size_t length) override {
371     return page_allocator_->AllocatePages(nullptr, RoundUp(length, page_size_),
372                                           page_size_,
373                                           PageAllocator::kReadWrite);
374   }
375 
AllocateUninitialized(size_t length)376   void* AllocateUninitialized(size_t length) override {
377     return Allocate(length);
378   }
379 
Free(void * data,size_t length)380   void Free(void* data, size_t length) override {
381     page_allocator_->FreePages(data, RoundUp(length, page_size_));
382   }
383 
384  private:
385   PageAllocator* page_allocator_ = internal::GetArrayBufferPageAllocator();
386   const size_t page_size_ = page_allocator_->AllocatePageSize();
387 };
388 
389 #else
390 
391 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
392  public:
393   void* Allocate(size_t length) override {
394 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
395     // Work around for GCC bug on AIX
396     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
397     void* data = __linux_calloc(length, 1);
398 #else
399     void* data = base::Calloc(length, 1);
400 #endif
401     return data;
402   }
403 
404   void* AllocateUninitialized(size_t length) override {
405 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
406     // Work around for GCC bug on AIX
407     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
408     void* data = __linux_malloc(length);
409 #else
410     void* data = base::Malloc(length);
411 #endif
412     return data;
413   }
414 
415   void Free(void* data, size_t) override { base::Free(data); }
416 
417   void* Reallocate(void* data, size_t old_length, size_t new_length) override {
418 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
419     // Work around for GCC bug on AIX
420     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
421     void* new_data = __linux_realloc(data, new_length);
422 #else
423     void* new_data = base::Realloc(data, new_length);
424 #endif
425     if (new_length > old_length) {
426       memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0,
427              new_length - old_length);
428     }
429     return new_data;
430   }
431 };
432 #endif  // V8_SANDBOXED_POINTERS
433 
434 struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anon48d2745d0111::SnapshotCreatorData435   explicit SnapshotCreatorData(Isolate* isolate)
436       : isolate_(isolate),
437         default_context_(),
438         contexts_(isolate),
439         created_(false) {}
440 
castv8::__anon48d2745d0111::SnapshotCreatorData441   static SnapshotCreatorData* cast(void* data) {
442     return reinterpret_cast<SnapshotCreatorData*>(data);
443   }
444 
445   ArrayBufferAllocator allocator_;
446   Isolate* isolate_;
447   Persistent<Context> default_context_;
448   SerializeInternalFieldsCallback default_embedder_fields_serializer_;
449   PersistentValueVector<Context> contexts_;
450   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
451   bool created_;
452 };
453 
454 }  // namespace
455 
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)456 SnapshotCreator::SnapshotCreator(Isolate* isolate,
457                                  const intptr_t* external_references,
458                                  StartupData* existing_snapshot) {
459   SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
460   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
461   internal_isolate->set_array_buffer_allocator(&data->allocator_);
462   internal_isolate->set_api_external_references(external_references);
463   internal_isolate->enable_serializer();
464   isolate->Enter();
465   const StartupData* blob = existing_snapshot
466                                 ? existing_snapshot
467                                 : i::Snapshot::DefaultSnapshotBlob();
468   if (blob && blob->raw_size > 0) {
469     internal_isolate->set_snapshot_blob(blob);
470     i::Snapshot::Initialize(internal_isolate);
471   } else {
472     internal_isolate->InitWithoutSnapshot();
473   }
474   data_ = data;
475   // Disable batch compilation during snapshot creation.
476   internal_isolate->baseline_batch_compiler()->set_enabled(false);
477 }
478 
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)479 SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
480                                  StartupData* existing_snapshot)
481     : SnapshotCreator(Isolate::Allocate(), external_references,
482                       existing_snapshot) {}
483 
~SnapshotCreator()484 SnapshotCreator::~SnapshotCreator() {
485   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
486   Isolate* isolate = data->isolate_;
487   isolate->Exit();
488   isolate->Dispose();
489   delete data;
490 }
491 
GetIsolate()492 Isolate* SnapshotCreator::GetIsolate() {
493   return SnapshotCreatorData::cast(data_)->isolate_;
494 }
495 
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)496 void SnapshotCreator::SetDefaultContext(
497     Local<Context> context, SerializeInternalFieldsCallback callback) {
498   DCHECK(!context.IsEmpty());
499   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
500   DCHECK(!data->created_);
501   DCHECK(data->default_context_.IsEmpty());
502   Isolate* isolate = data->isolate_;
503   CHECK_EQ(isolate, context->GetIsolate());
504   data->default_context_.Reset(isolate, context);
505   data->default_embedder_fields_serializer_ = callback;
506 }
507 
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)508 size_t SnapshotCreator::AddContext(Local<Context> context,
509                                    SerializeInternalFieldsCallback callback) {
510   DCHECK(!context.IsEmpty());
511   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
512   DCHECK(!data->created_);
513   Isolate* isolate = data->isolate_;
514   CHECK_EQ(isolate, context->GetIsolate());
515   size_t index = data->contexts_.Size();
516   data->contexts_.Append(context);
517   data->embedder_fields_serializers_.push_back(callback);
518   return index;
519 }
520 
AddData(i::Address object)521 size_t SnapshotCreator::AddData(i::Address object) {
522   DCHECK_NE(object, i::kNullAddress);
523   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
524   DCHECK(!data->created_);
525   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
526   i::HandleScope scope(isolate);
527   i::Handle<i::Object> obj(i::Object(object), isolate);
528   i::Handle<i::ArrayList> list;
529   if (!isolate->heap()->serialized_objects().IsArrayList()) {
530     list = i::ArrayList::New(isolate, 1);
531   } else {
532     list = i::Handle<i::ArrayList>(
533         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
534   }
535   size_t index = static_cast<size_t>(list->Length());
536   list = i::ArrayList::Add(isolate, list, obj);
537   isolate->heap()->SetSerializedObjects(*list);
538   return index;
539 }
540 
AddData(Local<Context> context,i::Address object)541 size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
542   DCHECK_NE(object, i::kNullAddress);
543   DCHECK(!SnapshotCreatorData::cast(data_)->created_);
544   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
545   i::Isolate* isolate = ctx->GetIsolate();
546   i::HandleScope scope(isolate);
547   i::Handle<i::Object> obj(i::Object(object), isolate);
548   i::Handle<i::ArrayList> list;
549   if (!ctx->serialized_objects().IsArrayList()) {
550     list = i::ArrayList::New(isolate, 1);
551   } else {
552     list = i::Handle<i::ArrayList>(
553         i::ArrayList::cast(ctx->serialized_objects()), isolate);
554   }
555   size_t index = static_cast<size_t>(list->Length());
556   list = i::ArrayList::Add(isolate, list, obj);
557   ctx->set_serialized_objects(*list);
558   return index;
559 }
560 
561 namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)562 void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
563   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
564   i::Isolate* isolate = ctx->GetIsolate();
565   if (!ctx->serialized_objects().IsArrayList()) {
566     ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
567   } else {
568     i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
569                                  isolate);
570     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
571     ctx->set_serialized_objects(*elements);
572   }
573 }
574 
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)575 void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
576   if (!isolate->heap()->serialized_objects().IsArrayList()) {
577     isolate->heap()->SetSerializedObjects(
578         i::ReadOnlyRoots(isolate).empty_fixed_array());
579   } else {
580     i::Handle<i::ArrayList> list(
581         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
582     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
583     isolate->heap()->SetSerializedObjects(*elements);
584   }
585 }
586 }  // anonymous namespace
587 
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)588 StartupData SnapshotCreator::CreateBlob(
589     SnapshotCreator::FunctionCodeHandling function_code_handling) {
590   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
591   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
592   Utils::ApiCheck(!data->created_, "v8::SnapshotCreator::CreateBlob",
593                   "CreateBlob() cannot be called more than once on the same "
594                   "SnapshotCreator.");
595   Utils::ApiCheck(
596       !data->default_context_.IsEmpty(), "v8::SnapshotCreator::CreateBlob",
597       "CreateBlob() cannot be called before the default context is set.");
598 
599   const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
600   const int num_contexts = num_additional_contexts + 1;  // The default context.
601 
602   // Create and store lists of embedder-provided data needed during
603   // serialization.
604   {
605     i::HandleScope scope(isolate);
606     // Convert list of context-independent data to FixedArray.
607     ConvertSerializedObjectsToFixedArray(isolate);
608 
609     // Convert lists of context-dependent data to FixedArray.
610     ConvertSerializedObjectsToFixedArray(
611         data->default_context_.Get(data->isolate_));
612     for (int i = 0; i < num_additional_contexts; i++) {
613       ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
614     }
615 
616     // We need to store the global proxy size upfront in case we need the
617     // bootstrapper to create a global proxy before we deserialize the context.
618     i::Handle<i::FixedArray> global_proxy_sizes =
619         isolate->factory()->NewFixedArray(num_additional_contexts,
620                                           i::AllocationType::kOld);
621     for (int i = 0; i < num_additional_contexts; i++) {
622       i::Handle<i::Context> context =
623           v8::Utils::OpenHandle(*data->contexts_.Get(i));
624       global_proxy_sizes->set(i,
625                               i::Smi::FromInt(context->global_proxy().Size()));
626     }
627     isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
628   }
629 
630   // We might rehash strings and re-sort descriptors. Clear the lookup cache.
631   isolate->descriptor_lookup_cache()->Clear();
632 
633   // If we don't do this then we end up with a stray root pointing at the
634   // context even after we have disposed of the context.
635   isolate->heap()->CollectAllAvailableGarbage(
636       i::GarbageCollectionReason::kSnapshotCreator);
637   {
638     i::HandleScope scope(isolate);
639     isolate->heap()->CompactWeakArrayLists();
640   }
641 
642   i::Snapshot::ClearReconstructableDataForSerialization(
643       isolate, function_code_handling == FunctionCodeHandling::kClear);
644 
645   i::GlobalSafepointScope global_safepoint(isolate);
646   i::DisallowGarbageCollection no_gc_from_here_on;
647 
648   // Create a vector with all contexts and clear associated Persistent fields.
649   // Note these contexts may be dead after calling Clear(), but will not be
650   // collected until serialization completes and the DisallowGarbageCollection
651   // scope above goes out of scope.
652   std::vector<i::Context> contexts;
653   contexts.reserve(num_contexts);
654   {
655     i::HandleScope scope(isolate);
656     contexts.push_back(
657         *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
658     data->default_context_.Reset();
659     for (int i = 0; i < num_additional_contexts; i++) {
660       i::Handle<i::Context> context =
661           v8::Utils::OpenHandle(*data->contexts_.Get(i));
662       contexts.push_back(*context);
663     }
664     data->contexts_.Clear();
665   }
666 
667   // Check that values referenced by global/eternal handles are accounted for.
668   i::SerializedHandleChecker handle_checker(isolate, &contexts);
669   CHECK(handle_checker.CheckGlobalAndEternalHandles());
670 
671   // Create a vector with all embedder fields serializers.
672   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
673   embedder_fields_serializers.reserve(num_contexts);
674   embedder_fields_serializers.push_back(
675       data->default_embedder_fields_serializer_);
676   for (int i = 0; i < num_additional_contexts; i++) {
677     embedder_fields_serializers.push_back(
678         data->embedder_fields_serializers_[i]);
679   }
680 
681   data->created_ = true;
682   return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
683                              global_safepoint, no_gc_from_here_on);
684 }
685 
CanBeRehashed() const686 bool StartupData::CanBeRehashed() const {
687   DCHECK(i::Snapshot::VerifyChecksum(this));
688   return i::Snapshot::ExtractRehashability(this);
689 }
690 
IsValid() const691 bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
692 
SetDcheckErrorHandler(DcheckErrorCallback that)693 void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
694   v8::base::SetDcheckFunction(that);
695 }
696 
SetFlagsFromString(const char * str)697 void V8::SetFlagsFromString(const char* str) {
698   SetFlagsFromString(str, strlen(str));
699 }
700 
SetFlagsFromString(const char * str,size_t length)701 void V8::SetFlagsFromString(const char* str, size_t length) {
702   i::FlagList::SetFlagsFromString(str, length);
703   i::FlagList::EnforceFlagImplications();
704 }
705 
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)706 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
707   using HelpOptions = i::FlagList::HelpOptions;
708   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
709                                        HelpOptions(HelpOptions::kDontExit));
710 }
711 
712 RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
713 
RegisteredExtension(std::unique_ptr<Extension> extension)714 RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
715     : extension_(std::move(extension)) {}
716 
717 // static
Register(std::unique_ptr<Extension> extension)718 void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
719   RegisteredExtension* new_extension =
720       new RegisteredExtension(std::move(extension));
721   new_extension->next_ = first_extension_;
722   first_extension_ = new_extension;
723 }
724 
725 // static
UnregisterAll()726 void RegisteredExtension::UnregisterAll() {
727   RegisteredExtension* re = first_extension_;
728   while (re != nullptr) {
729     RegisteredExtension* next = re->next();
730     delete re;
731     re = next;
732   }
733   first_extension_ = nullptr;
734 }
735 
736 namespace {
737 class ExtensionResource : public String::ExternalOneByteStringResource {
738  public:
ExtensionResource()739   ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)740   ExtensionResource(const char* data, size_t length)
741       : data_(data), length_(length) {}
data() const742   const char* data() const override { return data_; }
length() const743   size_t length() const override { return length_; }
Dispose()744   void Dispose() override {}
745 
746  private:
747   const char* data_;
748   size_t length_;
749 };
750 }  // anonymous namespace
751 
RegisterExtension(std::unique_ptr<Extension> extension)752 void RegisterExtension(std::unique_ptr<Extension> extension) {
753   RegisteredExtension::Register(std::move(extension));
754 }
755 
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)756 Extension::Extension(const char* name, const char* source, int dep_count,
757                      const char** deps, int source_length)
758     : name_(name),
759       source_length_(source_length >= 0
760                          ? source_length
761                          : (source ? static_cast<int>(strlen(source)) : 0)),
762       dep_count_(dep_count),
763       deps_(deps),
764       auto_enable_(false) {
765   source_ = new ExtensionResource(source, source_length_);
766   CHECK(source != nullptr || source_length_ == 0);
767 }
768 
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)769 void ResourceConstraints::ConfigureDefaultsFromHeapSize(
770     size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
771   CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
772   if (maximum_heap_size_in_bytes == 0) {
773     return;
774   }
775   size_t young_generation, old_generation;
776   i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
777                                        &young_generation, &old_generation);
778   set_max_young_generation_size_in_bytes(
779       std::max(young_generation, i::Heap::MinYoungGenerationSize()));
780   set_max_old_generation_size_in_bytes(
781       std::max(old_generation, i::Heap::MinOldGenerationSize()));
782   if (initial_heap_size_in_bytes > 0) {
783     i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
784                                          &young_generation, &old_generation);
785     // We do not set lower bounds for the initial sizes.
786     set_initial_young_generation_size_in_bytes(young_generation);
787     set_initial_old_generation_size_in_bytes(old_generation);
788   }
789   if (i::kPlatformRequiresCodeRange) {
790     set_code_range_size_in_bytes(
791         std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
792   }
793 }
794 
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)795 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
796                                             uint64_t virtual_memory_limit) {
797   size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
798   size_t young_generation, old_generation;
799   i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
800                                        &old_generation);
801   set_max_young_generation_size_in_bytes(young_generation);
802   set_max_old_generation_size_in_bytes(old_generation);
803 
804   if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
805     set_code_range_size_in_bytes(
806         std::min(i::kMaximalCodeRangeSize,
807                  static_cast<size_t>(virtual_memory_limit / 8)));
808   }
809 }
810 
811 namespace internal {
812 
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,GlobalHandleStoreMode store_mode)813 i::Address* GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
814                                      internal::Address* slot,
815                                      GlobalHandleStoreMode store_mode) {
816   API_RCS_SCOPE(isolate, TracedGlobal, New);
817 #ifdef DEBUG
818   Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
819                   "the address slot must be not null");
820 #endif
821   i::Handle<i::Object> result =
822       isolate->global_handles()->CreateTraced(*obj, slot, store_mode);
823 #ifdef VERIFY_HEAP
824   if (i::FLAG_verify_heap) {
825     i::Object(*obj).ObjectVerify(isolate);
826   }
827 #endif  // VERIFY_HEAP
828   return result.location();
829 }
830 
MoveTracedReference(internal::Address ** from,internal::Address ** to)831 void MoveTracedReference(internal::Address** from, internal::Address** to) {
832   GlobalHandles::MoveTracedReference(from, to);
833 }
834 
CopyTracedReference(const internal::Address * const * from,internal::Address ** to)835 void CopyTracedReference(const internal::Address* const* from,
836                          internal::Address** to) {
837   GlobalHandles::CopyTracedReference(from, to);
838 }
839 
DisposeTracedReference(internal::Address * location)840 void DisposeTracedReference(internal::Address* location) {
841   GlobalHandles::DestroyTracedReference(location);
842 }
843 
844 }  // namespace internal
845 
846 namespace api_internal {
847 
GlobalizeReference(i::Isolate * isolate,i::Address * obj)848 i::Address* GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
849   API_RCS_SCOPE(isolate, Persistent, New);
850   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
851 #ifdef VERIFY_HEAP
852   if (i::FLAG_verify_heap) {
853     i::Object(*obj).ObjectVerify(isolate);
854   }
855 #endif  // VERIFY_HEAP
856   return result.location();
857 }
858 
CopyGlobalReference(i::Address * from)859 i::Address* CopyGlobalReference(i::Address* from) {
860   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
861   return result.location();
862 }
863 
MoveGlobalReference(internal::Address ** from,internal::Address ** to)864 void MoveGlobalReference(internal::Address** from, internal::Address** to) {
865   i::GlobalHandles::MoveGlobal(from, to);
866 }
867 
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)868 void MakeWeak(i::Address* location, void* parameter,
869               WeakCallbackInfo<void>::Callback weak_callback,
870               WeakCallbackType type) {
871   i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
872 }
873 
MakeWeak(i::Address ** location_addr)874 void MakeWeak(i::Address** location_addr) {
875   i::GlobalHandles::MakeWeak(location_addr);
876 }
877 
ClearWeak(i::Address * location)878 void* ClearWeak(i::Address* location) {
879   return i::GlobalHandles::ClearWeakness(location);
880 }
881 
AnnotateStrongRetainer(i::Address * location,const char * label)882 void AnnotateStrongRetainer(i::Address* location, const char* label) {
883   i::GlobalHandles::AnnotateStrongRetainer(location, label);
884 }
885 
DisposeGlobal(i::Address * location)886 void DisposeGlobal(i::Address* location) {
887   i::GlobalHandles::Destroy(location);
888 }
889 
Eternalize(Isolate * v8_isolate,Value * value)890 Value* Eternalize(Isolate* v8_isolate, Value* value) {
891   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
892   i::Object object = *Utils::OpenHandle(value);
893   int index = -1;
894   isolate->eternal_handles()->Create(isolate, object, &index);
895   return reinterpret_cast<Value*>(
896       isolate->eternal_handles()->Get(index).location());
897 }
898 
FromJustIsNothing()899 void FromJustIsNothing() {
900   Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
901 }
902 
ToLocalEmpty()903 void ToLocalEmpty() {
904   Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
905 }
906 
InternalFieldOutOfBounds(int index)907 void InternalFieldOutOfBounds(int index) {
908   Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
909                   "WeakCallbackInfo::GetInternalField",
910                   "Internal field out of bounds.");
911 }
912 
913 }  // namespace api_internal
914 
915 // --- H a n d l e s ---
916 
HandleScope(Isolate * isolate)917 HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
918 
Initialize(Isolate * isolate)919 void HandleScope::Initialize(Isolate* isolate) {
920   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
921   // We do not want to check the correct usage of the Locker class all over the
922   // place, so we do it only here: Without a HandleScope, an embedder can do
923   // almost nothing, so it is enough to check in this central place.
924   // We make an exception if the serializer is enabled, which means that the
925   // Isolate is exclusively used to create a snapshot.
926   Utils::ApiCheck(
927       !internal_isolate->was_locker_ever_used() ||
928           internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
929           internal_isolate->serializer_enabled(),
930       "HandleScope::HandleScope",
931       "Entering the V8 API without proper locking in place");
932   i::HandleScopeData* current = internal_isolate->handle_scope_data();
933   isolate_ = internal_isolate;
934   prev_next_ = current->next;
935   prev_limit_ = current->limit;
936   current->level++;
937 }
938 
~HandleScope()939 HandleScope::~HandleScope() {
940   i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
941 }
942 
operator new(size_t)943 void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)944 void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)945 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)946 void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
947 
NumberOfHandles(Isolate * isolate)948 int HandleScope::NumberOfHandles(Isolate* isolate) {
949   return i::HandleScope::NumberOfHandles(
950       reinterpret_cast<i::Isolate*>(isolate));
951 }
952 
CreateHandle(i::Isolate * isolate,i::Address value)953 i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
954   return i::HandleScope::CreateHandle(isolate, value);
955 }
956 
EscapableHandleScope(Isolate * v8_isolate)957 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
958   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
959   escape_slot_ =
960       CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
961   Initialize(v8_isolate);
962 }
963 
Escape(i::Address * escape_value)964 i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
965   i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
966   Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
967                   "EscapableHandleScope::Escape", "Escape value set twice");
968   if (escape_value == nullptr) {
969     *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
970     return nullptr;
971   }
972   *escape_slot_ = *escape_value;
973   return escape_slot_;
974 }
975 
operator new(size_t)976 void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)977 void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)978 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)979 void EscapableHandleScope::operator delete[](void*, size_t) {
980   base::OS::Abort();
981 }
982 
SealHandleScope(Isolate * isolate)983 SealHandleScope::SealHandleScope(Isolate* isolate)
984     : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
985   i::HandleScopeData* current = isolate_->handle_scope_data();
986   prev_limit_ = current->limit;
987   current->limit = current->next;
988   prev_sealed_level_ = current->sealed_level;
989   current->sealed_level = current->level;
990 }
991 
~SealHandleScope()992 SealHandleScope::~SealHandleScope() {
993   i::HandleScopeData* current = isolate_->handle_scope_data();
994   DCHECK_EQ(current->next, current->limit);
995   current->limit = prev_limit_;
996   DCHECK_EQ(current->level, current->sealed_level);
997   current->sealed_level = prev_sealed_level_;
998 }
999 
operator new(size_t)1000 void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1001 void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1002 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1003 void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1004 
IsModule() const1005 bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
IsFixedArray() const1006 bool Data::IsFixedArray() const {
1007   return Utils::OpenHandle(this)->IsFixedArray();
1008 }
1009 
IsValue() const1010 bool Data::IsValue() const {
1011   i::DisallowGarbageCollection no_gc;
1012   i::Object self = *Utils::OpenHandle(this);
1013   if (self.IsSmi()) return true;
1014   i::HeapObject heap_object = i::HeapObject::cast(self);
1015   DCHECK(!heap_object.IsTheHole());
1016   if (heap_object.IsSymbol()) {
1017     return !i::Symbol::cast(heap_object).is_private();
1018   }
1019   return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1020 }
1021 
IsPrivate() const1022 bool Data::IsPrivate() const {
1023   return Utils::OpenHandle(this)->IsPrivateSymbol();
1024 }
1025 
IsObjectTemplate() const1026 bool Data::IsObjectTemplate() const {
1027   return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1028 }
1029 
IsFunctionTemplate() const1030 bool Data::IsFunctionTemplate() const {
1031   return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1032 }
1033 
IsContext() const1034 bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1035 
Enter()1036 void Context::Enter() {
1037   i::Handle<i::Context> env = Utils::OpenHandle(this);
1038   i::Isolate* isolate = env->GetIsolate();
1039   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1040   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1041   impl->EnterContext(*env);
1042   impl->SaveContext(isolate->context());
1043   isolate->set_context(*env);
1044 }
1045 
Exit()1046 void Context::Exit() {
1047   i::Handle<i::Context> env = Utils::OpenHandle(this);
1048   i::Isolate* isolate = env->GetIsolate();
1049   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1050   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1051   if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1052                        "Cannot exit non-entered context")) {
1053     return;
1054   }
1055   impl->LeaveContext();
1056   isolate->set_context(impl->RestoreContext());
1057 }
1058 
BackupIncumbentScope(Local<Context> backup_incumbent_context)1059 Context::BackupIncumbentScope::BackupIncumbentScope(
1060     Local<Context> backup_incumbent_context)
1061     : backup_incumbent_context_(backup_incumbent_context) {
1062   DCHECK(!backup_incumbent_context_.IsEmpty());
1063 
1064   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1065   i::Isolate* isolate = env->GetIsolate();
1066 
1067   js_stack_comparable_address_ =
1068       i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1069 
1070   prev_ = isolate->top_backup_incumbent_scope();
1071   isolate->set_top_backup_incumbent_scope(this);
1072 }
1073 
~BackupIncumbentScope()1074 Context::BackupIncumbentScope::~BackupIncumbentScope() {
1075   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1076   i::Isolate* isolate = env->GetIsolate();
1077 
1078   i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1079 
1080   isolate->set_top_backup_incumbent_scope(prev_);
1081 }
1082 
1083 STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1084 
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1085 static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1086                                                        int index, bool can_grow,
1087                                                        const char* location) {
1088   i::Handle<i::Context> env = Utils::OpenHandle(context);
1089   i::Isolate* isolate = env->GetIsolate();
1090   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
1091   bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1092                             "Not a native context") &&
1093             Utils::ApiCheck(index >= 0, location, "Negative index");
1094   if (!ok) return i::Handle<i::EmbedderDataArray>();
1095   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1096   i::Handle<i::EmbedderDataArray> data(
1097       i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1098   if (index < data->length()) return data;
1099   if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1100                        location, "Index too large")) {
1101     return i::Handle<i::EmbedderDataArray>();
1102   }
1103   data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1104   env->set_embedder_data(*data);
1105   return data;
1106 }
1107 
GetNumberOfEmbedderDataFields()1108 uint32_t Context::GetNumberOfEmbedderDataFields() {
1109   i::Handle<i::Context> context = Utils::OpenHandle(this);
1110   ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate());
1111   Utils::ApiCheck(context->IsNativeContext(),
1112                   "Context::GetNumberOfEmbedderDataFields",
1113                   "Not a native context");
1114   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1115   return static_cast<uint32_t>(
1116       i::EmbedderDataArray::cast(context->embedder_data()).length());
1117 }
1118 
SlowGetEmbedderData(int index)1119 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1120   const char* location = "v8::Context::GetEmbedderData()";
1121   i::Handle<i::EmbedderDataArray> data =
1122       EmbedderDataFor(this, index, false, location);
1123   if (data.is_null()) return Local<Value>();
1124   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1125   i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1126                               isolate);
1127   return Utils::ToLocal(result);
1128 }
1129 
SetEmbedderData(int index,v8::Local<Value> value)1130 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1131   const char* location = "v8::Context::SetEmbedderData()";
1132   i::Handle<i::EmbedderDataArray> data =
1133       EmbedderDataFor(this, index, true, location);
1134   if (data.is_null()) return;
1135   i::Handle<i::Object> val = Utils::OpenHandle(*value);
1136   i::EmbedderDataSlot::store_tagged(*data, index, *val);
1137   DCHECK_EQ(*Utils::OpenHandle(*value),
1138             *Utils::OpenHandle(*GetEmbedderData(index)));
1139 }
1140 
SlowGetAlignedPointerFromEmbedderData(int index)1141 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1142   const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1143   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1144   i::HandleScope handle_scope(isolate);
1145   i::Handle<i::EmbedderDataArray> data =
1146       EmbedderDataFor(this, index, false, location);
1147   if (data.is_null()) return nullptr;
1148   void* result;
1149   Utils::ApiCheck(
1150       i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1151       location, "Pointer is not aligned");
1152   return result;
1153 }
1154 
SetAlignedPointerInEmbedderData(int index,void * value)1155 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1156   const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1157   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1158   i::Handle<i::EmbedderDataArray> data =
1159       EmbedderDataFor(this, index, true, location);
1160   bool ok =
1161       i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1162   Utils::ApiCheck(ok, location, "Pointer is not aligned");
1163   DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1164 }
1165 
1166 // --- T e m p l a t e ---
1167 
InitializeTemplate(i::TemplateInfo that,int type,bool do_not_cache)1168 static void InitializeTemplate(i::TemplateInfo that, int type,
1169                                bool do_not_cache) {
1170   that.set_number_of_properties(0);
1171   that.set_tag(type);
1172   int serial_number =
1173       do_not_cache ? i::TemplateInfo::kDoNotCache : i::TemplateInfo::kUncached;
1174   that.set_serial_number(serial_number);
1175 }
1176 
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1177 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1178                    v8::PropertyAttribute attribute) {
1179   auto templ = Utils::OpenHandle(this);
1180   i::Isolate* isolate = templ->GetIsolate();
1181   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1182   i::HandleScope scope(isolate);
1183   auto value_obj = Utils::OpenHandle(*value);
1184 
1185   Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(),
1186                   "v8::Template::Set",
1187                   "Invalid value, must be a primitive or a Template");
1188 
1189   // The template cache only performs shallow clones, if we set an
1190   // ObjectTemplate as a property value then we can not cache the receiver
1191   // template.
1192   if (value_obj->IsObjectTemplateInfo()) {
1193     templ->set_serial_number(i::TemplateInfo::kDoNotCache);
1194   }
1195 
1196   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1197                                  value_obj,
1198                                  static_cast<i::PropertyAttributes>(attribute));
1199 }
1200 
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1201 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1202                           v8::PropertyAttribute attribute) {
1203   Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1204       attribute);
1205 }
1206 
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1207 void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1208                                    v8::Local<FunctionTemplate> getter,
1209                                    v8::Local<FunctionTemplate> setter,
1210                                    v8::PropertyAttribute attribute,
1211                                    v8::AccessControl access_control) {
1212   // TODO(verwaest): Remove |access_control|.
1213   DCHECK_EQ(v8::DEFAULT, access_control);
1214   auto templ = Utils::OpenHandle(this);
1215   auto isolate = templ->GetIsolate();
1216   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1217   DCHECK(!name.IsEmpty());
1218   DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1219   i::HandleScope scope(isolate);
1220   i::ApiNatives::AddAccessorProperty(
1221       isolate, templ, Utils::OpenHandle(*name),
1222       Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1223       static_cast<i::PropertyAttributes>(attribute));
1224 }
1225 
1226 // --- F u n c t i o n   T e m p l a t e ---
InitializeFunctionTemplate(i::FunctionTemplateInfo info,bool do_not_cache)1227 static void InitializeFunctionTemplate(i::FunctionTemplateInfo info,
1228                                        bool do_not_cache) {
1229   InitializeTemplate(info, Consts::FUNCTION_TEMPLATE, do_not_cache);
1230   info.set_flag(0);
1231 }
1232 
1233 static Local<ObjectTemplate> ObjectTemplateNew(
1234     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1235     bool do_not_cache);
1236 
PrototypeTemplate()1237 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1238   auto self = Utils::OpenHandle(this);
1239   i::Isolate* i_isolate = self->GetIsolate();
1240   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1241   i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1242   if (result->IsUndefined(i_isolate)) {
1243     // Do not cache prototype objects.
1244     result = Utils::OpenHandle(
1245         *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1246     i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1247   }
1248   return ToApiHandle<ObjectTemplate>(result);
1249 }
1250 
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1251 void FunctionTemplate::SetPrototypeProviderTemplate(
1252     Local<FunctionTemplate> prototype_provider) {
1253   auto self = Utils::OpenHandle(this);
1254   i::Isolate* i_isolate = self->GetIsolate();
1255   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1256   i::Handle<i::FunctionTemplateInfo> result =
1257       Utils::OpenHandle(*prototype_provider);
1258   Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
1259                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1260                   "Protoype must be undefined");
1261   Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
1262                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1263                   "Prototype provider must be empty");
1264   i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1265                                                         result);
1266 }
1267 
EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,const char * func)1268 static void EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,
1269                                const char* func) {
1270   DCHECK_IMPLIES(info->instantiated(), info->published());
1271   Utils::ApiCheck(!info->published(), func,
1272                   "FunctionTemplate already instantiated");
1273 }
1274 
Inherit(v8::Local<FunctionTemplate> value)1275 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1276   auto info = Utils::OpenHandle(this);
1277   EnsureNotPublished(info, "v8::FunctionTemplate::Inherit");
1278   i::Isolate* i_isolate = info->GetIsolate();
1279   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1280   Utils::ApiCheck(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate),
1281                   "v8::FunctionTemplate::Inherit",
1282                   "Protoype provider must be empty");
1283   i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1284                                              Utils::OpenHandle(*value));
1285 }
1286 
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> (),SideEffectType side_effect_type=SideEffectType::kHasSideEffect,const MemorySpan<const CFunction> & c_function_overloads={},uint8_t instance_type=0,uint8_t allowed_receiver_instance_type_range_start=0,uint8_t allowed_receiver_instance_type_range_end=0)1287 static Local<FunctionTemplate> FunctionTemplateNew(
1288     i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1289     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1290     bool do_not_cache,
1291     v8::Local<Private> cached_property_name = v8::Local<Private>(),
1292     SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1293     const MemorySpan<const CFunction>& c_function_overloads = {},
1294     uint8_t instance_type = 0,
1295     uint8_t allowed_receiver_instance_type_range_start = 0,
1296     uint8_t allowed_receiver_instance_type_range_end = 0) {
1297   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1298       i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1299   i::Handle<i::FunctionTemplateInfo> obj =
1300       i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1301   {
1302     // Disallow GC until all fields of obj have acceptable types.
1303     i::DisallowGarbageCollection no_gc;
1304     i::FunctionTemplateInfo raw = *obj;
1305     InitializeFunctionTemplate(raw, do_not_cache);
1306     raw.set_length(length);
1307     raw.set_undetectable(false);
1308     raw.set_needs_access_check(false);
1309     raw.set_accept_any_receiver(true);
1310     if (!signature.IsEmpty()) {
1311       raw.set_signature(*Utils::OpenHandle(*signature));
1312     }
1313     raw.set_cached_property_name(
1314         cached_property_name.IsEmpty()
1315             ? i::ReadOnlyRoots(isolate).the_hole_value()
1316             : *Utils::OpenHandle(*cached_property_name));
1317     if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
1318     raw.SetInstanceType(instance_type);
1319     raw.set_allowed_receiver_instance_type_range_start(
1320         allowed_receiver_instance_type_range_start);
1321     raw.set_allowed_receiver_instance_type_range_end(
1322         allowed_receiver_instance_type_range_end);
1323   }
1324   if (callback != nullptr) {
1325     Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1326                                         c_function_overloads);
1327   }
1328   return Utils::ToLocal(obj);
1329 }
1330 
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const CFunction * c_function,uint16_t instance_type,uint16_t allowed_receiver_instance_type_range_start,uint16_t allowed_receiver_instance_type_range_end)1331 Local<FunctionTemplate> FunctionTemplate::New(
1332     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1333     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1334     SideEffectType side_effect_type, const CFunction* c_function,
1335     uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
1336     uint16_t allowed_receiver_instance_type_range_end) {
1337   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1338   // Changes to the environment cannot be captured in the snapshot. Expect no
1339   // function templates when the isolate is created for serialization.
1340   API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1341 
1342   if (!Utils::ApiCheck(
1343           !c_function || behavior == ConstructorBehavior::kThrow,
1344           "FunctionTemplate::New",
1345           "Fast API calls are not supported for constructor functions.")) {
1346     return Local<FunctionTemplate>();
1347   }
1348 
1349   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1350   return FunctionTemplateNew(
1351       i_isolate, callback, data, signature, length, behavior, false,
1352       Local<Private>(), side_effect_type,
1353       c_function ? MemorySpan<const CFunction>{c_function, 1}
1354                  : MemorySpan<const CFunction>{},
1355       instance_type, allowed_receiver_instance_type_range_start,
1356       allowed_receiver_instance_type_range_end);
1357 }
1358 
NewWithCFunctionOverloads(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1359 Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1360     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1361     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1362     SideEffectType side_effect_type,
1363     const MemorySpan<const CFunction>& c_function_overloads) {
1364   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1365   API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1366 
1367   if (!Utils::ApiCheck(
1368           c_function_overloads.size() == 0 ||
1369               behavior == ConstructorBehavior::kThrow,
1370           "FunctionTemplate::NewWithCFunctionOverloads",
1371           "Fast API calls are not supported for constructor functions.")) {
1372     return Local<FunctionTemplate>();
1373   }
1374 
1375   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1376   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1377                              behavior, false, Local<Private>(),
1378                              side_effect_type, c_function_overloads);
1379 }
1380 
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1381 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1382     Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1383     Local<Value> data, Local<Signature> signature, int length,
1384     SideEffectType side_effect_type) {
1385   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1386   API_RCS_SCOPE(i_isolate, FunctionTemplate, NewWithCache);
1387   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1388   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1389                              ConstructorBehavior::kAllow, false, cache_property,
1390                              side_effect_type);
1391 }
1392 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1393 Local<Signature> Signature::New(Isolate* isolate,
1394                                 Local<FunctionTemplate> receiver) {
1395   return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1396 }
1397 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1398 Local<AccessorSignature> AccessorSignature::New(
1399     Isolate* isolate, Local<FunctionTemplate> receiver) {
1400   return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1401 }
1402 
1403 #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata)        \
1404   do {                                                        \
1405     i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1406     (obj)->setter(*foreign);                                  \
1407   } while (false)
1408 
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1409 void FunctionTemplate::SetCallHandler(
1410     FunctionCallback callback, v8::Local<Value> data,
1411     SideEffectType side_effect_type,
1412     const MemorySpan<const CFunction>& c_function_overloads) {
1413   auto info = Utils::OpenHandle(this);
1414   EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
1415   i::Isolate* isolate = info->GetIsolate();
1416   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1417   i::HandleScope scope(isolate);
1418   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1419       side_effect_type == SideEffectType::kHasNoSideEffect);
1420   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1421   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1422   if (data.IsEmpty()) {
1423     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424   }
1425   obj->set_data(*Utils::OpenHandle(*data));
1426   if (c_function_overloads.size() > 0) {
1427     // Stores the data for a sequence of CFunction overloads into a single
1428     // FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
1429     i::Handle<i::FixedArray> function_overloads =
1430         isolate->factory()->NewFixedArray(static_cast<int>(
1431             c_function_overloads.size() *
1432             i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
1433     int function_count = static_cast<int>(c_function_overloads.size());
1434     for (int i = 0; i < function_count; i++) {
1435       const CFunction& c_function = c_function_overloads.data()[i];
1436       i::Handle<i::Object> address =
1437           FromCData(isolate, c_function.GetAddress());
1438       function_overloads->set(
1439           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
1440       i::Handle<i::Object> signature =
1441           FromCData(isolate, c_function.GetTypeInfo());
1442       function_overloads->set(
1443           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
1444           *signature);
1445     }
1446     i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
1447                                                    function_overloads);
1448   }
1449   info->set_call_code(*obj, kReleaseStore);
1450 }
1451 
1452 namespace {
1453 
1454 template <typename Getter, typename Setter>
MakeAccessorInfo(i::Isolate * isolate,v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1455 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1456     i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1457     v8::Local<Value> data, v8::AccessControl settings,
1458     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1459     bool replace_on_access) {
1460   i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1461   SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1462   DCHECK_IMPLIES(replace_on_access,
1463                  is_special_data_property && setter == nullptr);
1464   if (is_special_data_property && setter == nullptr) {
1465     setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1466   }
1467   SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1468   i::Address redirected = obj->redirected_getter();
1469   if (redirected != i::kNullAddress) {
1470     SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1471   }
1472 
1473   i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1474   if (!accessor_name->IsUniqueName()) {
1475     accessor_name = isolate->factory()->InternalizeString(
1476         i::Handle<i::String>::cast(accessor_name));
1477   }
1478   i::DisallowGarbageCollection no_gc;
1479   i::AccessorInfo raw_obj = *obj;
1480   if (data.IsEmpty()) {
1481     raw_obj.set_data(i::ReadOnlyRoots(isolate).undefined_value());
1482   } else {
1483     raw_obj.set_data(*Utils::OpenHandle(*data));
1484   }
1485   raw_obj.set_name(*accessor_name);
1486   raw_obj.set_is_special_data_property(is_special_data_property);
1487   raw_obj.set_replace_on_access(replace_on_access);
1488   if (settings & ALL_CAN_READ) raw_obj.set_all_can_read(true);
1489   if (settings & ALL_CAN_WRITE) raw_obj.set_all_can_write(true);
1490   raw_obj.set_initial_property_attributes(i::NONE);
1491   if (!signature.IsEmpty()) {
1492     raw_obj.set_expected_receiver_type(*Utils::OpenHandle(*signature));
1493   }
1494   return obj;
1495 }
1496 
1497 }  // namespace
1498 
InstanceTemplate()1499 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1500   i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1501   if (!Utils::ApiCheck(!handle.is_null(),
1502                        "v8::FunctionTemplate::InstanceTemplate()",
1503                        "Reading from empty handle")) {
1504     return Local<ObjectTemplate>();
1505   }
1506   i::Isolate* isolate = handle->GetIsolate();
1507   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1508   if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1509     Local<ObjectTemplate> templ =
1510         ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1511     i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1512                                                  Utils::OpenHandle(*templ));
1513   }
1514   i::Handle<i::ObjectTemplateInfo> result(
1515       i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1516   return Utils::ToLocal(result);
1517 }
1518 
SetLength(int length)1519 void FunctionTemplate::SetLength(int length) {
1520   auto info = Utils::OpenHandle(this);
1521   EnsureNotPublished(info, "v8::FunctionTemplate::SetLength");
1522   auto isolate = info->GetIsolate();
1523   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1524   info->set_length(length);
1525 }
1526 
SetClassName(Local<String> name)1527 void FunctionTemplate::SetClassName(Local<String> name) {
1528   auto info = Utils::OpenHandle(this);
1529   EnsureNotPublished(info, "v8::FunctionTemplate::SetClassName");
1530   auto isolate = info->GetIsolate();
1531   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1532   info->set_class_name(*Utils::OpenHandle(*name));
1533 }
1534 
SetAcceptAnyReceiver(bool value)1535 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1536   auto info = Utils::OpenHandle(this);
1537   EnsureNotPublished(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1538   auto isolate = info->GetIsolate();
1539   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1540   info->set_accept_any_receiver(value);
1541 }
1542 
ReadOnlyPrototype()1543 void FunctionTemplate::ReadOnlyPrototype() {
1544   auto info = Utils::OpenHandle(this);
1545   EnsureNotPublished(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1546   auto isolate = info->GetIsolate();
1547   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548   info->set_read_only_prototype(true);
1549 }
1550 
RemovePrototype()1551 void FunctionTemplate::RemovePrototype() {
1552   auto info = Utils::OpenHandle(this);
1553   EnsureNotPublished(info, "v8::FunctionTemplate::RemovePrototype");
1554   auto isolate = info->GetIsolate();
1555   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1556   info->set_remove_prototype(true);
1557 }
1558 
1559 // --- O b j e c t T e m p l a t e ---
1560 
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1561 Local<ObjectTemplate> ObjectTemplate::New(
1562     Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1563   return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1564 }
1565 
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1566 static Local<ObjectTemplate> ObjectTemplateNew(
1567     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1568     bool do_not_cache) {
1569   API_RCS_SCOPE(isolate, ObjectTemplate, New);
1570   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1571   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1572       i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1573   i::Handle<i::ObjectTemplateInfo> obj =
1574       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1575   {
1576     // Disallow GC until all fields of obj have acceptable types.
1577     i::DisallowGarbageCollection no_gc;
1578     i::ObjectTemplateInfo raw = *obj;
1579     InitializeTemplate(raw, Consts::OBJECT_TEMPLATE, do_not_cache);
1580     raw.set_data(0);
1581     if (!constructor.IsEmpty()) {
1582       raw.set_constructor(*Utils::OpenHandle(*constructor));
1583     }
1584   }
1585   return Utils::ToLocal(obj);
1586 }
1587 
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1588 Local<ObjectTemplate> ObjectTemplate::New(
1589     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1590   return ObjectTemplateNew(isolate, constructor, false);
1591 }
1592 
1593 // Ensure that the object template has a constructor.  If no
1594 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1595 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1596     i::Isolate* isolate, ObjectTemplate* object_template) {
1597   i::Object obj = Utils::OpenHandle(object_template)->constructor();
1598   if (!obj.IsUndefined(isolate)) {
1599     i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1600     return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1601   }
1602   Local<FunctionTemplate> templ =
1603       FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1604   i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1605   i::FunctionTemplateInfo::SetInstanceTemplate(
1606       isolate, constructor, Utils::OpenHandle(object_template));
1607   Utils::OpenHandle(object_template)->set_constructor(*constructor);
1608   return constructor;
1609 }
1610 
1611 template <typename Getter, typename Setter, typename Data, typename Template>
TemplateSetAccessor(Template * template_obj,v8::Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1612 static void TemplateSetAccessor(
1613     Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1614     Data data, AccessControl settings, PropertyAttribute attribute,
1615     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1616     bool replace_on_access, SideEffectType getter_side_effect_type,
1617     SideEffectType setter_side_effect_type) {
1618   auto info = Utils::OpenHandle(template_obj);
1619   auto isolate = info->GetIsolate();
1620   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1621   i::HandleScope scope(isolate);
1622   i::Handle<i::AccessorInfo> accessor_info =
1623       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1624                        is_special_data_property, replace_on_access);
1625   {
1626     i::DisallowGarbageCollection no_gc;
1627     i::AccessorInfo raw = *accessor_info;
1628     raw.set_initial_property_attributes(
1629         static_cast<i::PropertyAttributes>(attribute));
1630     raw.set_getter_side_effect_type(getter_side_effect_type);
1631     raw.set_setter_side_effect_type(setter_side_effect_type);
1632   }
1633   i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1634 }
1635 
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1636 void Template::SetNativeDataProperty(v8::Local<String> name,
1637                                      AccessorGetterCallback getter,
1638                                      AccessorSetterCallback setter,
1639                                      v8::Local<Value> data,
1640                                      PropertyAttribute attribute,
1641                                      AccessControl settings,
1642                                      SideEffectType getter_side_effect_type,
1643                                      SideEffectType setter_side_effect_type) {
1644   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1645                       Local<AccessorSignature>(), true, false,
1646                       getter_side_effect_type, setter_side_effect_type);
1647 }
1648 
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1649 void Template::SetNativeDataProperty(
1650     v8::Local<String> name, AccessorGetterCallback getter,
1651     AccessorSetterCallback setter, v8::Local<Value> data,
1652     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1653     AccessControl settings, SideEffectType getter_side_effect_type,
1654     SideEffectType setter_side_effect_type) {
1655   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1656                       signature, true, false, getter_side_effect_type,
1657                       setter_side_effect_type);
1658 }
1659 
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1660 void Template::SetNativeDataProperty(v8::Local<Name> name,
1661                                      AccessorNameGetterCallback getter,
1662                                      AccessorNameSetterCallback setter,
1663                                      v8::Local<Value> data,
1664                                      PropertyAttribute attribute,
1665                                      AccessControl settings,
1666                                      SideEffectType getter_side_effect_type,
1667                                      SideEffectType setter_side_effect_type) {
1668   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1669                       Local<AccessorSignature>(), true, false,
1670                       getter_side_effect_type, setter_side_effect_type);
1671 }
1672 
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1673 void Template::SetNativeDataProperty(
1674     v8::Local<Name> name, AccessorNameGetterCallback getter,
1675     AccessorNameSetterCallback setter, v8::Local<Value> data,
1676     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1677     AccessControl settings, SideEffectType getter_side_effect_type,
1678     SideEffectType setter_side_effect_type) {
1679   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1680                       signature, true, false, getter_side_effect_type,
1681                       setter_side_effect_type);
1682 }
1683 
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1684 void Template::SetLazyDataProperty(v8::Local<Name> name,
1685                                    AccessorNameGetterCallback getter,
1686                                    v8::Local<Value> data,
1687                                    PropertyAttribute attribute,
1688                                    SideEffectType getter_side_effect_type,
1689                                    SideEffectType setter_side_effect_type) {
1690   TemplateSetAccessor(this, name, getter,
1691                       static_cast<AccessorNameSetterCallback>(nullptr), data,
1692                       DEFAULT, attribute, Local<AccessorSignature>(), true,
1693                       true, getter_side_effect_type, setter_side_effect_type);
1694 }
1695 
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1696 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1697                                         PropertyAttribute attribute) {
1698   auto templ = Utils::OpenHandle(this);
1699   i::Isolate* isolate = templ->GetIsolate();
1700   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1701   i::HandleScope scope(isolate);
1702   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1703                                  intrinsic,
1704                                  static_cast<i::PropertyAttributes>(attribute));
1705 }
1706 
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1707 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1708                                  AccessorGetterCallback getter,
1709                                  AccessorSetterCallback setter,
1710                                  v8::Local<Value> data, AccessControl settings,
1711                                  PropertyAttribute attribute,
1712                                  SideEffectType getter_side_effect_type,
1713                                  SideEffectType setter_side_effect_type) {
1714   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1715                       Local<AccessorSignature>(),
1716                       i::FLAG_disable_old_api_accessors, false,
1717                       getter_side_effect_type, setter_side_effect_type);
1718 }
1719 
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1720 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1721                                  AccessorNameGetterCallback getter,
1722                                  AccessorNameSetterCallback setter,
1723                                  v8::Local<Value> data, AccessControl settings,
1724                                  PropertyAttribute attribute,
1725                                  SideEffectType getter_side_effect_type,
1726                                  SideEffectType setter_side_effect_type) {
1727   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1728                       Local<AccessorSignature>(),
1729                       i::FLAG_disable_old_api_accessors, false,
1730                       getter_side_effect_type, setter_side_effect_type);
1731 }
1732 
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1733 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1734                                  AccessorGetterCallback getter,
1735                                  AccessorSetterCallback setter,
1736                                  v8::Local<Value> data, AccessControl settings,
1737                                  PropertyAttribute attribute,
1738                                  v8::Local<AccessorSignature> signature,
1739                                  SideEffectType getter_side_effect_type,
1740                                  SideEffectType setter_side_effect_type) {
1741   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1742                       signature, i::FLAG_disable_old_api_accessors, false,
1743                       getter_side_effect_type, setter_side_effect_type);
1744 }
1745 
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1746 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1747                                  AccessorNameGetterCallback getter,
1748                                  AccessorNameSetterCallback setter,
1749                                  v8::Local<Value> data, AccessControl settings,
1750                                  PropertyAttribute attribute,
1751                                  v8::Local<AccessorSignature> signature,
1752                                  SideEffectType getter_side_effect_type,
1753                                  SideEffectType setter_side_effect_type) {
1754   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1755                       signature, i::FLAG_disable_old_api_accessors, false,
1756                       getter_side_effect_type, setter_side_effect_type);
1757 }
1758 
1759 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1760           typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1761 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1762     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1763     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1764     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1765   auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1766       i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1767   obj->set_flags(0);
1768 
1769   if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1770   if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1771   if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1772   if (descriptor != nullptr)
1773     SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1774   if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1775   if (enumerator != nullptr)
1776     SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1777   if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1778   obj->set_can_intercept_symbols(
1779       !(static_cast<int>(flags) &
1780         static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1781   obj->set_all_can_read(static_cast<int>(flags) &
1782                         static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1783   obj->set_non_masking(static_cast<int>(flags) &
1784                        static_cast<int>(PropertyHandlerFlags::kNonMasking));
1785   obj->set_has_no_side_effect(
1786       static_cast<int>(flags) &
1787       static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1788 
1789   if (data.IsEmpty()) {
1790     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1791   }
1792   obj->set_data(*Utils::OpenHandle(*data));
1793   return obj;
1794 }
1795 
1796 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1797           typename Deleter, typename Enumerator, typename Definer>
CreateNamedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1798 static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1799     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1800     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1801     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1802   auto interceptor =
1803       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1804                             enumerator, definer, data, flags);
1805   interceptor->set_is_named(true);
1806   return interceptor;
1807 }
1808 
1809 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1810           typename Deleter, typename Enumerator, typename Definer>
CreateIndexedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1811 static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1812     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1813     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1814     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1815   auto interceptor =
1816       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1817                             enumerator, definer, data, flags);
1818   interceptor->set_is_named(false);
1819   return interceptor;
1820 }
1821 
1822 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1823           typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1824 static void ObjectTemplateSetNamedPropertyHandler(
1825     ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1826     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1827     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1828   i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1829   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1830   i::HandleScope scope(isolate);
1831   auto cons = EnsureConstructor(isolate, templ);
1832   EnsureNotPublished(cons, "ObjectTemplateSetNamedPropertyHandler");
1833   auto obj =
1834       CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1835                                  remover, enumerator, definer, data, flags);
1836   i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1837 }
1838 
SetHandler(const NamedPropertyHandlerConfiguration & config)1839 void ObjectTemplate::SetHandler(
1840     const NamedPropertyHandlerConfiguration& config) {
1841   ObjectTemplateSetNamedPropertyHandler(
1842       this, config.getter, config.setter, config.query, config.descriptor,
1843       config.deleter, config.enumerator, config.definer, config.data,
1844       config.flags);
1845 }
1846 
MarkAsUndetectable()1847 void ObjectTemplate::MarkAsUndetectable() {
1848   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1849   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1850   i::HandleScope scope(isolate);
1851   auto cons = EnsureConstructor(isolate, this);
1852   EnsureNotPublished(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1853   cons->set_undetectable(true);
1854 }
1855 
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1856 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1857                                             Local<Value> data) {
1858   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1859   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1860   i::HandleScope scope(isolate);
1861   auto cons = EnsureConstructor(isolate, this);
1862   EnsureNotPublished(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1863 
1864   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1865       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1866   i::Handle<i::AccessCheckInfo> info =
1867       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1868 
1869   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1870   info->set_named_interceptor(i::Object());
1871   info->set_indexed_interceptor(i::Object());
1872 
1873   if (data.IsEmpty()) {
1874     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1875   }
1876   info->set_data(*Utils::OpenHandle(*data));
1877 
1878   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1879   cons->set_needs_access_check(true);
1880 }
1881 
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1882 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1883     AccessCheckCallback callback,
1884     const NamedPropertyHandlerConfiguration& named_handler,
1885     const IndexedPropertyHandlerConfiguration& indexed_handler,
1886     Local<Value> data) {
1887   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1888   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1889   i::HandleScope scope(isolate);
1890   auto cons = EnsureConstructor(isolate, this);
1891   EnsureNotPublished(cons,
1892                      "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1893 
1894   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1895       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1896   i::Handle<i::AccessCheckInfo> info =
1897       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1898 
1899   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1900   auto named_interceptor = CreateNamedInterceptorInfo(
1901       isolate, named_handler.getter, named_handler.setter, named_handler.query,
1902       named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1903       named_handler.definer, named_handler.data, named_handler.flags);
1904   info->set_named_interceptor(*named_interceptor);
1905   auto indexed_interceptor = CreateIndexedInterceptorInfo(
1906       isolate, indexed_handler.getter, indexed_handler.setter,
1907       indexed_handler.query, indexed_handler.descriptor,
1908       indexed_handler.deleter, indexed_handler.enumerator,
1909       indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1910   info->set_indexed_interceptor(*indexed_interceptor);
1911 
1912   if (data.IsEmpty()) {
1913     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1914   }
1915   info->set_data(*Utils::OpenHandle(*data));
1916 
1917   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1918   cons->set_needs_access_check(true);
1919 }
1920 
SetHandler(const IndexedPropertyHandlerConfiguration & config)1921 void ObjectTemplate::SetHandler(
1922     const IndexedPropertyHandlerConfiguration& config) {
1923   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1924   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1925   i::HandleScope scope(isolate);
1926   auto cons = EnsureConstructor(isolate, this);
1927   EnsureNotPublished(cons, "v8::ObjectTemplate::SetHandler");
1928   auto obj = CreateIndexedInterceptorInfo(
1929       isolate, config.getter, config.setter, config.query, config.descriptor,
1930       config.deleter, config.enumerator, config.definer, config.data,
1931       config.flags);
1932   i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1933 }
1934 
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1935 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1936                                               Local<Value> data) {
1937   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1938   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1939   i::HandleScope scope(isolate);
1940   auto cons = EnsureConstructor(isolate, this);
1941   EnsureNotPublished(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1942   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1943   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1944   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1945   if (data.IsEmpty()) {
1946     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1947   }
1948   obj->set_data(*Utils::OpenHandle(*data));
1949   i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1950 }
1951 
InternalFieldCount() const1952 int ObjectTemplate::InternalFieldCount() const {
1953   return Utils::OpenHandle(this)->embedder_field_count();
1954 }
1955 
SetInternalFieldCount(int value)1956 void ObjectTemplate::SetInternalFieldCount(int value) {
1957   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1958   if (!Utils::ApiCheck(i::Smi::IsValid(value),
1959                        "v8::ObjectTemplate::SetInternalFieldCount()",
1960                        "Invalid embedder field count")) {
1961     return;
1962   }
1963   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1964   if (value > 0) {
1965     // The embedder field count is set by the constructor function's
1966     // construct code, so we ensure that there is a constructor
1967     // function to do the setting.
1968     EnsureConstructor(isolate, this);
1969   }
1970   Utils::OpenHandle(this)->set_embedder_field_count(value);
1971 }
1972 
IsImmutableProto() const1973 bool ObjectTemplate::IsImmutableProto() const {
1974   return Utils::OpenHandle(this)->immutable_proto();
1975 }
1976 
SetImmutableProto()1977 void ObjectTemplate::SetImmutableProto() {
1978   auto self = Utils::OpenHandle(this);
1979   i::Isolate* isolate = self->GetIsolate();
1980   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1981   self->set_immutable_proto(true);
1982 }
1983 
IsCodeLike() const1984 bool ObjectTemplate::IsCodeLike() const {
1985   return Utils::OpenHandle(this)->code_like();
1986 }
1987 
SetCodeLike()1988 void ObjectTemplate::SetCodeLike() {
1989   auto self = Utils::OpenHandle(this);
1990   i::Isolate* isolate = self->GetIsolate();
1991   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1992   self->set_code_like(true);
1993 }
1994 
1995 // --- S c r i p t s ---
1996 
1997 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1998 // JSFunction.
1999 
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)2000 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
2001                                        BufferPolicy buffer_policy_)
2002     : data(data_),
2003       length(length_),
2004       rejected(false),
2005       buffer_policy(buffer_policy_) {}
2006 
~CachedData()2007 ScriptCompiler::CachedData::~CachedData() {
2008   if (buffer_policy == BufferOwned) {
2009     delete[] data;
2010   }
2011 }
2012 
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)2013 ScriptCompiler::StreamedSource::StreamedSource(
2014     std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2015     : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2016 
2017 ScriptCompiler::StreamedSource::~StreamedSource() = default;
2018 
BindToCurrentContext()2019 Local<Script> UnboundScript::BindToCurrentContext() {
2020   auto function_info =
2021       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2022   i::Isolate* isolate = function_info->GetIsolate();
2023   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2024   i::Handle<i::JSFunction> function =
2025       i::Factory::JSFunctionBuilder{isolate, function_info,
2026                                     isolate->native_context()}
2027           .Build();
2028   return ToApiHandle<Script>(function);
2029 }
2030 
GetId() const2031 int UnboundScript::GetId() const {
2032   auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
2033   API_RCS_SCOPE(function_info.GetIsolate(), UnboundScript, GetId);
2034   return i::Script::cast(function_info.script()).id();
2035 }
2036 
GetLineNumber(int code_pos)2037 int UnboundScript::GetLineNumber(int code_pos) {
2038   i::Handle<i::SharedFunctionInfo> obj =
2039       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2040   i::Isolate* isolate = obj->GetIsolate();
2041   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2042   API_RCS_SCOPE(isolate, UnboundScript, GetLineNumber);
2043   if (obj->script().IsScript()) {
2044     i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2045     return i::Script::GetLineNumber(script, code_pos);
2046   } else {
2047     return -1;
2048   }
2049 }
2050 
GetScriptName()2051 Local<Value> UnboundScript::GetScriptName() {
2052   i::Handle<i::SharedFunctionInfo> obj =
2053       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2054   i::Isolate* isolate = obj->GetIsolate();
2055   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2056   API_RCS_SCOPE(isolate, UnboundScript, GetName);
2057   if (obj->script().IsScript()) {
2058     i::Object name = i::Script::cast(obj->script()).name();
2059     return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2060   } else {
2061     return Local<String>();
2062   }
2063 }
2064 
GetSourceURL()2065 Local<Value> UnboundScript::GetSourceURL() {
2066   i::Handle<i::SharedFunctionInfo> obj =
2067       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2068   i::Isolate* isolate = obj->GetIsolate();
2069   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2070   API_RCS_SCOPE(isolate, UnboundScript, GetSourceURL);
2071   if (obj->script().IsScript()) {
2072     i::Object url = i::Script::cast(obj->script()).source_url();
2073     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2074   } else {
2075     return Local<String>();
2076   }
2077 }
2078 
GetSourceMappingURL()2079 Local<Value> UnboundScript::GetSourceMappingURL() {
2080   i::Handle<i::SharedFunctionInfo> obj =
2081       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2082   i::Isolate* isolate = obj->GetIsolate();
2083   API_RCS_SCOPE(isolate, UnboundScript, GetSourceMappingURL);
2084   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2085   if (obj->script().IsScript()) {
2086     i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2087     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2088   } else {
2089     return Local<String>();
2090   }
2091 }
2092 
Run(Local<Context> context)2093 MaybeLocal<Value> Script::Run(Local<Context> context) {
2094   return Run(context, Local<Data>());
2095 }
2096 
Run(Local<Context> context,Local<Data> host_defined_options)2097 MaybeLocal<Value> Script::Run(Local<Context> context,
2098                               Local<Data> host_defined_options) {
2099   auto v8_isolate = context->GetIsolate();
2100   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2101   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2102   ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2103            InternalEscapableScope);
2104   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2105   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2106                                              isolate);
2107   i::AggregatingHistogramTimerScope histogram_timer(
2108       isolate->counters()->compile_lazy());
2109   auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2110 
2111   // TODO(crbug.com/1193459): remove once ablation study is completed
2112   base::ElapsedTimer timer;
2113   base::TimeDelta delta;
2114   if (i::FLAG_script_delay > 0) {
2115     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay);
2116   }
2117   if (i::FLAG_script_delay_once > 0 && !isolate->did_run_script_delay()) {
2118     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay_once);
2119     isolate->set_did_run_script_delay(true);
2120   }
2121   if (i::FLAG_script_delay_fraction > 0.0) {
2122     timer.Start();
2123   } else if (delta.InMicroseconds() > 0) {
2124     timer.Start();
2125     while (timer.Elapsed() < delta) {
2126       // Busy wait.
2127     }
2128   }
2129 
2130   if (V8_UNLIKELY(i::FLAG_experimental_web_snapshots)) {
2131     i::Handle<i::HeapObject> maybe_script =
2132         handle(fun->shared().script(), isolate);
2133     if (maybe_script->IsScript() &&
2134         i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
2135       i::WebSnapshotDeserializer deserializer(
2136           reinterpret_cast<i::Isolate*>(v8_isolate),
2137           i::Handle<i::Script>::cast(maybe_script));
2138       deserializer.Deserialize();
2139       RETURN_ON_FAILED_EXECUTION(Value);
2140       Local<Value> result = v8::Undefined(v8_isolate);
2141       RETURN_ESCAPED(result);
2142     }
2143   }
2144 
2145   i::Handle<i::Object> receiver = isolate->global_proxy();
2146   // TODO(cbruni, chromium:1244145): Remove once migrated to the context.
2147   i::Handle<i::Object> options(
2148       i::Script::cast(fun->shared().script()).host_defined_options(), isolate);
2149   Local<Value> result;
2150   has_pending_exception = !ToLocal<Value>(
2151       i::Execution::CallScript(isolate, fun, receiver, options), &result);
2152 
2153   if (i::FLAG_script_delay_fraction > 0.0) {
2154     delta = v8::base::TimeDelta::FromMillisecondsD(
2155         timer.Elapsed().InMillisecondsF() * i::FLAG_script_delay_fraction);
2156     timer.Restart();
2157     while (timer.Elapsed() < delta) {
2158       // Busy wait.
2159     }
2160   }
2161 
2162   RETURN_ON_FAILED_EXECUTION(Value);
2163   RETURN_ESCAPED(result);
2164 }
2165 
GetResourceName()2166 Local<Value> ScriptOrModule::GetResourceName() {
2167   i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2168   i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2169   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2170   i::Handle<i::Object> val(obj->resource_name(), isolate);
2171   return ToApiHandle<Value>(val);
2172 }
2173 
GetHostDefinedOptions()2174 Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2175   return HostDefinedOptions().As<PrimitiveArray>();
2176 }
2177 
HostDefinedOptions()2178 Local<Data> ScriptOrModule::HostDefinedOptions() {
2179   i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2180   i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2181   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2182   i::Handle<i::Object> val(obj->host_defined_options(), isolate);
2183   return ToApiHandle<Data>(val);
2184 }
2185 
GetUnboundScript()2186 Local<UnboundScript> Script::GetUnboundScript() {
2187   i::DisallowGarbageCollection no_gc;
2188   i::Handle<i::JSFunction> obj = Utils::OpenHandle(this);
2189   i::SharedFunctionInfo sfi = (*obj).shared();
2190   i::Isolate* isolate = sfi.GetIsolate();
2191   return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2192 }
2193 
GetResourceName()2194 Local<Value> Script::GetResourceName() {
2195   i::DisallowGarbageCollection no_gc;
2196   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2197   i::SharedFunctionInfo sfi = (*func).shared();
2198   i::Isolate* isolate = func->GetIsolate();
2199   CHECK(sfi.script().IsScript());
2200   return ToApiHandle<Value>(
2201       i::handle(i::Script::cast(sfi.script()).name(), isolate));
2202 }
2203 
2204 // static
New(Isolate * v8_isolate,int length)2205 Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2206   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2207   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2208   Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2209                   "length must be equal or greater than zero");
2210   i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2211   return ToApiHandle<PrimitiveArray>(array);
2212 }
2213 
Length() const2214 int PrimitiveArray::Length() const {
2215   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2216   return array->length();
2217 }
2218 
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2219 void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2220                          Local<Primitive> item) {
2221   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2222   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2223   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2224   Utils::ApiCheck(index >= 0 && index < array->length(),
2225                   "v8::PrimitiveArray::Set",
2226                   "index must be greater than or equal to 0 and less than the "
2227                   "array length");
2228   i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2229   array->set(index, *i_item);
2230 }
2231 
Get(Isolate * v8_isolate,int index)2232 Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2233   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2234   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2235   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2236   Utils::ApiCheck(index >= 0 && index < array->length(),
2237                   "v8::PrimitiveArray::Get",
2238                   "index must be greater than or equal to 0 and less than the "
2239                   "array length");
2240   i::Handle<i::Object> i_item(array->get(index), isolate);
2241   return ToApiHandle<Primitive>(i_item);
2242 }
2243 
CheckCast(v8::Data * that)2244 void v8::PrimitiveArray::CheckCast(v8::Data* that) {
2245   i::Handle<i::Object> obj = Utils::OpenHandle(that);
2246   Utils::ApiCheck(
2247       obj->IsFixedArray(), "v8::PrimitiveArray::Cast",
2248       "Value is not a PrimitiveArray. This is a temporary issue, v8::Data and "
2249       "v8::PrimitiveArray will not be compatible in the future.");
2250 }
2251 
Length() const2252 int FixedArray::Length() const {
2253   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2254   return self->length();
2255 }
2256 
Get(Local<Context> context,int i) const2257 Local<Data> FixedArray::Get(Local<Context> context, int i) const {
2258   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2259   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2260   CHECK_LT(i, self->length());
2261   i::Handle<i::Object> entry(self->get(i), isolate);
2262   return ToApiHandle<Data>(entry);
2263 }
2264 
GetSpecifier() const2265 Local<String> ModuleRequest::GetSpecifier() const {
2266   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2267   i::Isolate* isolate = self->GetIsolate();
2268   return ToApiHandle<String>(i::handle(self->specifier(), isolate));
2269 }
2270 
GetSourceOffset() const2271 int ModuleRequest::GetSourceOffset() const {
2272   return Utils::OpenHandle(this)->position();
2273 }
2274 
GetImportAssertions() const2275 Local<FixedArray> ModuleRequest::GetImportAssertions() const {
2276   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2277   i::Isolate* isolate = self->GetIsolate();
2278   return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate));
2279 }
2280 
GetStatus() const2281 Module::Status Module::GetStatus() const {
2282   i::Handle<i::Module> self = Utils::OpenHandle(this);
2283   switch (self->status()) {
2284     case i::Module::kUnlinked:
2285     case i::Module::kPreLinking:
2286       return kUninstantiated;
2287     case i::Module::kLinking:
2288       return kInstantiating;
2289     case i::Module::kLinked:
2290       return kInstantiated;
2291     case i::Module::kEvaluating:
2292     case i::Module::kEvaluatingAsync:
2293       return kEvaluating;
2294     case i::Module::kEvaluated:
2295       return kEvaluated;
2296     case i::Module::kErrored:
2297       return kErrored;
2298   }
2299   UNREACHABLE();
2300 }
2301 
GetException() const2302 Local<Value> Module::GetException() const {
2303   Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2304                   "Module status must be kErrored");
2305   i::Handle<i::Module> self = Utils::OpenHandle(this);
2306   i::Isolate* isolate = self->GetIsolate();
2307   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2308   return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2309 }
2310 
GetModuleRequests() const2311 Local<FixedArray> Module::GetModuleRequests() const {
2312   i::Handle<i::Module> self = Utils::OpenHandle(this);
2313   if (self->IsSyntheticModule()) {
2314     // Synthetic modules are leaf nodes in the module graph. They have no
2315     // ModuleRequests.
2316     return ToApiHandle<FixedArray>(
2317         self->GetReadOnlyRoots().empty_fixed_array_handle());
2318   } else {
2319     i::Isolate* isolate = self->GetIsolate();
2320     i::Handle<i::FixedArray> module_requests(
2321         i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2322         isolate);
2323     return ToApiHandle<FixedArray>(module_requests);
2324   }
2325 }
2326 
SourceOffsetToLocation(int offset) const2327 Location Module::SourceOffsetToLocation(int offset) const {
2328   i::Handle<i::Module> self = Utils::OpenHandle(this);
2329   i::Isolate* isolate = self->GetIsolate();
2330   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2331   i::HandleScope scope(isolate);
2332   Utils::ApiCheck(
2333       self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation",
2334       "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule");
2335   i::Handle<i::Script> script(
2336       i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2337   i::Script::PositionInfo info;
2338   i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
2339   return v8::Location(info.line, info.column);
2340 }
2341 
GetModuleNamespace()2342 Local<Value> Module::GetModuleNamespace() {
2343   Utils::ApiCheck(
2344       GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2345       "v8::Module::GetModuleNamespace must be used on an instantiated module");
2346   i::Handle<i::Module> self = Utils::OpenHandle(this);
2347   auto isolate = self->GetIsolate();
2348   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2349   i::Handle<i::JSModuleNamespace> module_namespace =
2350       i::Module::GetModuleNamespace(isolate, self);
2351   return ToApiHandle<Value>(module_namespace);
2352 }
2353 
GetUnboundModuleScript()2354 Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2355   i::Handle<i::Module> self = Utils::OpenHandle(this);
2356   Utils::ApiCheck(
2357       self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript",
2358       "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule");
2359   auto isolate = self->GetIsolate();
2360   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2361   return ToApiHandle<UnboundModuleScript>(i::handle(
2362       i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2363       isolate));
2364 }
2365 
ScriptId() const2366 int Module::ScriptId() const {
2367   i::Module self = *Utils::OpenHandle(this);
2368   Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
2369                   "v8::Module::ScriptId must be used on an SourceTextModule");
2370   ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2371   return i::SourceTextModule::cast(self).GetScript().id();
2372 }
2373 
IsGraphAsync() const2374 bool Module::IsGraphAsync() const {
2375   Utils::ApiCheck(
2376       GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2377       "v8::Module::IsGraphAsync must be used on an instantiated module");
2378   i::Module self = *Utils::OpenHandle(this);
2379   auto isolate = self.GetIsolate();
2380   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2381   return self.IsGraphAsync(isolate);
2382 }
2383 
IsSourceTextModule() const2384 bool Module::IsSourceTextModule() const {
2385   return Utils::OpenHandle(this)->IsSourceTextModule();
2386 }
2387 
IsSyntheticModule() const2388 bool Module::IsSyntheticModule() const {
2389   return Utils::OpenHandle(this)->IsSyntheticModule();
2390 }
2391 
GetIdentityHash() const2392 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2393 
InstantiateModule(Local<Context> context,Module::ResolveModuleCallback callback)2394 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2395                                       Module::ResolveModuleCallback callback) {
2396   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2397   ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2398            i::HandleScope);
2399   has_pending_exception = !i::Module::Instantiate(
2400       isolate, Utils::OpenHandle(this), context, callback, nullptr);
2401   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2402   return Just(true);
2403 }
2404 
Evaluate(Local<Context> context)2405 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2406   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2407   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2408   ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2409            InternalEscapableScope);
2410   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2411   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2412                                              isolate);
2413   i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2414 
2415   i::Handle<i::Module> self = Utils::OpenHandle(this);
2416   Utils::ApiCheck(self->status() >= i::Module::kLinked, "Module::Evaluate",
2417                   "Expected instantiated module");
2418 
2419   Local<Value> result;
2420   has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2421   RETURN_ON_FAILED_EXECUTION(Value);
2422   RETURN_ESCAPED(result);
2423 }
2424 
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2425 Local<Module> Module::CreateSyntheticModule(
2426     Isolate* isolate, Local<String> module_name,
2427     const std::vector<Local<v8::String>>& export_names,
2428     v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2429   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2430   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
2431   i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2432   i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2433       static_cast<int>(export_names.size()));
2434   for (int i = 0; i < i_export_names->length(); ++i) {
2435     i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2436         Utils::OpenHandle(*export_names[i]));
2437     i_export_names->set(i, *str);
2438   }
2439   return v8::Utils::ToLocal(
2440       i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2441           i_module_name, i_export_names, evaluation_steps)));
2442 }
2443 
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2444 Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2445                                              Local<String> export_name,
2446                                              Local<v8::Value> export_value) {
2447   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2448   i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2449   i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2450   i::Handle<i::Module> self = Utils::OpenHandle(this);
2451   Utils::ApiCheck(self->IsSyntheticModule(),
2452                   "v8::Module::SyntheticModuleSetExport",
2453                   "v8::Module::SyntheticModuleSetExport must only be called on "
2454                   "a SyntheticModule");
2455   ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2456                      SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2457   has_pending_exception =
2458       i::SyntheticModule::SetExport(i_isolate,
2459                                     i::Handle<i::SyntheticModule>::cast(self),
2460                                     i_export_name, i_export_value)
2461           .IsNothing();
2462   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2463   return Just(true);
2464 }
2465 
2466 namespace {
2467 
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,int resource_line_offset,int resource_column_offset,Local<Value> source_map_url,Local<Data> host_defined_options,ScriptOriginOptions origin_options)2468 i::ScriptDetails GetScriptDetails(
2469     i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset,
2470     int resource_column_offset, Local<Value> source_map_url,
2471     Local<Data> host_defined_options, ScriptOriginOptions origin_options) {
2472   i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
2473                                   origin_options);
2474   script_details.line_offset = resource_line_offset;
2475   script_details.column_offset = resource_column_offset;
2476   script_details.host_defined_options =
2477       host_defined_options.IsEmpty()
2478           ? isolate->factory()->empty_fixed_array()
2479           : Utils::OpenHandle(*(host_defined_options));
2480   if (!source_map_url.IsEmpty()) {
2481     script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2482   }
2483   return script_details;
2484 }
2485 
2486 }  // namespace
2487 
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2488 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2489     Isolate* v8_isolate, Source* source, CompileOptions options,
2490     NoCacheReason no_cache_reason) {
2491   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2492   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2493   ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2494                      CompileUnbound, MaybeLocal<UnboundScript>(),
2495                      InternalEscapableScope);
2496 
2497   i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2498 
2499   i::Handle<i::SharedFunctionInfo> result;
2500   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2501   i::ScriptDetails script_details = GetScriptDetails(
2502       isolate, source->resource_name, source->resource_line_offset,
2503       source->resource_column_offset, source->source_map_url,
2504       source->host_defined_options, source->resource_options);
2505 
2506   i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info;
2507   if (options == kConsumeCodeCache) {
2508     if (source->consume_cache_task) {
2509       // Take ownership of the internal deserialization task and clear it off
2510       // the consume task on the source.
2511       DCHECK_NOT_NULL(source->consume_cache_task->impl_);
2512       std::unique_ptr<i::BackgroundDeserializeTask> deserialize_task =
2513           std::move(source->consume_cache_task->impl_);
2514       maybe_function_info =
2515           i::Compiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
2516               isolate, str, script_details, deserialize_task.get(), options,
2517               no_cache_reason, i::NOT_NATIVES_CODE);
2518       source->cached_data->rejected = deserialize_task->rejected();
2519     } else {
2520       DCHECK(source->cached_data);
2521       // AlignedCachedData takes care of pointer-aligning the data.
2522       auto cached_data = std::make_unique<i::AlignedCachedData>(
2523           source->cached_data->data, source->cached_data->length);
2524       maybe_function_info =
2525           i::Compiler::GetSharedFunctionInfoForScriptWithCachedData(
2526               isolate, str, script_details, cached_data.get(), options,
2527               no_cache_reason, i::NOT_NATIVES_CODE);
2528       source->cached_data->rejected = cached_data->rejected();
2529     }
2530   } else {
2531     // Compile without any cache.
2532     maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript(
2533         isolate, str, script_details, options, no_cache_reason,
2534         i::NOT_NATIVES_CODE);
2535   }
2536 
2537   has_pending_exception = !maybe_function_info.ToHandle(&result);
2538   RETURN_ON_FAILED_EXECUTION(UnboundScript);
2539   RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2540 }
2541 
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2542 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2543     Isolate* v8_isolate, Source* source, CompileOptions options,
2544     NoCacheReason no_cache_reason) {
2545   Utils::ApiCheck(
2546       !source->GetResourceOptions().IsModule(),
2547       "v8::ScriptCompiler::CompileUnboundScript",
2548       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2549   return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2550 }
2551 
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2552 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2553                                            Source* source,
2554                                            CompileOptions options,
2555                                            NoCacheReason no_cache_reason) {
2556   Utils::ApiCheck(
2557       !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2558       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2559   auto isolate = context->GetIsolate();
2560   MaybeLocal<UnboundScript> maybe =
2561       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2562   Local<UnboundScript> result;
2563   if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2564   v8::Context::Scope scope(context);
2565   return result->BindToCurrentContext();
2566 }
2567 
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2568 MaybeLocal<Module> ScriptCompiler::CompileModule(
2569     Isolate* isolate, Source* source, CompileOptions options,
2570     NoCacheReason no_cache_reason) {
2571   Utils::ApiCheck(options == kNoCompileOptions || options == kConsumeCodeCache,
2572                   "v8::ScriptCompiler::CompileModule",
2573                   "Invalid CompileOptions");
2574   Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2575                   "v8::ScriptCompiler::CompileModule",
2576                   "Invalid ScriptOrigin: is_module must be true");
2577   MaybeLocal<UnboundScript> maybe =
2578       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2579   Local<UnboundScript> unbound;
2580   if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2581   i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2582   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2583   return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2584 }
2585 
2586 // static
CompileFunction(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason)2587 V8_WARN_UNUSED_RESULT MaybeLocal<Function> ScriptCompiler::CompileFunction(
2588     Local<Context> context, Source* source, size_t arguments_count,
2589     Local<String> arguments[], size_t context_extension_count,
2590     Local<Object> context_extensions[], CompileOptions options,
2591     NoCacheReason no_cache_reason) {
2592   return CompileFunctionInternal(context, source, arguments_count, arguments,
2593                                  context_extension_count, context_extensions,
2594                                  options, no_cache_reason, nullptr);
2595 }
2596 
2597 // static
CompileFunctionInContext(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2598 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2599     Local<Context> context, Source* source, size_t arguments_count,
2600     Local<String> arguments[], size_t context_extension_count,
2601     Local<Object> context_extensions[], CompileOptions options,
2602     NoCacheReason no_cache_reason,
2603     Local<ScriptOrModule>* script_or_module_out) {
2604   return CompileFunctionInternal(
2605       context, source, arguments_count, arguments, context_extension_count,
2606       context_extensions, options, no_cache_reason, script_or_module_out);
2607 }
2608 
CompileFunctionInternal(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2609 MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
2610     Local<Context> v8_context, Source* source, size_t arguments_count,
2611     Local<String> arguments[], size_t context_extension_count,
2612     Local<Object> context_extensions[], CompileOptions options,
2613     NoCacheReason no_cache_reason,
2614     Local<ScriptOrModule>* script_or_module_out) {
2615   Local<Function> result;
2616 
2617   {
2618     PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunction,
2619                           Function);
2620     TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2621 
2622     DCHECK(options == CompileOptions::kConsumeCodeCache ||
2623            options == CompileOptions::kEagerCompile ||
2624            options == CompileOptions::kNoCompileOptions);
2625 
2626     i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2627 
2628     DCHECK(context->IsNativeContext());
2629 
2630     i::Handle<i::FixedArray> arguments_list =
2631         isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2632     for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2633       i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2634       if (!i::String::IsIdentifier(isolate, argument)) return Local<Function>();
2635       arguments_list->set(i, *argument);
2636     }
2637 
2638     for (size_t i = 0; i < context_extension_count; ++i) {
2639       i::Handle<i::JSReceiver> extension =
2640           Utils::OpenHandle(*context_extensions[i]);
2641       if (!extension->IsJSObject()) return Local<Function>();
2642       context = isolate->factory()->NewWithContext(
2643           context,
2644           i::ScopeInfo::CreateForWithScope(
2645               isolate,
2646               context->IsNativeContext()
2647                   ? i::Handle<i::ScopeInfo>::null()
2648                   : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2649           extension);
2650     }
2651 
2652     i::ScriptDetails script_details = GetScriptDetails(
2653         isolate, source->resource_name, source->resource_line_offset,
2654         source->resource_column_offset, source->source_map_url,
2655         source->host_defined_options, source->resource_options);
2656 
2657     std::unique_ptr<i::AlignedCachedData> cached_data;
2658     if (options == kConsumeCodeCache) {
2659       DCHECK(source->cached_data);
2660       // ScriptData takes care of pointer-aligning the data.
2661       cached_data.reset(new i::AlignedCachedData(source->cached_data->data,
2662                                                  source->cached_data->length));
2663     }
2664 
2665     i::Handle<i::JSFunction> scoped_result;
2666     has_pending_exception =
2667         !i::Compiler::GetWrappedFunction(
2668              Utils::OpenHandle(*source->source_string), arguments_list, context,
2669              script_details, cached_data.get(), options, no_cache_reason)
2670              .ToHandle(&scoped_result);
2671     if (options == kConsumeCodeCache) {
2672       source->cached_data->rejected = cached_data->rejected();
2673     }
2674     RETURN_ON_FAILED_EXECUTION(Function);
2675     result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2676   }
2677   // TODO(cbruni): remove script_or_module_out paramater
2678   if (script_or_module_out != nullptr) {
2679     i::Handle<i::JSFunction> function =
2680         i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2681     i::Isolate* isolate = function->GetIsolate();
2682     i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2683     i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2684     // TODO(cbruni, v8:12302): Avoid creating tempory ScriptOrModule objects.
2685     auto script_or_module = i::Handle<i::ScriptOrModule>::cast(
2686         isolate->factory()->NewStruct(i::SCRIPT_OR_MODULE_TYPE));
2687     script_or_module->set_resource_name(script->name());
2688     script_or_module->set_host_defined_options(script->host_defined_options());
2689 #ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
2690     i::Handle<i::ArrayList> list =
2691         i::handle(script->script_or_modules(), isolate);
2692     list = i::ArrayList::Add(isolate, list, script_or_module);
2693     script->set_script_or_modules(*list);
2694 #endif  // V8_SCRIPTORMODULE_LEGACY_LIFETIME
2695     *script_or_module_out = v8::Utils::ToLocal(script_or_module);
2696   }
2697   return result;
2698 }
2699 
Run()2700 void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2701 
StartStreaming(Isolate * v8_isolate,StreamedSource * source,v8::ScriptType type)2702 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2703     Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) {
2704   if (!i::FLAG_script_streaming) return nullptr;
2705   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2706   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2707   i::ScriptStreamingData* data = source->impl();
2708   std::unique_ptr<i::BackgroundCompileTask> task =
2709       std::make_unique<i::BackgroundCompileTask>(data, isolate, type);
2710   data->task = std::move(task);
2711   return new ScriptCompiler::ScriptStreamingTask(data);
2712 }
2713 
ConsumeCodeCacheTask(std::unique_ptr<i::BackgroundDeserializeTask> impl)2714 ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2715     std::unique_ptr<i::BackgroundDeserializeTask> impl)
2716     : impl_(std::move(impl)) {}
2717 
2718 ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2719 
Run()2720 void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2721 
StartConsumingCodeCache(Isolate * v8_isolate,std::unique_ptr<CachedData> cached_data)2722 ScriptCompiler::ConsumeCodeCacheTask* ScriptCompiler::StartConsumingCodeCache(
2723     Isolate* v8_isolate, std::unique_ptr<CachedData> cached_data) {
2724   if (!i::FLAG_concurrent_cache_deserialization) return nullptr;
2725   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2726   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2727   return new ScriptCompiler::ConsumeCodeCacheTask(
2728       std::make_unique<i::BackgroundDeserializeTask>(isolate,
2729                                                      std::move(cached_data)));
2730 }
2731 
2732 namespace {
CompileStreamedSource(i::Isolate * isolate,ScriptCompiler::StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2733 i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
2734     i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source,
2735     Local<String> full_source_string, const ScriptOrigin& origin) {
2736   i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2737   i::ScriptDetails script_details =
2738       GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
2739                        origin.ColumnOffset(), origin.SourceMapUrl(),
2740                        origin.GetHostDefinedOptions(), origin.Options());
2741   i::ScriptStreamingData* data = v8_source->impl();
2742   return i::Compiler::GetSharedFunctionInfoForStreamedScript(
2743       isolate, str, script_details, data);
2744 }
2745 
2746 }  // namespace
2747 
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2748 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2749                                            StreamedSource* v8_source,
2750                                            Local<String> full_source_string,
2751                                            const ScriptOrigin& origin) {
2752   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2753   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2754   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2755                "V8.CompileStreamedScript");
2756   i::Handle<i::SharedFunctionInfo> sfi;
2757   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2758       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2759   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2760   if (has_pending_exception) isolate->ReportPendingMessages();
2761   RETURN_ON_FAILED_EXECUTION(Script);
2762   Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi);
2763   if (generic.IsEmpty()) return Local<Script>();
2764   Local<Script> bound = generic->BindToCurrentContext();
2765   if (bound.IsEmpty()) return Local<Script>();
2766   RETURN_ESCAPED(bound);
2767 }
2768 
CompileModule(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2769 MaybeLocal<Module> ScriptCompiler::CompileModule(
2770     Local<Context> context, StreamedSource* v8_source,
2771     Local<String> full_source_string, const ScriptOrigin& origin) {
2772   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module);
2773   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2774   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2775                "V8.CompileStreamedModule");
2776   i::Handle<i::SharedFunctionInfo> sfi;
2777   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2778       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2779   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2780   if (has_pending_exception) isolate->ReportPendingMessages();
2781   RETURN_ON_FAILED_EXECUTION(Module);
2782   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2783   RETURN_ESCAPED(
2784       ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi)));
2785 }
2786 
CachedDataVersionTag()2787 uint32_t ScriptCompiler::CachedDataVersionTag() {
2788   return static_cast<uint32_t>(base::hash_combine(
2789       internal::Version::Hash(), internal::FlagList::Hash(),
2790       static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2791 }
2792 
CreateCodeCache(Local<UnboundScript> unbound_script)2793 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2794     Local<UnboundScript> unbound_script) {
2795   i::Handle<i::SharedFunctionInfo> shared =
2796       i::Handle<i::SharedFunctionInfo>::cast(
2797           Utils::OpenHandle(*unbound_script));
2798   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2799   DCHECK(shared->is_toplevel());
2800   return i::CodeSerializer::Serialize(shared);
2801 }
2802 
2803 // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2804 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2805     Local<UnboundModuleScript> unbound_module_script) {
2806   i::Handle<i::SharedFunctionInfo> shared =
2807       i::Handle<i::SharedFunctionInfo>::cast(
2808           Utils::OpenHandle(*unbound_module_script));
2809   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2810   DCHECK(shared->is_toplevel());
2811   return i::CodeSerializer::Serialize(shared);
2812 }
2813 
CreateCodeCacheForFunction(Local<Function> function)2814 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2815     Local<Function> function) {
2816   auto js_function =
2817       i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2818   i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2819                                           js_function->GetIsolate());
2820   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2821   Utils::ApiCheck(shared->is_wrapped(),
2822                   "v8::ScriptCompiler::CreateCodeCacheForFunction",
2823                   "Expected SharedFunctionInfo with wrapped source code.");
2824   return i::CodeSerializer::Serialize(shared);
2825 }
2826 
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2827 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2828                                    ScriptOrigin* origin) {
2829   if (origin) {
2830     ScriptCompiler::Source script_source(source, *origin);
2831     return ScriptCompiler::Compile(context, &script_source);
2832   }
2833   ScriptCompiler::Source script_source(source);
2834   return ScriptCompiler::Compile(context, &script_source);
2835 }
2836 
2837 // --- E x c e p t i o n s ---
2838 
TryCatch(v8::Isolate * isolate)2839 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2840     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2841       next_(isolate_->try_catch_handler()),
2842       is_verbose_(false),
2843       can_continue_(true),
2844       capture_message_(true),
2845       rethrow_(false),
2846       has_terminated_(false) {
2847   ResetInternal();
2848   // Special handling for simulators which have a separate JS stack.
2849   js_stack_comparable_address_ = static_cast<internal::Address>(
2850       i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2851   isolate_->RegisterTryCatchHandler(this);
2852 }
2853 
~TryCatch()2854 v8::TryCatch::~TryCatch() {
2855   if (rethrow_) {
2856     v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2857     v8::HandleScope scope(isolate);
2858     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2859     if (HasCaught() && capture_message_) {
2860       // If an exception was caught and rethrow_ is indicated, the saved
2861       // message, script, and location need to be restored to Isolate TLS
2862       // for reuse.  capture_message_ needs to be disabled so that Throw()
2863       // does not create a new message.
2864       isolate_->thread_local_top()->rethrowing_message_ = true;
2865       isolate_->RestorePendingMessageFromTryCatch(this);
2866     }
2867     isolate_->UnregisterTryCatchHandler(this);
2868     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2869     reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2870     DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2871   } else {
2872     if (HasCaught() && isolate_->has_scheduled_exception()) {
2873       // If an exception was caught but is still scheduled because no API call
2874       // promoted it, then it is canceled to prevent it from being propagated.
2875       // Note that this will not cancel termination exceptions.
2876       isolate_->CancelScheduledExceptionFromTryCatch(this);
2877     }
2878     isolate_->UnregisterTryCatchHandler(this);
2879     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2880   }
2881 }
2882 
operator new(size_t)2883 void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2884 void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2885 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2886 void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2887 
HasCaught() const2888 bool v8::TryCatch::HasCaught() const {
2889   return !i::Object(reinterpret_cast<i::Address>(exception_))
2890               .IsTheHole(isolate_);
2891 }
2892 
CanContinue() const2893 bool v8::TryCatch::CanContinue() const { return can_continue_; }
2894 
HasTerminated() const2895 bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2896 
ReThrow()2897 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2898   if (!HasCaught()) return v8::Local<v8::Value>();
2899   rethrow_ = true;
2900   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2901 }
2902 
Exception() const2903 v8::Local<Value> v8::TryCatch::Exception() const {
2904   if (HasCaught()) {
2905     // Check for out of memory exception.
2906     i::Object exception(reinterpret_cast<i::Address>(exception_));
2907     return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2908   } else {
2909     return v8::Local<Value>();
2910   }
2911 }
2912 
StackTrace(Local<Context> context,Local<Value> exception)2913 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2914                                            Local<Value> exception) {
2915   i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2916   if (!i_exception->IsJSObject()) return v8::Local<Value>();
2917   PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2918   auto obj = i::Handle<i::JSObject>::cast(i_exception);
2919   i::Handle<i::String> name = isolate->factory()->stack_string();
2920   Maybe<bool> maybe = i::JSReceiver::HasProperty(isolate, obj, name);
2921   has_pending_exception = maybe.IsNothing();
2922   RETURN_ON_FAILED_EXECUTION(Value);
2923   if (!maybe.FromJust()) return v8::Local<Value>();
2924   Local<Value> result;
2925   has_pending_exception =
2926       !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2927   RETURN_ON_FAILED_EXECUTION(Value);
2928   RETURN_ESCAPED(result);
2929 }
2930 
StackTrace(Local<Context> context) const2931 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2932   if (!HasCaught()) return v8::Local<Value>();
2933   return StackTrace(context, Exception());
2934 }
2935 
Message() const2936 v8::Local<v8::Message> v8::TryCatch::Message() const {
2937   i::Object message(reinterpret_cast<i::Address>(message_obj_));
2938   DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2939   if (HasCaught() && !message.IsTheHole(isolate_)) {
2940     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2941   } else {
2942     return v8::Local<v8::Message>();
2943   }
2944 }
2945 
Reset()2946 void v8::TryCatch::Reset() {
2947   if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2948     // If an exception was caught but is still scheduled because no API call
2949     // promoted it, then it is canceled to prevent it from being propagated.
2950     // Note that this will not cancel termination exceptions.
2951     isolate_->CancelScheduledExceptionFromTryCatch(this);
2952   }
2953   ResetInternal();
2954 }
2955 
ResetInternal()2956 void v8::TryCatch::ResetInternal() {
2957   i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2958   exception_ = reinterpret_cast<void*>(the_hole.ptr());
2959   message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2960 }
2961 
SetVerbose(bool value)2962 void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2963 
IsVerbose() const2964 bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2965 
SetCaptureMessage(bool value)2966 void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2967 
2968 // --- M e s s a g e ---
2969 
Get() const2970 Local<String> Message::Get() const {
2971   auto self = Utils::OpenHandle(this);
2972   i::Isolate* isolate = self->GetIsolate();
2973   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2975   i::Handle<i::String> raw_result =
2976       i::MessageHandler::GetMessage(isolate, self);
2977   Local<String> result = Utils::ToLocal(raw_result);
2978   return scope.Escape(result);
2979 }
2980 
GetIsolate() const2981 v8::Isolate* Message::GetIsolate() const {
2982   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983   return reinterpret_cast<Isolate*>(isolate);
2984 }
2985 
GetScriptOrigin() const2986 ScriptOrigin Message::GetScriptOrigin() const {
2987   auto self = Utils::OpenHandle(this);
2988   i::Isolate* isolate = self->GetIsolate();
2989   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2990   i::Handle<i::Script> script(self->script(), isolate);
2991   return GetScriptOriginForScript(isolate, script);
2992 }
2993 
VerifyHostDefinedOptions() const2994 void ScriptOrigin::VerifyHostDefinedOptions() const {
2995   // TODO(cbruni, chromium:1244145): Remove checks once we allow arbitrary
2996   // host-defined options.
2997   USE(isolate_);
2998   if (host_defined_options_.IsEmpty()) return;
2999   Utils::ApiCheck(host_defined_options_->IsFixedArray(), "ScriptOrigin()",
3000                   "Host-defined options has to be a PrimitiveArray");
3001   i::Handle<i::FixedArray> options =
3002       Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
3003   for (int i = 0; i < options->length(); i++) {
3004     Utils::ApiCheck(options->get(i).IsPrimitive(), "ScriptOrigin()",
3005                     "PrimitiveArray can only contain primtive values");
3006   }
3007 }
3008 
GetScriptResourceName() const3009 v8::Local<Value> Message::GetScriptResourceName() const {
3010   ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
3011   return GetScriptOrigin().ResourceName();
3012 }
3013 
GetStackTrace() const3014 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
3015   auto self = Utils::OpenHandle(this);
3016   i::Isolate* isolate = self->GetIsolate();
3017   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3018   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3019   i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
3020   if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
3021   auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
3022   return scope.Escape(Utils::StackTraceToLocal(stackTrace));
3023 }
3024 
GetLineNumber(Local<Context> context) const3025 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
3026   auto self = Utils::OpenHandle(this);
3027   i::Isolate* isolate = self->GetIsolate();
3028   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3029   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3030   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3031   return Just(self->GetLineNumber());
3032 }
3033 
GetStartPosition() const3034 int Message::GetStartPosition() const {
3035   auto self = Utils::OpenHandle(this);
3036   i::Isolate* isolate = self->GetIsolate();
3037   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3038   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3039   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3040   return self->GetStartPosition();
3041 }
3042 
GetEndPosition() const3043 int Message::GetEndPosition() const {
3044   auto self = Utils::OpenHandle(this);
3045   i::Isolate* isolate = self->GetIsolate();
3046   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3047   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3048   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3049   return self->GetEndPosition();
3050 }
3051 
ErrorLevel() const3052 int Message::ErrorLevel() const {
3053   auto self = Utils::OpenHandle(this);
3054   ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3055   return self->error_level();
3056 }
3057 
GetStartColumn() const3058 int Message::GetStartColumn() const {
3059   auto self = Utils::OpenHandle(this);
3060   i::Isolate* isolate = self->GetIsolate();
3061   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3062   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3063   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3064   return self->GetColumnNumber();
3065 }
3066 
GetWasmFunctionIndex() const3067 int Message::GetWasmFunctionIndex() const {
3068 #if V8_ENABLE_WEBASSEMBLY
3069   auto self = Utils::OpenHandle(this);
3070   i::Isolate* isolate = self->GetIsolate();
3071   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3072   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3073   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3074   int start_position = self->GetColumnNumber();
3075   if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
3076 
3077   i::Handle<i::Script> script(self->script(), isolate);
3078 
3079   if (script->type() != i::Script::TYPE_WASM) {
3080     return Message::kNoWasmFunctionIndexInfo;
3081   }
3082 
3083   auto debug_script = ToApiHandle<debug::Script>(script);
3084   return Local<debug::WasmScript>::Cast(debug_script)
3085       ->GetContainingFunction(start_position);
3086 #else
3087   return Message::kNoWasmFunctionIndexInfo;
3088 #endif  // V8_ENABLE_WEBASSEMBLY
3089 }
3090 
GetStartColumn(Local<Context> context) const3091 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3092   return Just(GetStartColumn());
3093 }
3094 
GetEndColumn() const3095 int Message::GetEndColumn() const {
3096   auto self = Utils::OpenHandle(this);
3097   i::Isolate* isolate = self->GetIsolate();
3098   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3099   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3100   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3101   const int column_number = self->GetColumnNumber();
3102   if (column_number == -1) return -1;
3103   const int start = self->GetStartPosition();
3104   const int end = self->GetEndPosition();
3105   return column_number + (end - start);
3106 }
3107 
GetEndColumn(Local<Context> context) const3108 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3109   return Just(GetEndColumn());
3110 }
3111 
IsSharedCrossOrigin() const3112 bool Message::IsSharedCrossOrigin() const {
3113   auto self = Utils::OpenHandle(this);
3114   i::Isolate* isolate = self->GetIsolate();
3115   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3116   return self->script().origin_options().IsSharedCrossOrigin();
3117 }
3118 
IsOpaque() const3119 bool Message::IsOpaque() const {
3120   auto self = Utils::OpenHandle(this);
3121   i::Isolate* isolate = self->GetIsolate();
3122   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3123   return self->script().origin_options().IsOpaque();
3124 }
3125 
GetSource(Local<Context> context) const3126 MaybeLocal<String> Message::GetSource(Local<Context> context) const {
3127   auto self = Utils::OpenHandle(this);
3128   i::Isolate* isolate = self->GetIsolate();
3129   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3130   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3131   i::Handle<i::String> source(self->GetSource(), isolate);
3132   RETURN_ESCAPED(Utils::ToLocal(source));
3133 }
3134 
GetSourceLine(Local<Context> context) const3135 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3136   auto self = Utils::OpenHandle(this);
3137   i::Isolate* isolate = self->GetIsolate();
3138   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3139   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3140   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3141   RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3142 }
3143 
PrintCurrentStackTrace(Isolate * isolate,std::ostream & out)3144 void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) {
3145   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3146   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3147   i_isolate->PrintCurrentStackTrace(out);
3148 }
3149 
3150 // --- S t a c k T r a c e ---
3151 
GetFrame(Isolate * v8_isolate,uint32_t index) const3152 Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3153                                        uint32_t index) const {
3154   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3155   i::Handle<i::StackFrameInfo> info(
3156       i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate);
3157   return Utils::StackFrameToLocal(info);
3158 }
3159 
GetFrameCount() const3160 int StackTrace::GetFrameCount() const {
3161   return Utils::OpenHandle(this)->length();
3162 }
3163 
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3164 Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3165                                                 int frame_limit,
3166                                                 StackTraceOptions options) {
3167   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3168   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3169   i::Handle<i::FixedArray> stackTrace =
3170       i_isolate->CaptureDetailedStackTrace(frame_limit, options);
3171   return Utils::StackTraceToLocal(stackTrace);
3172 }
3173 
CurrentScriptNameOrSourceURL(Isolate * v8_isolate)3174 Local<String> StackTrace::CurrentScriptNameOrSourceURL(Isolate* v8_isolate) {
3175   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3176   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3177   i::Handle<i::String> name_or_source_url =
3178       isolate->CurrentScriptNameOrSourceURL();
3179   return Utils::ToLocal(name_or_source_url);
3180 }
3181 
3182 // --- S t a c k F r a m e ---
3183 
GetLocation() const3184 Location StackFrame::GetLocation() const {
3185   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3186   i::Isolate* isolate = self->GetIsolate();
3187   i::Handle<i::Script> script(self->script(), isolate);
3188   i::Script::PositionInfo info;
3189   CHECK(i::Script::GetPositionInfo(script,
3190                                    i::StackFrameInfo::GetSourcePosition(self),
3191                                    &info, i::Script::WITH_OFFSET));
3192   if (script->HasSourceURLComment()) {
3193     info.line -= script->line_offset();
3194     if (info.line == 0) {
3195       info.column -= script->column_offset();
3196     }
3197   }
3198   return {info.line, info.column};
3199 }
3200 
GetScriptId() const3201 int StackFrame::GetScriptId() const {
3202   return Utils::OpenHandle(this)->script().id();
3203 }
3204 
GetScriptName() const3205 Local<String> StackFrame::GetScriptName() const {
3206   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3207   i::Isolate* isolate = self->GetIsolate();
3208   i::Handle<i::Object> name(self->script().name(), isolate);
3209   if (!name->IsString()) return {};
3210   return Utils::ToLocal(i::Handle<i::String>::cast(name));
3211 }
3212 
GetScriptNameOrSourceURL() const3213 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3214   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3215   i::Isolate* isolate = self->GetIsolate();
3216   i::Handle<i::Object> name_or_source_url(self->script().GetNameOrSourceURL(),
3217                                           isolate);
3218   if (!name_or_source_url->IsString()) return {};
3219   return Utils::ToLocal(i::Handle<i::String>::cast(name_or_source_url));
3220 }
3221 
GetScriptSource() const3222 Local<String> StackFrame::GetScriptSource() const {
3223   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3224   i::Isolate* isolate = self->GetIsolate();
3225   if (!self->script().HasValidSource()) return {};
3226   i::Handle<i::PrimitiveHeapObject> source(self->script().source(), isolate);
3227   if (!source->IsString()) return {};
3228   return Utils::ToLocal(i::Handle<i::String>::cast(source));
3229 }
3230 
GetScriptSourceMappingURL() const3231 Local<String> StackFrame::GetScriptSourceMappingURL() const {
3232   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3233   i::Isolate* isolate = self->GetIsolate();
3234   i::Handle<i::Object> source_mapping_url(self->script().source_mapping_url(),
3235                                           isolate);
3236   if (!source_mapping_url->IsString()) return {};
3237   return Utils::ToLocal(i::Handle<i::String>::cast(source_mapping_url));
3238 }
3239 
GetFunctionName() const3240 Local<String> StackFrame::GetFunctionName() const {
3241   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3242   i::Isolate* isolate = self->GetIsolate();
3243   i::Handle<i::String> name(self->function_name(), isolate);
3244   if (name->length() == 0) return {};
3245   return Utils::ToLocal(name);
3246 }
3247 
IsEval() const3248 bool StackFrame::IsEval() const {
3249   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3250   return self->script().compilation_type() == i::Script::COMPILATION_TYPE_EVAL;
3251 }
3252 
IsConstructor() const3253 bool StackFrame::IsConstructor() const {
3254   return Utils::OpenHandle(this)->is_constructor();
3255 }
3256 
IsWasm() const3257 bool StackFrame::IsWasm() const { return !IsUserJavaScript(); }
3258 
IsUserJavaScript() const3259 bool StackFrame::IsUserJavaScript() const {
3260   return Utils::OpenHandle(this)->script().IsUserJavaScript();
3261 }
3262 
3263 // --- J S O N ---
3264 
Parse(Local<Context> context,Local<String> json_string)3265 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3266                               Local<String> json_string) {
3267   PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3268   i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3269   i::Handle<i::String> source = i::String::Flatten(isolate, string);
3270   i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3271   auto maybe = source->IsOneByteRepresentation()
3272                    ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3273                    : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3274   Local<Value> result;
3275   has_pending_exception = !ToLocal<Value>(maybe, &result);
3276   RETURN_ON_FAILED_EXECUTION(Value);
3277   RETURN_ESCAPED(result);
3278 }
3279 
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3280 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3281                                    Local<Value> json_object,
3282                                    Local<String> gap) {
3283   PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3284   i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3285   i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3286   i::Handle<i::String> gap_string = gap.IsEmpty()
3287                                         ? isolate->factory()->empty_string()
3288                                         : Utils::OpenHandle(*gap);
3289   i::Handle<i::Object> maybe;
3290   has_pending_exception =
3291       !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3292   RETURN_ON_FAILED_EXECUTION(String);
3293   Local<String> result;
3294   has_pending_exception =
3295       !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3296   RETURN_ON_FAILED_EXECUTION(String);
3297   RETURN_ESCAPED(result);
3298 }
3299 
3300 // --- V a l u e   S e r i a l i z a t i o n ---
3301 
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3302 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3303                                                        Local<Object> object) {
3304   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3305   isolate->ScheduleThrow(*isolate->factory()->NewError(
3306       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3307       Utils::OpenHandle(*object)));
3308   return Nothing<bool>();
3309 }
3310 
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3311 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3312     Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3313   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3314   isolate->ScheduleThrow(*isolate->factory()->NewError(
3315       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3316       Utils::OpenHandle(*shared_array_buffer)));
3317   return Nothing<uint32_t>();
3318 }
3319 
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3320 Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3321     Isolate* v8_isolate, Local<WasmModuleObject> module) {
3322   return Nothing<uint32_t>();
3323 }
3324 
SupportsSharedValues() const3325 bool ValueSerializer::Delegate::SupportsSharedValues() const { return false; }
3326 
GetSharedValueId(Isolate * v8_isolate,Local<Value> shared_value)3327 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedValueId(
3328     Isolate* v8_isolate, Local<Value> shared_value) {
3329   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3330   isolate->ScheduleThrow(*isolate->factory()->NewError(
3331       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3332       Utils::OpenHandle(*shared_value)));
3333   return Nothing<uint32_t>();
3334 }
3335 
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3336 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3337                                                         size_t size,
3338                                                         size_t* actual_size) {
3339   *actual_size = size;
3340   return base::Realloc(old_buffer, size);
3341 }
3342 
FreeBufferMemory(void * buffer)3343 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3344   return base::Free(buffer);
3345 }
3346 
3347 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3348   explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3349       : isolate(i), serializer(i, delegate) {}
3350   i::Isolate* isolate;
3351   i::ValueSerializer serializer;
3352 };
3353 
ValueSerializer(Isolate * isolate)3354 ValueSerializer::ValueSerializer(Isolate* isolate)
3355     : ValueSerializer(isolate, nullptr) {}
3356 
ValueSerializer(Isolate * isolate,Delegate * delegate)3357 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3358     : private_(
3359           new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3360 
~ValueSerializer()3361 ValueSerializer::~ValueSerializer() { delete private_; }
3362 
WriteHeader()3363 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3364 
SetTreatArrayBufferViewsAsHostObjects(bool mode)3365 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3366   private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3367 }
3368 
WriteValue(Local<Context> context,Local<Value> value)3369 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3370                                         Local<Value> value) {
3371   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3372   ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3373            i::HandleScope);
3374   i::Handle<i::Object> object = Utils::OpenHandle(*value);
3375   Maybe<bool> result = private_->serializer.WriteObject(object);
3376   has_pending_exception = result.IsNothing();
3377   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3378   return result;
3379 }
3380 
Release()3381 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3382   return private_->serializer.Release();
3383 }
3384 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3385 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3386                                           Local<ArrayBuffer> array_buffer) {
3387   private_->serializer.TransferArrayBuffer(transfer_id,
3388                                            Utils::OpenHandle(*array_buffer));
3389 }
3390 
WriteUint32(uint32_t value)3391 void ValueSerializer::WriteUint32(uint32_t value) {
3392   private_->serializer.WriteUint32(value);
3393 }
3394 
WriteUint64(uint64_t value)3395 void ValueSerializer::WriteUint64(uint64_t value) {
3396   private_->serializer.WriteUint64(value);
3397 }
3398 
WriteDouble(double value)3399 void ValueSerializer::WriteDouble(double value) {
3400   private_->serializer.WriteDouble(value);
3401 }
3402 
WriteRawBytes(const void * source,size_t length)3403 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3404   private_->serializer.WriteRawBytes(source, length);
3405 }
3406 
ReadHostObject(Isolate * v8_isolate)3407 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3408     Isolate* v8_isolate) {
3409   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3410   isolate->ScheduleThrow(*isolate->factory()->NewError(
3411       isolate->error_function(),
3412       i::MessageTemplate::kDataCloneDeserializationError));
3413   return MaybeLocal<Object>();
3414 }
3415 
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3416 MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3417     Isolate* v8_isolate, uint32_t id) {
3418   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3419   isolate->ScheduleThrow(*isolate->factory()->NewError(
3420       isolate->error_function(),
3421       i::MessageTemplate::kDataCloneDeserializationError));
3422   return MaybeLocal<WasmModuleObject>();
3423 }
3424 
SupportsSharedValues() const3425 bool ValueDeserializer::Delegate::SupportsSharedValues() const { return false; }
3426 
GetSharedValueFromId(Isolate * v8_isolate,uint32_t shared_value_id)3427 MaybeLocal<Value> ValueDeserializer::Delegate::GetSharedValueFromId(
3428     Isolate* v8_isolate, uint32_t shared_value_id) {
3429   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3430   isolate->ScheduleThrow(*isolate->factory()->NewError(
3431       isolate->error_function(),
3432       i::MessageTemplate::kDataCloneDeserializationError));
3433   return MaybeLocal<Value>();
3434 }
3435 
3436 MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3437 ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3438                                                         uint32_t id) {
3439   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3440   isolate->ScheduleThrow(*isolate->factory()->NewError(
3441       isolate->error_function(),
3442       i::MessageTemplate::kDataCloneDeserializationError));
3443   return MaybeLocal<SharedArrayBuffer>();
3444 }
3445 
3446 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3447   PrivateData(i::Isolate* i, base::Vector<const uint8_t> data,
3448               Delegate* delegate)
3449       : isolate(i), deserializer(i, data, delegate) {}
3450   i::Isolate* isolate;
3451   i::ValueDeserializer deserializer;
3452   bool supports_legacy_wire_format = false;
3453 };
3454 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3455 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3456                                      size_t size)
3457     : ValueDeserializer(isolate, data, size, nullptr) {}
3458 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3459 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3460                                      size_t size, Delegate* delegate) {
3461   private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3462                              base::Vector<const uint8_t>(data, size), delegate);
3463 }
3464 
~ValueDeserializer()3465 ValueDeserializer::~ValueDeserializer() { delete private_; }
3466 
ReadHeader(Local<Context> context)3467 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3468   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3469   ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3470                      Nothing<bool>(), i::HandleScope);
3471 
3472   bool read_header = false;
3473   has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3474   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3475   DCHECK(read_header);
3476 
3477   static const uint32_t kMinimumNonLegacyVersion = 13;
3478   if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3479       !private_->supports_legacy_wire_format) {
3480     isolate->Throw(*isolate->factory()->NewError(
3481         i::MessageTemplate::kDataCloneDeserializationVersionError));
3482     has_pending_exception = true;
3483     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3484   }
3485 
3486   return Just(true);
3487 }
3488 
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3489 void ValueDeserializer::SetSupportsLegacyWireFormat(
3490     bool supports_legacy_wire_format) {
3491   private_->supports_legacy_wire_format = supports_legacy_wire_format;
3492 }
3493 
GetWireFormatVersion() const3494 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3495   return private_->deserializer.GetWireFormatVersion();
3496 }
3497 
ReadValue(Local<Context> context)3498 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3499   PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3500   i::MaybeHandle<i::Object> result;
3501   if (GetWireFormatVersion() > 0) {
3502     result = private_->deserializer.ReadObjectWrapper();
3503   } else {
3504     result =
3505         private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3506   }
3507   Local<Value> value;
3508   has_pending_exception = !ToLocal(result, &value);
3509   RETURN_ON_FAILED_EXECUTION(Value);
3510   RETURN_ESCAPED(value);
3511 }
3512 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3513 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3514                                             Local<ArrayBuffer> array_buffer) {
3515   private_->deserializer.TransferArrayBuffer(transfer_id,
3516                                              Utils::OpenHandle(*array_buffer));
3517 }
3518 
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3519 void ValueDeserializer::TransferSharedArrayBuffer(
3520     uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3521   private_->deserializer.TransferArrayBuffer(
3522       transfer_id, Utils::OpenHandle(*shared_array_buffer));
3523 }
3524 
ReadUint32(uint32_t * value)3525 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3526   return private_->deserializer.ReadUint32(value);
3527 }
3528 
ReadUint64(uint64_t * value)3529 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3530   return private_->deserializer.ReadUint64(value);
3531 }
3532 
ReadDouble(double * value)3533 bool ValueDeserializer::ReadDouble(double* value) {
3534   return private_->deserializer.ReadDouble(value);
3535 }
3536 
ReadRawBytes(size_t length,const void ** data)3537 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3538   return private_->deserializer.ReadRawBytes(length, data);
3539 }
3540 
3541 // --- D a t a ---
3542 
FullIsUndefined() const3543 bool Value::FullIsUndefined() const {
3544   i::Handle<i::Object> object = Utils::OpenHandle(this);
3545   bool result = object->IsUndefined();
3546   DCHECK_EQ(result, QuickIsUndefined());
3547   return result;
3548 }
3549 
FullIsNull() const3550 bool Value::FullIsNull() const {
3551   i::Handle<i::Object> object = Utils::OpenHandle(this);
3552   bool result = object->IsNull();
3553   DCHECK_EQ(result, QuickIsNull());
3554   return result;
3555 }
3556 
IsTrue() const3557 bool Value::IsTrue() const {
3558   i::Object object = *Utils::OpenHandle(this);
3559   if (object.IsSmi()) return false;
3560   return object.IsTrue();
3561 }
3562 
IsFalse() const3563 bool Value::IsFalse() const {
3564   i::Object object = *Utils::OpenHandle(this);
3565   if (object.IsSmi()) return false;
3566   return object.IsFalse();
3567 }
3568 
IsFunction() const3569 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3570 
IsName() const3571 bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3572 
FullIsString() const3573 bool Value::FullIsString() const {
3574   bool result = Utils::OpenHandle(this)->IsString();
3575   DCHECK_EQ(result, QuickIsString());
3576   return result;
3577 }
3578 
IsSymbol() const3579 bool Value::IsSymbol() const {
3580   return Utils::OpenHandle(this)->IsPublicSymbol();
3581 }
3582 
IsArray() const3583 bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3584 
IsArrayBuffer() const3585 bool Value::IsArrayBuffer() const {
3586   i::Object obj = *Utils::OpenHandle(this);
3587   if (!obj.IsJSArrayBuffer()) return false;
3588   return !i::JSArrayBuffer::cast(obj).is_shared();
3589 }
3590 
IsArrayBufferView() const3591 bool Value::IsArrayBufferView() const {
3592   return Utils::OpenHandle(this)->IsJSArrayBufferView();
3593 }
3594 
IsTypedArray() const3595 bool Value::IsTypedArray() const {
3596   return Utils::OpenHandle(this)->IsJSTypedArray();
3597 }
3598 
3599 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype)                   \
3600   bool Value::Is##Type##Array() const {                                     \
3601     i::Handle<i::Object> obj = Utils::OpenHandle(this);                     \
3602     return obj->IsJSTypedArray() &&                                         \
3603            i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3604   }
3605 
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3606 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3607 
3608 #undef VALUE_IS_TYPED_ARRAY
3609 
3610 bool Value::IsDataView() const {
3611   return Utils::OpenHandle(this)->IsJSDataView();
3612 }
3613 
IsSharedArrayBuffer() const3614 bool Value::IsSharedArrayBuffer() const {
3615   i::Object obj = *Utils::OpenHandle(this);
3616   if (!obj.IsJSArrayBuffer()) return false;
3617   return i::JSArrayBuffer::cast(obj).is_shared();
3618 }
3619 
IsObject() const3620 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3621 
IsNumber() const3622 bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3623 
IsBigInt() const3624 bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3625 
IsProxy() const3626 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3627 
3628 #define VALUE_IS_SPECIFIC_TYPE(Type, Check)             \
3629   bool Value::Is##Type() const {                        \
3630     i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3631     return obj->Is##Check();                            \
3632   }
3633 
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3634 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3635 VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3636 VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3637 VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3638 VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3639 VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3640 VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3641 VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3642 VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3643 #if V8_ENABLE_WEBASSEMBLY
3644 VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3645 VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3646 #else
3647 bool Value::IsWasmMemoryObject() const { return false; }
3648 bool Value::IsWasmModuleObject() const { return false; }
3649 #endif  // V8_ENABLE_WEBASSEMBLY
3650 VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3651 VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3652 
3653 #undef VALUE_IS_SPECIFIC_TYPE
3654 
3655 bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3656 
IsExternal() const3657 bool Value::IsExternal() const {
3658   i::Object obj = *Utils::OpenHandle(this);
3659   return obj.IsJSExternalObject();
3660 }
3661 
IsInt32() const3662 bool Value::IsInt32() const {
3663   i::Object obj = *Utils::OpenHandle(this);
3664   if (obj.IsSmi()) return true;
3665   if (obj.IsNumber()) {
3666     return i::IsInt32Double(obj.Number());
3667   }
3668   return false;
3669 }
3670 
IsUint32() const3671 bool Value::IsUint32() const {
3672   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3673   if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3674   if (obj->IsNumber()) {
3675     double value = obj->Number();
3676     return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3677            value == i::FastUI2D(i::FastD2UI(value));
3678   }
3679   return false;
3680 }
3681 
IsNativeError() const3682 bool Value::IsNativeError() const {
3683   return Utils::OpenHandle(this)->IsJSError();
3684 }
3685 
IsRegExp() const3686 bool Value::IsRegExp() const {
3687   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3688   return obj->IsJSRegExp();
3689 }
3690 
IsAsyncFunction() const3691 bool Value::IsAsyncFunction() const {
3692   i::Object obj = *Utils::OpenHandle(this);
3693   if (!obj.IsJSFunction()) return false;
3694   i::JSFunction func = i::JSFunction::cast(obj);
3695   return i::IsAsyncFunction(func.shared().kind());
3696 }
3697 
IsGeneratorFunction() const3698 bool Value::IsGeneratorFunction() const {
3699   i::Object obj = *Utils::OpenHandle(this);
3700   if (!obj.IsJSFunction()) return false;
3701   i::JSFunction func = i::JSFunction::cast(obj);
3702   ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
3703   return i::IsGeneratorFunction(func.shared().kind());
3704 }
3705 
IsGeneratorObject() const3706 bool Value::IsGeneratorObject() const {
3707   return Utils::OpenHandle(this)->IsJSGeneratorObject();
3708 }
3709 
IsMapIterator() const3710 bool Value::IsMapIterator() const {
3711   return Utils::OpenHandle(this)->IsJSMapIterator();
3712 }
3713 
IsSetIterator() const3714 bool Value::IsSetIterator() const {
3715   return Utils::OpenHandle(this)->IsJSSetIterator();
3716 }
3717 
IsPromise() const3718 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3719 
IsModuleNamespaceObject() const3720 bool Value::IsModuleNamespaceObject() const {
3721   return Utils::OpenHandle(this)->IsJSModuleNamespace();
3722 }
3723 
ToString(Local<Context> context) const3724 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3725   auto obj = Utils::OpenHandle(this);
3726   if (obj->IsString()) return ToApiHandle<String>(obj);
3727   PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3728   Local<String> result;
3729   has_pending_exception =
3730       !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3731   RETURN_ON_FAILED_EXECUTION(String);
3732   RETURN_ESCAPED(result);
3733 }
3734 
ToDetailString(Local<Context> context) const3735 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3736   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3737   if (obj->IsString()) return ToApiHandle<String>(obj);
3738   PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3739   Local<String> result =
3740       Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3741   RETURN_ON_FAILED_EXECUTION(String);
3742   RETURN_ESCAPED(result);
3743 }
3744 
ToObject(Local<Context> context) const3745 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3746   auto obj = Utils::OpenHandle(this);
3747   if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3748   PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3749   Local<Object> result;
3750   has_pending_exception =
3751       !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3752   RETURN_ON_FAILED_EXECUTION(Object);
3753   RETURN_ESCAPED(result);
3754 }
3755 
ToBigInt(Local<Context> context) const3756 MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3757   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3758   if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3759   PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3760   Local<BigInt> result;
3761   has_pending_exception =
3762       !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3763   RETURN_ON_FAILED_EXECUTION(BigInt);
3764   RETURN_ESCAPED(result);
3765 }
3766 
BooleanValue(Isolate * v8_isolate) const3767 bool Value::BooleanValue(Isolate* v8_isolate) const {
3768   return Utils::OpenHandle(this)->BooleanValue(
3769       reinterpret_cast<i::Isolate*>(v8_isolate));
3770 }
3771 
ToBoolean(Isolate * v8_isolate) const3772 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3773   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3774   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3775   return ToApiHandle<Boolean>(
3776       isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3777 }
3778 
ToNumber(Local<Context> context) const3779 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3780   auto obj = Utils::OpenHandle(this);
3781   if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3782   PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3783   Local<Number> result;
3784   has_pending_exception =
3785       !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3786   RETURN_ON_FAILED_EXECUTION(Number);
3787   RETURN_ESCAPED(result);
3788 }
3789 
ToInteger(Local<Context> context) const3790 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3791   auto obj = Utils::OpenHandle(this);
3792   if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3793   PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3794   Local<Integer> result;
3795   has_pending_exception =
3796       !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3797   RETURN_ON_FAILED_EXECUTION(Integer);
3798   RETURN_ESCAPED(result);
3799 }
3800 
ToInt32(Local<Context> context) const3801 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3802   auto obj = Utils::OpenHandle(this);
3803   if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3804   Local<Int32> result;
3805   PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3806   has_pending_exception =
3807       !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3808   RETURN_ON_FAILED_EXECUTION(Int32);
3809   RETURN_ESCAPED(result);
3810 }
3811 
ToUint32(Local<Context> context) const3812 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3813   auto obj = Utils::OpenHandle(this);
3814   if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3815   Local<Uint32> result;
3816   PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3817   has_pending_exception =
3818       !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3819   RETURN_ON_FAILED_EXECUTION(Uint32);
3820   RETURN_ESCAPED(result);
3821 }
3822 
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3823 i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3824                                         i::ExternalPointer_t encoded_pointer,
3825                                         ExternalPointerTag tag) {
3826   return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3827 }
3828 
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3829 i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3830   return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3831 }
3832 
ShouldThrowOnError(i::Isolate * isolate)3833 bool i::ShouldThrowOnError(i::Isolate* isolate) {
3834   return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3835          i::ShouldThrow::kThrowOnError;
3836 }
3837 
CanHaveInternalField(int instance_type)3838 bool i::CanHaveInternalField(int instance_type) {
3839   return instance_type == i::Internals::kJSObjectType ||
3840          instance_type == i::Internals::kJSSpecialApiObjectType ||
3841          v8::internal::InstanceTypeChecker::IsJSApiObject(
3842              static_cast<v8::internal::InstanceType>(instance_type));
3843 }
3844 
CheckInitializedImpl(v8::Isolate * external_isolate)3845 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3846   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3847   Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3848                   "v8::internal::Internals::CheckInitialized",
3849                   "Isolate is not initialized or V8 has died");
3850 }
3851 
CheckCast(Data * that)3852 void v8::Value::CheckCast(Data* that) {
3853   Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3854 }
3855 
CheckCast(v8::Value * that)3856 void External::CheckCast(v8::Value* that) {
3857   Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3858                   "Value is not an External");
3859 }
3860 
CheckCast(Value * that)3861 void v8::Object::CheckCast(Value* that) {
3862   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3863   Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3864                   "Value is not an Object");
3865 }
3866 
CheckCast(Value * that)3867 void v8::Function::CheckCast(Value* that) {
3868   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3869   Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3870                   "Value is not a Function");
3871 }
3872 
CheckCast(v8::Data * that)3873 void v8::Boolean::CheckCast(v8::Data* that) {
3874   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3875   Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3876                   "Value is not a Boolean");
3877 }
3878 
CheckCast(v8::Data * that)3879 void v8::Name::CheckCast(v8::Data* that) {
3880   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3881   Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3882 }
3883 
CheckCast(v8::Data * that)3884 void v8::String::CheckCast(v8::Data* that) {
3885   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3886   Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3887 }
3888 
CheckCast(v8::Data * that)3889 void v8::Symbol::CheckCast(v8::Data* that) {
3890   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3891   Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3892 }
3893 
CheckCast(v8::Data * that)3894 void v8::Private::CheckCast(v8::Data* that) {
3895   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3896   Utils::ApiCheck(
3897       obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3898       "v8::Private::Cast", "Value is not a Private");
3899 }
3900 
CheckCast(v8::Data * that)3901 void v8::FixedArray::CheckCast(v8::Data* that) {
3902   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3903   Utils::ApiCheck(obj->IsFixedArray(), "v8::FixedArray::Cast",
3904                   "Value is not a FixedArray");
3905 }
3906 
CheckCast(v8::Data * that)3907 void v8::ModuleRequest::CheckCast(v8::Data* that) {
3908   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3909   Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast",
3910                   "Value is not a ModuleRequest");
3911 }
3912 
CheckCast(v8::Data * that)3913 void v8::Module::CheckCast(v8::Data* that) {
3914   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3915   Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3916 }
3917 
CheckCast(v8::Data * that)3918 void v8::Number::CheckCast(v8::Data* that) {
3919   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3920   Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3921                   "Value is not a Number");
3922 }
3923 
CheckCast(v8::Data * that)3924 void v8::Integer::CheckCast(v8::Data* that) {
3925   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3926   Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3927                   "Value is not an Integer");
3928 }
3929 
CheckCast(v8::Data * that)3930 void v8::Int32::CheckCast(v8::Data* that) {
3931   Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast",
3932                   "Value is not a 32-bit signed integer");
3933 }
3934 
CheckCast(v8::Data * that)3935 void v8::Uint32::CheckCast(v8::Data* that) {
3936   Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast",
3937                   "Value is not a 32-bit unsigned integer");
3938 }
3939 
CheckCast(v8::Data * that)3940 void v8::BigInt::CheckCast(v8::Data* that) {
3941   Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3942                   "Value is not a BigInt");
3943 }
3944 
CheckCast(v8::Data * that)3945 void v8::Context::CheckCast(v8::Data* that) {
3946   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3947   Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast",
3948                   "Value is not a Context");
3949 }
3950 
CheckCast(Value * that)3951 void v8::Array::CheckCast(Value* that) {
3952   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3953   Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3954 }
3955 
CheckCast(Value * that)3956 void v8::Map::CheckCast(Value* that) {
3957   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3958   Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3959 }
3960 
CheckCast(Value * that)3961 void v8::Set::CheckCast(Value* that) {
3962   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3963   Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3964 }
3965 
CheckCast(Value * that)3966 void v8::Promise::CheckCast(Value* that) {
3967   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3968                   "Value is not a Promise");
3969 }
3970 
CheckCast(Value * that)3971 void v8::Promise::Resolver::CheckCast(Value* that) {
3972   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3973                   "Value is not a Promise::Resolver");
3974 }
3975 
CheckCast(Value * that)3976 void v8::Proxy::CheckCast(Value* that) {
3977   Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3978 }
3979 
CheckCast(Value * that)3980 void v8::WasmMemoryObject::CheckCast(Value* that) {
3981   Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3982                   "Value is not a WasmMemoryObject");
3983 }
3984 
CheckCast(Value * that)3985 void v8::WasmModuleObject::CheckCast(Value* that) {
3986   Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3987                   "Value is not a WasmModuleObject");
3988 }
3989 
~BackingStore()3990 v8::BackingStore::~BackingStore() {
3991   auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3992   i_this->~BackingStore();  // manually call internal destructor
3993 }
3994 
Data() const3995 void* v8::BackingStore::Data() const {
3996   return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3997 }
3998 
ByteLength() const3999 size_t v8::BackingStore::ByteLength() const {
4000   return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
4001 }
4002 
IsShared() const4003 bool v8::BackingStore::IsShared() const {
4004   return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
4005 }
4006 
4007 // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)4008 std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
4009     v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
4010     size_t byte_length) {
4011   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
4012   API_RCS_SCOPE(i_isolate, ArrayBuffer, BackingStore_Reallocate);
4013   Utils::ApiCheck(byte_length <= i::JSArrayBuffer::kMaxByteLength,
4014                   "v8::BackingStore::Reallocate", "byte_lenght is too large");
4015   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
4016   i::BackingStore* i_backing_store =
4017       reinterpret_cast<i::BackingStore*>(backing_store.get());
4018   if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
4019     i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
4020   }
4021   return backing_store;
4022 }
4023 
4024 // static
EmptyDeleter(void * data,size_t length,void * deleter_data)4025 void v8::BackingStore::EmptyDeleter(void* data, size_t length,
4026                                     void* deleter_data) {
4027   DCHECK_NULL(deleter_data);
4028 }
4029 
GetBackingStore()4030 std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
4031   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4032   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4033   if (!backing_store) {
4034     backing_store =
4035         i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
4036   }
4037   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4038   return std::static_pointer_cast<v8::BackingStore>(bs_base);
4039 }
4040 
Data() const4041 void* v8::ArrayBuffer::Data() const {
4042   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4043   return self->backing_store();
4044 }
4045 
GetBackingStore()4046 std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
4047   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4048   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4049   if (!backing_store) {
4050     backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
4051   }
4052   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4053   return std::static_pointer_cast<v8::BackingStore>(bs_base);
4054 }
4055 
Data() const4056 void* v8::SharedArrayBuffer::Data() const {
4057   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4058   return self->backing_store();
4059 }
4060 
CheckCast(Value * that)4061 void v8::ArrayBuffer::CheckCast(Value* that) {
4062   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4063   Utils::ApiCheck(
4064       obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
4065       "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
4066 }
4067 
CheckCast(Value * that)4068 void v8::ArrayBufferView::CheckCast(Value* that) {
4069   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4070   Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
4071                   "Value is not an ArrayBufferView");
4072 }
4073 
4074 constexpr size_t v8::TypedArray::kMaxLength;
4075 
CheckCast(Value * that)4076 void v8::TypedArray::CheckCast(Value* that) {
4077   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4078   Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
4079                   "Value is not a TypedArray");
4080 }
4081 
4082 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype)                  \
4083   void v8::Type##Array::CheckCast(Value* that) {                             \
4084     i::Handle<i::Object> obj = Utils::OpenHandle(that);                      \
4085     Utils::ApiCheck(                                                         \
4086         obj->IsJSTypedArray() &&                                             \
4087             i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
4088         "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array");      \
4089   }
4090 
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)4091 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4092 
4093 #undef CHECK_TYPED_ARRAY_CAST
4094 
4095 void v8::DataView::CheckCast(Value* that) {
4096   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4097   Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
4098                   "Value is not a DataView");
4099 }
4100 
CheckCast(Value * that)4101 void v8::SharedArrayBuffer::CheckCast(Value* that) {
4102   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4103   Utils::ApiCheck(
4104       obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
4105       "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
4106 }
4107 
CheckCast(v8::Value * that)4108 void v8::Date::CheckCast(v8::Value* that) {
4109   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4110   Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
4111 }
4112 
CheckCast(v8::Value * that)4113 void v8::StringObject::CheckCast(v8::Value* that) {
4114   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4115   Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
4116                   "Value is not a StringObject");
4117 }
4118 
CheckCast(v8::Value * that)4119 void v8::SymbolObject::CheckCast(v8::Value* that) {
4120   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4121   Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
4122                   "Value is not a SymbolObject");
4123 }
4124 
CheckCast(v8::Value * that)4125 void v8::NumberObject::CheckCast(v8::Value* that) {
4126   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4127   Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
4128                   "Value is not a NumberObject");
4129 }
4130 
CheckCast(v8::Value * that)4131 void v8::BigIntObject::CheckCast(v8::Value* that) {
4132   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4133   Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
4134                   "Value is not a BigIntObject");
4135 }
4136 
CheckCast(v8::Value * that)4137 void v8::BooleanObject::CheckCast(v8::Value* that) {
4138   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4139   Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
4140                   "Value is not a BooleanObject");
4141 }
4142 
CheckCast(v8::Value * that)4143 void v8::RegExp::CheckCast(v8::Value* that) {
4144   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4145   Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
4146                   "Value is not a RegExp");
4147 }
4148 
NumberValue(Local<Context> context) const4149 Maybe<double> Value::NumberValue(Local<Context> context) const {
4150   auto obj = Utils::OpenHandle(this);
4151   if (obj->IsNumber()) return Just(obj->Number());
4152   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4153   ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4154            i::HandleScope);
4155   i::Handle<i::Object> num;
4156   has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
4157   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4158   return Just(num->Number());
4159 }
4160 
IntegerValue(Local<Context> context) const4161 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4162   auto obj = Utils::OpenHandle(this);
4163   if (obj->IsNumber()) {
4164     return Just(NumberToInt64(*obj));
4165   }
4166   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4167   ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4168            i::HandleScope);
4169   i::Handle<i::Object> num;
4170   has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4171   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4172   return Just(NumberToInt64(*num));
4173 }
4174 
Int32Value(Local<Context> context) const4175 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4176   auto obj = Utils::OpenHandle(this);
4177   if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4178   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4179   ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4180            i::HandleScope);
4181   i::Handle<i::Object> num;
4182   has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4183   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4184   return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4185                            : static_cast<int32_t>(num->Number()));
4186 }
4187 
Uint32Value(Local<Context> context) const4188 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4189   auto obj = Utils::OpenHandle(this);
4190   if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4191   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4192   ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4193            i::HandleScope);
4194   i::Handle<i::Object> num;
4195   has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4196   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4197   return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4198                            : static_cast<uint32_t>(num->Number()));
4199 }
4200 
ToArrayIndex(Local<Context> context) const4201 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4202   auto self = Utils::OpenHandle(this);
4203   if (self->IsSmi()) {
4204     if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4205     return Local<Uint32>();
4206   }
4207   PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4208   i::Handle<i::Object> string_obj;
4209   has_pending_exception =
4210       !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4211   RETURN_ON_FAILED_EXECUTION(Uint32);
4212   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4213   uint32_t index;
4214   if (str->AsArrayIndex(&index)) {
4215     i::Handle<i::Object> value;
4216     if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4217       value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4218     } else {
4219       value = isolate->factory()->NewNumber(index);
4220     }
4221     RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4222   }
4223   return Local<Uint32>();
4224 }
4225 
Equals(Local<Context> context,Local<Value> that) const4226 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4227   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4228   ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope);
4229   auto self = Utils::OpenHandle(this);
4230   auto other = Utils::OpenHandle(*that);
4231   Maybe<bool> result = i::Object::Equals(isolate, self, other);
4232   has_pending_exception = result.IsNothing();
4233   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4234   return result;
4235 }
4236 
StrictEquals(Local<Value> that) const4237 bool Value::StrictEquals(Local<Value> that) const {
4238   auto self = Utils::OpenHandle(this);
4239   auto other = Utils::OpenHandle(*that);
4240   return self->StrictEquals(*other);
4241 }
4242 
SameValue(Local<Value> that) const4243 bool Value::SameValue(Local<Value> that) const {
4244   auto self = Utils::OpenHandle(this);
4245   auto other = Utils::OpenHandle(*that);
4246   return self->SameValue(*other);
4247 }
4248 
TypeOf(v8::Isolate * external_isolate)4249 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4250   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4251   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4252   API_RCS_SCOPE(isolate, Value, TypeOf);
4253   return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4254 }
4255 
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4256 Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4257                               v8::Local<v8::Object> object) {
4258   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4259   ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4260            i::HandleScope);
4261   auto left = Utils::OpenHandle(this);
4262   auto right = Utils::OpenHandle(*object);
4263   i::Handle<i::Object> result;
4264   has_pending_exception =
4265       !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4266   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4267   return Just(result->IsTrue(isolate));
4268 }
4269 
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4270 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4271                             v8::Local<Value> key, v8::Local<Value> value) {
4272   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4273   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4274   auto self = Utils::OpenHandle(this);
4275   auto key_obj = Utils::OpenHandle(*key);
4276   auto value_obj = Utils::OpenHandle(*value);
4277   has_pending_exception =
4278       i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4279                                     i::StoreOrigin::kMaybeKeyed,
4280                                     Just(i::ShouldThrow::kDontThrow))
4281           .is_null();
4282   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4283   return Just(true);
4284 }
4285 
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4286 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4287                             v8::Local<Value> value) {
4288   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4289   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4290   auto self = Utils::OpenHandle(this);
4291   auto value_obj = Utils::OpenHandle(*value);
4292   has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4293                                                 i::ShouldThrow::kDontThrow)
4294                               .is_null();
4295   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4296   return Just(true);
4297 }
4298 
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4299 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4300                                            v8::Local<Name> key,
4301                                            v8::Local<Value> value) {
4302   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4303   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4304   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4305   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4306 
4307   i::PropertyKey lookup_key(isolate, key_obj);
4308   i::LookupIterator it(isolate, self, lookup_key, i::LookupIterator::OWN);
4309   if (self->IsJSProxy()) {
4310     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4311              i::HandleScope);
4312     Maybe<bool> result =
4313         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4314     has_pending_exception = result.IsNothing();
4315     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4316     return result;
4317   } else {
4318     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4319                        Nothing<bool>(), i::HandleScope);
4320     Maybe<bool> result =
4321         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4322     has_pending_exception = result.IsNothing();
4323     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4324     return result;
4325   }
4326 }
4327 
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4328 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4329                                            uint32_t index,
4330                                            v8::Local<Value> value) {
4331   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4332   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4333   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4334 
4335   i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4336   if (self->IsJSProxy()) {
4337     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4338              i::HandleScope);
4339     Maybe<bool> result =
4340         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4341     has_pending_exception = result.IsNothing();
4342     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4343     return result;
4344   } else {
4345     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4346                        Nothing<bool>(), i::HandleScope);
4347     Maybe<bool> result =
4348         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4349     has_pending_exception = result.IsNothing();
4350     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4351     return result;
4352   }
4353 }
4354 
4355 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4356   PrivateData() : desc() {}
4357   i::PropertyDescriptor desc;
4358 };
4359 
PropertyDescriptor()4360 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4361 
4362 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4363 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4364     : private_(new PrivateData()) {
4365   private_->desc.set_value(Utils::OpenHandle(*value, true));
4366 }
4367 
4368 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4369 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4370                                            bool writable)
4371     : private_(new PrivateData()) {
4372   private_->desc.set_value(Utils::OpenHandle(*value, true));
4373   private_->desc.set_writable(writable);
4374 }
4375 
4376 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4377 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4378                                            v8::Local<v8::Value> set)
4379     : private_(new PrivateData()) {
4380   DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4381   DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4382   private_->desc.set_get(Utils::OpenHandle(*get, true));
4383   private_->desc.set_set(Utils::OpenHandle(*set, true));
4384 }
4385 
~PropertyDescriptor()4386 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4387 
value() const4388 v8::Local<Value> v8::PropertyDescriptor::value() const {
4389   DCHECK(private_->desc.has_value());
4390   return Utils::ToLocal(private_->desc.value());
4391 }
4392 
get() const4393 v8::Local<Value> v8::PropertyDescriptor::get() const {
4394   DCHECK(private_->desc.has_get());
4395   return Utils::ToLocal(private_->desc.get());
4396 }
4397 
set() const4398 v8::Local<Value> v8::PropertyDescriptor::set() const {
4399   DCHECK(private_->desc.has_set());
4400   return Utils::ToLocal(private_->desc.set());
4401 }
4402 
has_value() const4403 bool v8::PropertyDescriptor::has_value() const {
4404   return private_->desc.has_value();
4405 }
has_get() const4406 bool v8::PropertyDescriptor::has_get() const {
4407   return private_->desc.has_get();
4408 }
has_set() const4409 bool v8::PropertyDescriptor::has_set() const {
4410   return private_->desc.has_set();
4411 }
4412 
writable() const4413 bool v8::PropertyDescriptor::writable() const {
4414   DCHECK(private_->desc.has_writable());
4415   return private_->desc.writable();
4416 }
4417 
has_writable() const4418 bool v8::PropertyDescriptor::has_writable() const {
4419   return private_->desc.has_writable();
4420 }
4421 
set_enumerable(bool enumerable)4422 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4423   private_->desc.set_enumerable(enumerable);
4424 }
4425 
enumerable() const4426 bool v8::PropertyDescriptor::enumerable() const {
4427   DCHECK(private_->desc.has_enumerable());
4428   return private_->desc.enumerable();
4429 }
4430 
has_enumerable() const4431 bool v8::PropertyDescriptor::has_enumerable() const {
4432   return private_->desc.has_enumerable();
4433 }
4434 
set_configurable(bool configurable)4435 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4436   private_->desc.set_configurable(configurable);
4437 }
4438 
configurable() const4439 bool v8::PropertyDescriptor::configurable() const {
4440   DCHECK(private_->desc.has_configurable());
4441   return private_->desc.configurable();
4442 }
4443 
has_configurable() const4444 bool v8::PropertyDescriptor::has_configurable() const {
4445   return private_->desc.has_configurable();
4446 }
4447 
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4448 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4449                                           v8::Local<Name> key,
4450                                           v8::Local<Value> value,
4451                                           v8::PropertyAttribute attributes) {
4452   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4453   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4454   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4455   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4456 
4457   i::PropertyDescriptor desc;
4458   desc.set_writable(!(attributes & v8::ReadOnly));
4459   desc.set_enumerable(!(attributes & v8::DontEnum));
4460   desc.set_configurable(!(attributes & v8::DontDelete));
4461   desc.set_value(value_obj);
4462 
4463   if (self->IsJSProxy()) {
4464     ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4465              i::HandleScope);
4466     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4467         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4468     // Even though we said kDontThrow, there might be accessors that do throw.
4469     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4470     return success;
4471   } else {
4472     // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4473     // a script.
4474     ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4475                        Nothing<bool>(), i::HandleScope);
4476     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4477         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4478     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4479     return success;
4480   }
4481 }
4482 
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4483 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4484                                        v8::Local<Name> key,
4485                                        PropertyDescriptor& descriptor) {
4486   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4487   ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4488            i::HandleScope);
4489   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4490   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4491 
4492   Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4493       isolate, self, key_obj, &descriptor.get_private()->desc,
4494       Just(i::kDontThrow));
4495   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4496   return success;
4497 }
4498 
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4499 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4500                                    Local<Value> value) {
4501   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4502   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4503                      i::HandleScope);
4504   auto self = Utils::OpenHandle(this);
4505   auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4506   auto value_obj = Utils::OpenHandle(*value);
4507   if (self->IsJSProxy()) {
4508     i::PropertyDescriptor desc;
4509     desc.set_writable(true);
4510     desc.set_enumerable(false);
4511     desc.set_configurable(true);
4512     desc.set_value(value_obj);
4513     return i::JSProxy::SetPrivateSymbol(
4514         isolate, i::Handle<i::JSProxy>::cast(self),
4515         i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4516   }
4517   auto js_object = i::Handle<i::JSObject>::cast(self);
4518   i::LookupIterator it(isolate, js_object, key_obj, js_object);
4519   has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4520                               &it, value_obj, i::DONT_ENUM)
4521                               .is_null();
4522   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4523   return Just(true);
4524 }
4525 
Get(Local<v8::Context> context,Local<Value> key)4526 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4527                                   Local<Value> key) {
4528   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4529   auto self = Utils::OpenHandle(this);
4530   auto key_obj = Utils::OpenHandle(*key);
4531   i::Handle<i::Object> result;
4532   has_pending_exception =
4533       !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4534   RETURN_ON_FAILED_EXECUTION(Value);
4535   RETURN_ESCAPED(Utils::ToLocal(result));
4536 }
4537 
Get(Local<Context> context,uint32_t index)4538 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4539   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4540   auto self = Utils::OpenHandle(this);
4541   i::Handle<i::Object> result;
4542   has_pending_exception =
4543       !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4544   RETURN_ON_FAILED_EXECUTION(Value);
4545   RETURN_ESCAPED(Utils::ToLocal(result));
4546 }
4547 
GetPrivate(Local<Context> context,Local<Private> key)4548 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4549                                          Local<Private> key) {
4550   return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4551 }
4552 
GetPropertyAttributes(Local<Context> context,Local<Value> key)4553 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4554     Local<Context> context, Local<Value> key) {
4555   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4556   ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4557            Nothing<PropertyAttribute>(), i::HandleScope);
4558   auto self = Utils::OpenHandle(this);
4559   auto key_obj = Utils::OpenHandle(*key);
4560   if (!key_obj->IsName()) {
4561     has_pending_exception =
4562         !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4563     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4564   }
4565   auto key_name = i::Handle<i::Name>::cast(key_obj);
4566   auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4567   has_pending_exception = result.IsNothing();
4568   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4569   if (result.FromJust() == i::ABSENT) {
4570     return Just(static_cast<PropertyAttribute>(i::NONE));
4571   }
4572   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4573 }
4574 
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4575 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4576                                                        Local<Name> key) {
4577   PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4578   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4579   i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4580 
4581   i::PropertyDescriptor desc;
4582   Maybe<bool> found =
4583       i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4584   has_pending_exception = found.IsNothing();
4585   RETURN_ON_FAILED_EXECUTION(Value);
4586   if (!found.FromJust()) {
4587     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4588   }
4589   RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4590 }
4591 
GetPrototype()4592 Local<Value> v8::Object::GetPrototype() {
4593   auto self = Utils::OpenHandle(this);
4594   auto isolate = self->GetIsolate();
4595   i::PrototypeIterator iter(isolate, self);
4596   return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4597 }
4598 
GetPrototypeV2()4599 Local<Value> v8::Object::GetPrototypeV2() {
4600   auto self = Utils::OpenHandle(this);
4601   auto i_isolate = self->GetIsolate();
4602   i::PrototypeIterator iter(i_isolate, self);
4603   if (self->IsJSGlobalProxy()) {
4604     // Skip hidden prototype (i.e. JSGlobalObject).
4605     iter.Advance();
4606   }
4607   DCHECK(!i::PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
4608   return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4609 }
4610 
4611 namespace {
4612 
SetPrototypeImpl(v8::Object * this_,Local<Context> context,Local<Value> value,bool from_javascript)4613 Maybe<bool> SetPrototypeImpl(v8::Object* this_, Local<Context> context,
4614                              Local<Value> value, bool from_javascript) {
4615   auto i_isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4616   auto self = Utils::OpenHandle(this_);
4617   auto value_obj = Utils::OpenHandle(*value);
4618   // TODO(333672197): turn this to DCHECK once it's no longer possible
4619   // to get JSGlobalObject via API.
4620   CHECK_IMPLIES(from_javascript, !value_obj->IsJSGlobalObject());
4621   if (self->IsJSObject()) {
4622     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
4623     // TODO(333672197): turn this to DCHECK once it's no longer possible
4624     // to get JSGlobalObject via API.
4625     CHECK_IMPLIES(from_javascript, !self->IsJSGlobalObject());
4626     auto result =
4627         i::JSObject::SetPrototype(i_isolate, i::Handle<i::JSObject>::cast(self),
4628                                   value_obj, from_javascript, i::kDontThrow);
4629     if (!result.FromJust()) return Nothing<bool>();
4630     return Just(true);
4631   }
4632   if (self->IsJSProxy()) {
4633     ENTER_V8(i_isolate, context, Object, SetPrototype, Nothing<bool>(), i::HandleScope);
4634     // We do not allow exceptions thrown while setting the prototype
4635     // to propagate outside.
4636     TryCatch try_catch(reinterpret_cast<v8::Isolate*>(i_isolate));
4637     auto result =
4638         i::JSProxy::SetPrototype(i_isolate, i::Handle<i::JSProxy>::cast(self),
4639                                  value_obj, from_javascript, i::kThrowOnError);
4640     has_pending_exception = result.IsNothing();
4641     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4642     return Just(true);
4643   }
4644   // Wasm object or other kind of special object not supported here.
4645   return Nothing<bool>();
4646 }
4647 
4648 }  // namespace
4649 
SetPrototypeV2(Local<Context> context,Local<Value> value)4650 Maybe<bool> v8::Object::SetPrototypeV2(Local<Context> context,
4651                                        Local<Value> value) {
4652   static constexpr bool from_javascript = true;
4653   return SetPrototypeImpl(this, context, value, from_javascript);
4654 }
4655 
SetPrototype(Local<Context> context,Local<Value> value)4656 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4657                                      Local<Value> value) {
4658   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4659   auto self = Utils::OpenHandle(this);
4660   auto value_obj = Utils::OpenHandle(*value);
4661   if (self->IsJSProxy()) {
4662     ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4663              i::HandleScope);
4664     // We do not allow exceptions thrown while setting the prototype
4665     // to propagate outside.
4666     TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4667     auto result =
4668         i::JSProxy::SetPrototype(isolate, i::Handle<i::JSProxy>::cast(self),
4669                                  value_obj, false, i::kThrowOnError);
4670     has_pending_exception = result.IsNothing();
4671     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4672   } else {
4673     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4674     auto result =
4675         i::JSObject::SetPrototype(isolate, i::Handle<i::JSObject>::cast(self),
4676                                   value_obj, false, i::kThrowOnError);
4677     if (result.IsNothing()) {
4678       isolate->clear_pending_exception();
4679       return Nothing<bool>();
4680     }
4681   }
4682   return Just(true);
4683 }
4684 
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4685 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4686     v8::Local<FunctionTemplate> tmpl) {
4687   auto self = Utils::OpenHandle(this);
4688   auto isolate = self->GetIsolate();
4689   i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4690   auto tmpl_info = *Utils::OpenHandle(*tmpl);
4691   while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4692     iter.Advance();
4693     if (iter.IsAtEnd()) return Local<Object>();
4694     if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4695   }
4696   // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4697   return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4698 }
4699 
GetPropertyNames(Local<Context> context)4700 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4701   return GetPropertyNames(
4702       context, v8::KeyCollectionMode::kIncludePrototypes,
4703       static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4704       v8::IndexFilter::kIncludeIndices);
4705 }
4706 
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4707 MaybeLocal<Array> v8::Object::GetPropertyNames(
4708     Local<Context> context, KeyCollectionMode mode,
4709     PropertyFilter property_filter, IndexFilter index_filter,
4710     KeyConversionMode key_conversion) {
4711   PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4712   auto self = Utils::OpenHandle(this);
4713   i::Handle<i::FixedArray> value;
4714   i::KeyAccumulator accumulator(
4715       isolate, static_cast<i::KeyCollectionMode>(mode),
4716       static_cast<i::PropertyFilter>(property_filter));
4717   accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4718   has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4719   RETURN_ON_FAILED_EXECUTION(Array);
4720   value =
4721       accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4722   DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4723          self->map().EnumLength() == 0 ||
4724          self->map().instance_descriptors(isolate).enum_cache().keys() !=
4725              *value);
4726   auto result = isolate->factory()->NewJSArrayWithElements(value);
4727   RETURN_ESCAPED(Utils::ToLocal(result));
4728 }
4729 
GetOwnPropertyNames(Local<Context> context)4730 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4731   return GetOwnPropertyNames(
4732       context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4733 }
4734 
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4735 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4736     Local<Context> context, PropertyFilter filter,
4737     KeyConversionMode key_conversion) {
4738   return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4739                           v8::IndexFilter::kIncludeIndices, key_conversion);
4740 }
4741 
ObjectProtoToString(Local<Context> context)4742 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4743   PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4744   auto self = Utils::OpenHandle(this);
4745   Local<Value> result;
4746   has_pending_exception = !ToLocal<Value>(
4747       i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4748                                 nullptr),
4749       &result);
4750   RETURN_ON_FAILED_EXECUTION(String);
4751   RETURN_ESCAPED(Local<String>::Cast(result));
4752 }
4753 
GetConstructorName()4754 Local<String> v8::Object::GetConstructorName() {
4755   auto self = Utils::OpenHandle(this);
4756   // TODO(v8:12547): Support shared objects.
4757   DCHECK(!self->InSharedHeap());
4758   i::Handle<i::String> name =
4759       i::JSReceiver::GetConstructorName(self->GetIsolate(), self);
4760   return Utils::ToLocal(name);
4761 }
4762 
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4763 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4764                                           IntegrityLevel level) {
4765   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4766   ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4767            i::HandleScope);
4768   auto self = Utils::OpenHandle(this);
4769   i::JSReceiver::IntegrityLevel i_level =
4770       level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4771   Maybe<bool> result =
4772       i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4773   has_pending_exception = result.IsNothing();
4774   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4775   return result;
4776 }
4777 
Delete(Local<Context> context,Local<Value> key)4778 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4779   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4780   auto self = Utils::OpenHandle(this);
4781   auto key_obj = Utils::OpenHandle(*key);
4782   if (self->IsJSProxy()) {
4783     ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4784     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4785         isolate, self, key_obj, i::LanguageMode::kSloppy);
4786     has_pending_exception = result.IsNothing();
4787     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4788     return result;
4789   } else {
4790     // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4791     // a script.
4792     ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4793                        i::HandleScope);
4794     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4795         isolate, self, key_obj, i::LanguageMode::kSloppy);
4796     has_pending_exception = result.IsNothing();
4797     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4798     return result;
4799   }
4800 }
4801 
DeletePrivate(Local<Context> context,Local<Private> key)4802 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4803                                       Local<Private> key) {
4804   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4805   // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4806   // any author script.
4807   ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4808                      i::HandleScope);
4809   auto self = Utils::OpenHandle(this);
4810   auto key_obj = Utils::OpenHandle(*key);
4811   Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4812       isolate, self, key_obj, i::LanguageMode::kSloppy);
4813   has_pending_exception = result.IsNothing();
4814   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4815   return result;
4816 }
4817 
Has(Local<Context> context,Local<Value> key)4818 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4819   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4820   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4821   auto self = Utils::OpenHandle(this);
4822   auto key_obj = Utils::OpenHandle(*key);
4823   Maybe<bool> maybe = Nothing<bool>();
4824   // Check if the given key is an array index.
4825   uint32_t index = 0;
4826   if (key_obj->ToArrayIndex(&index)) {
4827     maybe = i::JSReceiver::HasElement(isolate, self, index);
4828   } else {
4829     // Convert the key to a name - possibly by calling back into JavaScript.
4830     i::Handle<i::Name> name;
4831     if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4832       maybe = i::JSReceiver::HasProperty(isolate, self, name);
4833     }
4834   }
4835   has_pending_exception = maybe.IsNothing();
4836   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4837   return maybe;
4838 }
4839 
HasPrivate(Local<Context> context,Local<Private> key)4840 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4841   return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4842 }
4843 
Delete(Local<Context> context,uint32_t index)4844 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4845   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4846   ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4847   auto self = Utils::OpenHandle(this);
4848   Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4849   has_pending_exception = result.IsNothing();
4850   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4851   return result;
4852 }
4853 
Has(Local<Context> context,uint32_t index)4854 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4855   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4856   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4857   auto self = Utils::OpenHandle(this);
4858   auto maybe = i::JSReceiver::HasElement(isolate, self, index);
4859   has_pending_exception = maybe.IsNothing();
4860   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4861   return maybe;
4862 }
4863 
4864 template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4865 static Maybe<bool> ObjectSetAccessor(
4866     Local<Context> context, Object* self, Local<Name> name, Getter getter,
4867     Setter setter, Data data, AccessControl settings,
4868     PropertyAttribute attributes, bool is_special_data_property,
4869     bool replace_on_access, SideEffectType getter_side_effect_type,
4870     SideEffectType setter_side_effect_type) {
4871   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4872   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4873                      i::HandleScope);
4874   if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4875   i::Handle<i::JSObject> obj =
4876       i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4877   v8::Local<AccessorSignature> signature;
4878   i::Handle<i::AccessorInfo> info =
4879       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4880                        is_special_data_property, replace_on_access);
4881   info->set_getter_side_effect_type(getter_side_effect_type);
4882   info->set_setter_side_effect_type(setter_side_effect_type);
4883   if (info.is_null()) return Nothing<bool>();
4884   bool fast = obj->HasFastProperties();
4885   i::Handle<i::Object> result;
4886 
4887   i::Handle<i::Name> accessor_name(info->name(), isolate);
4888   i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4889   has_pending_exception =
4890       !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4891            .ToHandle(&result);
4892   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4893   if (result->IsUndefined(isolate)) return Just(false);
4894   if (fast) {
4895     i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4896   }
4897   return Just(true);
4898 }
4899 
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4900 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4901                                 AccessorNameGetterCallback getter,
4902                                 AccessorNameSetterCallback setter,
4903                                 MaybeLocal<Value> data, AccessControl settings,
4904                                 PropertyAttribute attribute,
4905                                 SideEffectType getter_side_effect_type,
4906                                 SideEffectType setter_side_effect_type) {
4907   return ObjectSetAccessor(context, this, name, getter, setter,
4908                            data.FromMaybe(Local<Value>()), settings, attribute,
4909                            i::FLAG_disable_old_api_accessors, false,
4910                            getter_side_effect_type, setter_side_effect_type);
4911 }
4912 
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4913 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4914                                  Local<Function> setter,
4915                                  PropertyAttribute attribute,
4916                                  AccessControl settings) {
4917   // TODO(verwaest): Remove |settings|.
4918   DCHECK_EQ(v8::DEFAULT, settings);
4919   auto self = Utils::OpenHandle(this);
4920   i::Isolate* isolate = self->GetIsolate();
4921   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4922   i::HandleScope scope(isolate);
4923   if (!self->IsJSObject()) return;
4924   i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4925   i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4926   if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4927   i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4928                               v8::Utils::OpenHandle(*name), getter_i, setter_i,
4929                               static_cast<i::PropertyAttributes>(attribute));
4930 }
4931 
SetNativeDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4932 Maybe<bool> Object::SetNativeDataProperty(
4933     v8::Local<v8::Context> context, v8::Local<Name> name,
4934     AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4935     v8::Local<Value> data, PropertyAttribute attributes,
4936     SideEffectType getter_side_effect_type,
4937     SideEffectType setter_side_effect_type) {
4938   return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4939                            attributes, true, false, getter_side_effect_type,
4940                            setter_side_effect_type);
4941 }
4942 
SetLazyDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4943 Maybe<bool> Object::SetLazyDataProperty(
4944     v8::Local<v8::Context> context, v8::Local<Name> name,
4945     AccessorNameGetterCallback getter, v8::Local<Value> data,
4946     PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4947     SideEffectType setter_side_effect_type) {
4948   return ObjectSetAccessor(context, this, name, getter,
4949                            static_cast<AccessorNameSetterCallback>(nullptr),
4950                            data, DEFAULT, attributes, true, true,
4951                            getter_side_effect_type, setter_side_effect_type);
4952 }
4953 
HasOwnProperty(Local<Context> context,Local<Name> key)4954 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4955                                        Local<Name> key) {
4956   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4957   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4958            i::HandleScope);
4959   auto self = Utils::OpenHandle(this);
4960   auto key_val = Utils::OpenHandle(*key);
4961   auto result = i::JSReceiver::HasOwnProperty(isolate, self, key_val);
4962   has_pending_exception = result.IsNothing();
4963   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4964   return result;
4965 }
4966 
HasOwnProperty(Local<Context> context,uint32_t index)4967 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4968   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4969   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4970            i::HandleScope);
4971   auto self = Utils::OpenHandle(this);
4972   auto result = i::JSReceiver::HasOwnProperty(isolate, self, index);
4973   has_pending_exception = result.IsNothing();
4974   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4975   return result;
4976 }
4977 
HasRealNamedProperty(Local<Context> context,Local<Name> key)4978 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4979                                              Local<Name> key) {
4980   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4981   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4982                      Nothing<bool>(), i::HandleScope);
4983   auto self = Utils::OpenHandle(this);
4984   if (!self->IsJSObject()) return Just(false);
4985   auto key_val = Utils::OpenHandle(*key);
4986   auto result = i::JSObject::HasRealNamedProperty(
4987       isolate, i::Handle<i::JSObject>::cast(self), key_val);
4988   has_pending_exception = result.IsNothing();
4989   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4990   return result;
4991 }
4992 
HasRealIndexedProperty(Local<Context> context,uint32_t index)4993 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4994                                                uint32_t index) {
4995   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4996   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4997                      Nothing<bool>(), i::HandleScope);
4998   auto self = Utils::OpenHandle(this);
4999   if (!self->IsJSObject()) return Just(false);
5000   auto result = i::JSObject::HasRealElementProperty(
5001       isolate, i::Handle<i::JSObject>::cast(self), index);
5002   has_pending_exception = result.IsNothing();
5003   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5004   return result;
5005 }
5006 
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)5007 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
5008                                                      Local<Name> key) {
5009   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5010   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
5011                      Nothing<bool>(), i::HandleScope);
5012   auto self = Utils::OpenHandle(this);
5013   if (!self->IsJSObject()) return Just(false);
5014   auto key_val = Utils::OpenHandle(*key);
5015   auto result = i::JSObject::HasRealNamedCallbackProperty(
5016       isolate, i::Handle<i::JSObject>::cast(self), key_val);
5017   has_pending_exception = result.IsNothing();
5018   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5019   return result;
5020 }
5021 
HasNamedLookupInterceptor() const5022 bool v8::Object::HasNamedLookupInterceptor() const {
5023   auto self = *Utils::OpenHandle(this);
5024   if (self.IsJSObject()) return false;
5025   return i::JSObject::cast(self).HasNamedInterceptor();
5026 }
5027 
HasIndexedLookupInterceptor() const5028 bool v8::Object::HasIndexedLookupInterceptor() const {
5029   auto self = *Utils::OpenHandle(this);
5030   if (self.IsJSObject()) return false;
5031   return i::JSObject::cast(self).HasIndexedInterceptor();
5032 }
5033 
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)5034 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
5035     Local<Context> context, Local<Name> key) {
5036   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
5037                         Value);
5038   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5039   if (!self->IsJSObject()) return MaybeLocal<Value>();
5040   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5041   i::PrototypeIterator iter(isolate, self);
5042   if (iter.IsAtEnd()) return MaybeLocal<Value>();
5043   i::Handle<i::JSReceiver> proto =
5044       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5045   i::PropertyKey lookup_key(isolate, key_obj);
5046   i::LookupIterator it(isolate, self, lookup_key, proto,
5047                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5048   Local<Value> result;
5049   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5050   RETURN_ON_FAILED_EXECUTION(Value);
5051   if (!it.IsFound()) return MaybeLocal<Value>();
5052   RETURN_ESCAPED(result);
5053 }
5054 
5055 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)5056 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
5057     Local<Context> context, Local<Name> key) {
5058   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5059   ENTER_V8(isolate, context, Object,
5060            GetRealNamedPropertyAttributesInPrototypeChain,
5061            Nothing<PropertyAttribute>(), i::HandleScope);
5062   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5063   if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
5064   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5065   i::PrototypeIterator iter(isolate, self);
5066   if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
5067   i::Handle<i::JSReceiver> proto =
5068       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5069   i::PropertyKey lookup_key(isolate, key_obj);
5070   i::LookupIterator it(isolate, self, lookup_key, proto,
5071                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5072   Maybe<i::PropertyAttributes> result =
5073       i::JSReceiver::GetPropertyAttributes(&it);
5074   has_pending_exception = result.IsNothing();
5075   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5076   if (!it.IsFound()) return Nothing<PropertyAttribute>();
5077   if (result.FromJust() == i::ABSENT) return Just(None);
5078   return Just(static_cast<PropertyAttribute>(result.FromJust()));
5079 }
5080 
GetRealNamedProperty(Local<Context> context,Local<Name> key)5081 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
5082                                                    Local<Name> key) {
5083   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
5084   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5085   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5086   i::PropertyKey lookup_key(isolate, key_obj);
5087   i::LookupIterator it(isolate, self, lookup_key, self,
5088                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5089   Local<Value> result;
5090   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5091   RETURN_ON_FAILED_EXECUTION(Value);
5092   if (!it.IsFound()) return MaybeLocal<Value>();
5093   RETURN_ESCAPED(result);
5094 }
5095 
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)5096 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5097     Local<Context> context, Local<Name> key) {
5098   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5099   ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
5100            Nothing<PropertyAttribute>(), i::HandleScope);
5101   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5102   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5103   i::PropertyKey lookup_key(isolate, key_obj);
5104   i::LookupIterator it(isolate, self, lookup_key, self,
5105                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5106   auto result = i::JSReceiver::GetPropertyAttributes(&it);
5107   has_pending_exception = result.IsNothing();
5108   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5109   if (!it.IsFound()) return Nothing<PropertyAttribute>();
5110   if (result.FromJust() == i::ABSENT) {
5111     return Just(static_cast<PropertyAttribute>(i::NONE));
5112   }
5113   return Just<PropertyAttribute>(
5114       static_cast<PropertyAttribute>(result.FromJust()));
5115 }
5116 
Clone()5117 Local<v8::Object> v8::Object::Clone() {
5118   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5119   auto isolate = self->GetIsolate();
5120   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5121   i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
5122   return Utils::ToLocal(result);
5123 }
5124 
5125 namespace {
CreationContextImpl(i::Handle<i::JSReceiver> self)5126 Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) {
5127   i::Handle<i::Context> context;
5128   if (self->GetCreationContext().ToHandle(&context)) {
5129     return Utils::ToLocal(context);
5130   }
5131 
5132   return Local<v8::Context>();
5133 }
5134 }  // namespace
5135 
CreationContext()5136 Local<v8::Context> v8::Object::CreationContext() {
5137   auto self = Utils::OpenHandle(this);
5138   return CreationContextImpl(self);
5139 }
5140 
CreationContext(const PersistentBase<Object> & object)5141 Local<v8::Context> v8::Object::CreationContext(
5142     const PersistentBase<Object>& object) {
5143   auto self = Utils::OpenHandle(object.val_);
5144   return CreationContextImpl(self);
5145 }
5146 
GetCreationContext()5147 MaybeLocal<v8::Context> v8::Object::GetCreationContext() {
5148   auto self = Utils::OpenHandle(this);
5149   i::Handle<i::Context> context;
5150   if (self->GetCreationContext().ToHandle(&context)) {
5151     return Utils::ToLocal(context);
5152   }
5153   return MaybeLocal<v8::Context>();
5154 }
5155 
GetCreationContextChecked()5156 Local<v8::Context> v8::Object::GetCreationContextChecked() {
5157   Local<Context> context;
5158   Utils::ApiCheck(GetCreationContext().ToLocal(&context),
5159                   "v8::Object::GetCreationContextChecked",
5160                   "No creation context available");
5161   return context;
5162 }
5163 
GetIdentityHash()5164 int v8::Object::GetIdentityHash() {
5165   i::DisallowGarbageCollection no_gc;
5166   auto self = Utils::OpenHandle(this);
5167   auto isolate = self->GetIsolate();
5168   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
5169   i::HandleScope scope(isolate);
5170   return self->GetOrCreateIdentityHash(isolate).value();
5171 }
5172 
IsCallable() const5173 bool v8::Object::IsCallable() const {
5174   auto self = Utils::OpenHandle(this);
5175   return self->IsCallable();
5176 }
5177 
IsConstructor() const5178 bool v8::Object::IsConstructor() const {
5179   auto self = Utils::OpenHandle(this);
5180   return self->IsConstructor();
5181 }
5182 
IsApiWrapper() const5183 bool v8::Object::IsApiWrapper() const {
5184   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5185   // Objects with embedder fields can wrap API objects.
5186   return self->MayHaveEmbedderFields();
5187 }
5188 
IsUndetectable() const5189 bool v8::Object::IsUndetectable() const {
5190   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5191   return self->IsUndetectable();
5192 }
5193 
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5194 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5195                                          Local<Value> recv, int argc,
5196                                          Local<Value> argv[]) {
5197   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5198   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5199   ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5200            InternalEscapableScope);
5201   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5202   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5203                                              isolate);
5204   auto self = Utils::OpenHandle(this);
5205   auto recv_obj = Utils::OpenHandle(*recv);
5206   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5207   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5208   Local<Value> result;
5209   has_pending_exception = !ToLocal<Value>(
5210       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5211   RETURN_ON_FAILED_EXECUTION(Value);
5212   RETURN_ESCAPED(result);
5213 }
5214 
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5215 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5216                                             Local<Value> argv[]) {
5217   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5218   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5219   ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5220            InternalEscapableScope);
5221   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5222   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5223                                              isolate);
5224   auto self = Utils::OpenHandle(this);
5225   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5226   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5227   Local<Value> result;
5228   has_pending_exception = !ToLocal<Value>(
5229       i::Execution::New(isolate, self, self, argc, args), &result);
5230   RETURN_ON_FAILED_EXECUTION(Value);
5231   RETURN_ESCAPED(result);
5232 }
5233 
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)5234 MaybeLocal<Function> Function::New(Local<Context> context,
5235                                    FunctionCallback callback, Local<Value> data,
5236                                    int length, ConstructorBehavior behavior,
5237                                    SideEffectType side_effect_type) {
5238   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5239   API_RCS_SCOPE(isolate, Function, New);
5240   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5241   auto templ =
5242       FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
5243                           behavior, true, Local<Private>(), side_effect_type);
5244   return templ->GetFunction(context);
5245 }
5246 
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5247 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5248                                          v8::Local<v8::Value> argv[]) const {
5249   return NewInstanceWithSideEffectType(context, argc, argv,
5250                                        SideEffectType::kHasSideEffect);
5251 }
5252 
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const5253 MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
5254     Local<Context> context, int argc, v8::Local<v8::Value> argv[],
5255     SideEffectType side_effect_type) const {
5256   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5257   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5258   ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5259            InternalEscapableScope);
5260   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5261   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5262                                              isolate);
5263   auto self = Utils::OpenHandle(this);
5264   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5265   bool should_set_has_no_side_effect =
5266       side_effect_type == SideEffectType::kHasNoSideEffect &&
5267       isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
5268   if (should_set_has_no_side_effect) {
5269     CHECK(self->IsJSFunction() &&
5270           i::JSFunction::cast(*self).shared().IsApiFunction());
5271     i::Object obj =
5272         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5273             kAcquireLoad);
5274     if (obj.IsCallHandlerInfo()) {
5275       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5276       if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
5277         handler_info.SetNextCallHasNoSideEffect();
5278       }
5279     }
5280   }
5281   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5282   Local<Object> result;
5283   has_pending_exception = !ToLocal<Object>(
5284       i::Execution::New(isolate, self, self, argc, args), &result);
5285   if (should_set_has_no_side_effect) {
5286     i::Object obj =
5287         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5288             kAcquireLoad);
5289     if (obj.IsCallHandlerInfo()) {
5290       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5291       if (has_pending_exception) {
5292         // Restore the map if an exception prevented restoration.
5293         handler_info.NextCallHasNoSideEffect();
5294       } else {
5295         DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
5296                handler_info.IsSideEffectFreeCallHandlerInfo());
5297       }
5298     }
5299   }
5300   RETURN_ON_FAILED_EXECUTION(Object);
5301   RETURN_ESCAPED(result);
5302 }
5303 
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5304 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5305                                      v8::Local<v8::Value> recv, int argc,
5306                                      v8::Local<v8::Value> argv[]) {
5307   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5308   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5309   ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5310            InternalEscapableScope);
5311   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5312   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5313                                              isolate);
5314   auto self = Utils::OpenHandle(this);
5315   Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
5316                   "Function to be called is a null pointer");
5317   i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5318   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5319   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5320   Local<Value> result;
5321   has_pending_exception = !ToLocal<Value>(
5322       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5323   RETURN_ON_FAILED_EXECUTION(Value);
5324   RETURN_ESCAPED(result);
5325 }
5326 
SetName(v8::Local<v8::String> name)5327 void Function::SetName(v8::Local<v8::String> name) {
5328   auto self = Utils::OpenHandle(this);
5329   if (!self->IsJSFunction()) return;
5330   auto func = i::Handle<i::JSFunction>::cast(self);
5331   ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
5332   func->shared().SetName(*Utils::OpenHandle(*name));
5333 }
5334 
GetName() const5335 Local<Value> Function::GetName() const {
5336   auto self = Utils::OpenHandle(this);
5337   i::Isolate* isolate = self->GetIsolate();
5338   if (self->IsJSBoundFunction()) {
5339     auto func = i::Handle<i::JSBoundFunction>::cast(self);
5340     i::Handle<i::Object> name;
5341     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5342                                      i::JSBoundFunction::GetName(isolate, func),
5343                                      Local<Value>());
5344     return Utils::ToLocal(name);
5345   }
5346   if (self->IsJSFunction()) {
5347     auto func = i::Handle<i::JSFunction>::cast(self);
5348     return Utils::ToLocal(handle(func->shared().Name(), isolate));
5349   }
5350   return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5351 }
5352 
GetInferredName() const5353 Local<Value> Function::GetInferredName() const {
5354   auto self = Utils::OpenHandle(this);
5355   if (!self->IsJSFunction()) {
5356     return ToApiHandle<Primitive>(
5357         self->GetIsolate()->factory()->undefined_value());
5358   }
5359   auto func = i::Handle<i::JSFunction>::cast(self);
5360   return Utils::ToLocal(
5361       i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5362 }
5363 
GetDebugName() const5364 Local<Value> Function::GetDebugName() const {
5365   auto self = Utils::OpenHandle(this);
5366   if (!self->IsJSFunction()) {
5367     return ToApiHandle<Primitive>(
5368         self->GetIsolate()->factory()->undefined_value());
5369   }
5370   auto func = i::Handle<i::JSFunction>::cast(self);
5371   i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5372   return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5373 }
5374 
GetScriptOrigin() const5375 ScriptOrigin Function::GetScriptOrigin() const {
5376   auto self = Utils::OpenHandle(this);
5377   auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate());
5378   if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>());
5379   auto func = i::Handle<i::JSFunction>::cast(self);
5380   if (func->shared().script().IsScript()) {
5381     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5382                                 func->GetIsolate());
5383     return GetScriptOriginForScript(func->GetIsolate(), script);
5384   }
5385   return v8::ScriptOrigin(isolate, Local<Value>());
5386 }
5387 
5388 const int Function::kLineOffsetNotFound = -1;
5389 
GetScriptLineNumber() const5390 int Function::GetScriptLineNumber() const {
5391   auto self = Utils::OpenHandle(this);
5392   if (!self->IsJSFunction()) {
5393     return kLineOffsetNotFound;
5394   }
5395   auto func = i::Handle<i::JSFunction>::cast(self);
5396   if (func->shared().script().IsScript()) {
5397     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5398                                 func->GetIsolate());
5399     return i::Script::GetLineNumber(script, func->shared().StartPosition());
5400   }
5401   return kLineOffsetNotFound;
5402 }
5403 
GetScriptColumnNumber() const5404 int Function::GetScriptColumnNumber() const {
5405   auto self = Utils::OpenHandle(this);
5406   if (!self->IsJSFunction()) {
5407     return kLineOffsetNotFound;
5408   }
5409   auto func = i::Handle<i::JSFunction>::cast(self);
5410   if (func->shared().script().IsScript()) {
5411     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5412                                 func->GetIsolate());
5413     return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5414   }
5415   return kLineOffsetNotFound;
5416 }
5417 
GetUnboundScript() const5418 MaybeLocal<UnboundScript> Function::GetUnboundScript() const {
5419   i::Handle<i::Object> self = Utils::OpenHandle(this);
5420   if (!self->IsJSFunction()) return MaybeLocal<UnboundScript>();
5421   i::SharedFunctionInfo sfi = i::JSFunction::cast(*self).shared();
5422   i::Isolate* isolate = sfi.GetIsolate();
5423   return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
5424 }
5425 
ScriptId() const5426 int Function::ScriptId() const {
5427   i::JSReceiver self = *Utils::OpenHandle(this);
5428   if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
5429   auto func = i::JSFunction::cast(self);
5430   if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
5431   return i::Script::cast(func.shared().script()).id();
5432 }
5433 
GetBoundFunction() const5434 Local<v8::Value> Function::GetBoundFunction() const {
5435   auto self = Utils::OpenHandle(this);
5436   if (self->IsJSBoundFunction()) {
5437     auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5438     auto bound_target_function = i::handle(
5439         bound_function->bound_target_function(), bound_function->GetIsolate());
5440     return Utils::CallableToLocal(bound_target_function);
5441   }
5442   return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5443 }
5444 
FunctionProtoToString(Local<Context> context)5445 MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5446   PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5447   auto self = Utils::OpenHandle(this);
5448   Local<Value> result;
5449   has_pending_exception = !ToLocal<Value>(
5450       i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5451                                 nullptr),
5452       &result);
5453   RETURN_ON_FAILED_EXECUTION(String);
5454   RETURN_ESCAPED(Local<String>::Cast(result));
5455 }
5456 
GetIdentityHash()5457 int Name::GetIdentityHash() {
5458   auto self = Utils::OpenHandle(this);
5459   return static_cast<int>(self->EnsureHash());
5460 }
5461 
Length() const5462 int String::Length() const {
5463   i::Handle<i::String> str = Utils::OpenHandle(this);
5464   return str->length();
5465 }
5466 
IsOneByte() const5467 bool String::IsOneByte() const {
5468   i::Handle<i::String> str = Utils::OpenHandle(this);
5469   return str->IsOneByteRepresentation();
5470 }
5471 
5472 // Helpers for ContainsOnlyOneByteHelper
5473 template <size_t size>
5474 struct OneByteMask;
5475 template <>
5476 struct OneByteMask<4> {
5477   static const uint32_t value = 0xFF00FF00;
5478 };
5479 template <>
5480 struct OneByteMask<8> {
5481   static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5482 };
5483 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5484 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5485 static inline bool Unaligned(const uint16_t* chars) {
5486   return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5487 }
5488 
Align(const uint16_t * chars)5489 static inline const uint16_t* Align(const uint16_t* chars) {
5490   return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5491                                      ~kAlignmentMask);
5492 }
5493 
5494 class ContainsOnlyOneByteHelper {
5495  public:
ContainsOnlyOneByteHelper()5496   ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5497   ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5498   ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5499       delete;
Check(i::String string)5500   bool Check(i::String string) {
5501     i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5502     if (cons_string.is_null()) return is_one_byte_;
5503     return CheckCons(cons_string);
5504   }
VisitOneByteString(const uint8_t * chars,int length)5505   void VisitOneByteString(const uint8_t* chars, int length) {
5506     // Nothing to do.
5507   }
VisitTwoByteString(const uint16_t * chars,int length)5508   void VisitTwoByteString(const uint16_t* chars, int length) {
5509     // Accumulated bits.
5510     uintptr_t acc = 0;
5511     // Align to uintptr_t.
5512     const uint16_t* end = chars + length;
5513     while (Unaligned(chars) && chars != end) {
5514       acc |= *chars++;
5515     }
5516     // Read word aligned in blocks,
5517     // checking the return value at the end of each block.
5518     const uint16_t* aligned_end = Align(end);
5519     const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5520     const int inner_loops = 16;
5521     while (chars + inner_loops * increment < aligned_end) {
5522       for (int i = 0; i < inner_loops; i++) {
5523         acc |= *reinterpret_cast<const uintptr_t*>(chars);
5524         chars += increment;
5525       }
5526       // Check for early return.
5527       if ((acc & kOneByteMask) != 0) {
5528         is_one_byte_ = false;
5529         return;
5530       }
5531     }
5532     // Read the rest.
5533     while (chars != end) {
5534       acc |= *chars++;
5535     }
5536     // Check result.
5537     if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5538   }
5539 
5540  private:
CheckCons(i::ConsString cons_string)5541   bool CheckCons(i::ConsString cons_string) {
5542     while (true) {
5543       // Check left side if flat.
5544       i::String left = cons_string.first();
5545       i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5546       if (!is_one_byte_) return false;
5547       // Check right side if flat.
5548       i::String right = cons_string.second();
5549       i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5550       if (!is_one_byte_) return false;
5551       // Standard recurse/iterate trick.
5552       if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5553         if (left.length() < right.length()) {
5554           CheckCons(left_as_cons);
5555           cons_string = right_as_cons;
5556         } else {
5557           CheckCons(right_as_cons);
5558           cons_string = left_as_cons;
5559         }
5560         // Check fast return.
5561         if (!is_one_byte_) return false;
5562         continue;
5563       }
5564       // Descend left in place.
5565       if (!left_as_cons.is_null()) {
5566         cons_string = left_as_cons;
5567         continue;
5568       }
5569       // Descend right in place.
5570       if (!right_as_cons.is_null()) {
5571         cons_string = right_as_cons;
5572         continue;
5573       }
5574       // Terminate.
5575       break;
5576     }
5577     return is_one_byte_;
5578   }
5579   bool is_one_byte_;
5580 };
5581 
ContainsOnlyOneByte() const5582 bool String::ContainsOnlyOneByte() const {
5583   i::Handle<i::String> str = Utils::OpenHandle(this);
5584   if (str->IsOneByteRepresentation()) return true;
5585   ContainsOnlyOneByteHelper helper;
5586   return helper.Check(*str);
5587 }
5588 
Utf8Length(Isolate * isolate) const5589 int String::Utf8Length(Isolate* isolate) const {
5590   i::Handle<i::String> str = Utils::OpenHandle(this);
5591   str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5592   int length = str->length();
5593   if (length == 0) return 0;
5594   i::DisallowGarbageCollection no_gc;
5595   i::String::FlatContent flat = str->GetFlatContent(no_gc);
5596   DCHECK(flat.IsFlat());
5597   int utf8_length = 0;
5598   if (flat.IsOneByte()) {
5599     for (uint8_t c : flat.ToOneByteVector()) {
5600       utf8_length += c >> 7;
5601     }
5602     utf8_length += length;
5603   } else {
5604     int last_character = unibrow::Utf16::kNoPreviousCharacter;
5605     for (uint16_t c : flat.ToUC16Vector()) {
5606       utf8_length += unibrow::Utf8::Length(c, last_character);
5607       last_character = c;
5608     }
5609   }
5610   return utf8_length;
5611 }
5612 
5613 namespace {
5614 // Writes the flat content of a string to a buffer. This is done in two phases.
5615 // The first phase calculates a pessimistic estimate (writable_length) on how
5616 // many code units can be safely written without exceeding the buffer capacity
5617 // and without leaving at a lone surrogate. The estimated number of code units
5618 // is then written out in one go, and the reported byte usage is used to
5619 // correct the estimate. This is repeated until the estimate becomes <= 0 or
5620 // all code units have been written out. The second phase writes out code
5621 // units until the buffer capacity is reached, would be exceeded by the next
5622 // unit, or all code units have been written out.
5623 template <typename Char>
WriteUtf8Impl(base::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5624 static int WriteUtf8Impl(base::Vector<const Char> string, char* write_start,
5625                          int write_capacity, int options,
5626                          int* utf16_chars_read_out) {
5627   bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5628   bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5629   char* current_write = write_start;
5630   const Char* read_start = string.begin();
5631   int read_index = 0;
5632   int read_length = string.length();
5633   int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5634   // Do a fast loop where there is no exit capacity check.
5635   // Need enough space to write everything but one character.
5636   STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5637   static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5638   while (read_index < read_length) {
5639     int up_to = read_length;
5640     if (write_capacity != -1) {
5641       int remaining_capacity =
5642           write_capacity - static_cast<int>(current_write - write_start);
5643       int writable_length =
5644           (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5645       // Need to drop into slow loop.
5646       if (writable_length <= 0) break;
5647       up_to = std::min(up_to, read_index + writable_length);
5648     }
5649     // Write the characters to the stream.
5650     if (sizeof(Char) == 1) {
5651       // Simply memcpy if we only have ASCII characters.
5652       uint8_t char_mask = 0;
5653       for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5654       if ((char_mask & 0x80) == 0) {
5655         int copy_length = up_to - read_index;
5656         memcpy(current_write, read_start + read_index, copy_length);
5657         current_write += copy_length;
5658         read_index = up_to;
5659       } else {
5660         for (; read_index < up_to; read_index++) {
5661           current_write += unibrow::Utf8::EncodeOneByte(
5662               current_write, static_cast<uint8_t>(read_start[read_index]));
5663           DCHECK(write_capacity == -1 ||
5664                  (current_write - write_start) <= write_capacity);
5665         }
5666       }
5667     } else {
5668       for (; read_index < up_to; read_index++) {
5669         uint16_t character = read_start[read_index];
5670         current_write += unibrow::Utf8::Encode(current_write, character,
5671                                                prev_char, replace_invalid_utf8);
5672         prev_char = character;
5673         DCHECK(write_capacity == -1 ||
5674                (current_write - write_start) <= write_capacity);
5675       }
5676     }
5677   }
5678   if (read_index < read_length) {
5679     DCHECK_NE(-1, write_capacity);
5680     // Aborted due to limited capacity. Check capacity on each iteration.
5681     int remaining_capacity =
5682         write_capacity - static_cast<int>(current_write - write_start);
5683     DCHECK_GE(remaining_capacity, 0);
5684     for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5685       uint32_t character = read_start[read_index];
5686       int written = 0;
5687       // We can't use a local buffer here because Encode needs to modify
5688       // previous characters in the stream.  We know, however, that
5689       // exactly one character will be advanced.
5690       if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5691         written = unibrow::Utf8::Encode(current_write, character, prev_char,
5692                                         replace_invalid_utf8);
5693         DCHECK_EQ(written, 1);
5694       } else {
5695         // Use a scratch buffer to check the required characters.
5696         char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5697         // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5698         static const int kSurrogatePairEncodedSize =
5699             static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5700         // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5701         // middle of a surrogate pair. Abort before encoding the pair instead.
5702         if (replace_invalid_utf8 &&
5703             remaining_capacity < kSurrogatePairEncodedSize &&
5704             unibrow::Utf16::IsLeadSurrogate(character) &&
5705             read_index + 1 < read_length &&
5706             unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5707           write_null = false;
5708           break;
5709         }
5710         // Can't encode using prev_char as gcc has array bounds issues.
5711         written = unibrow::Utf8::Encode(temp_buffer, character,
5712                                         unibrow::Utf16::kNoPreviousCharacter,
5713                                         replace_invalid_utf8);
5714         if (written > remaining_capacity) {
5715           // Won't fit. Abort and do not null-terminate the result.
5716           write_null = false;
5717           break;
5718         }
5719         // Copy over the character from temp_buffer.
5720         for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5721       }
5722 
5723       current_write += written;
5724       remaining_capacity -= written;
5725       prev_char = character;
5726     }
5727   }
5728 
5729   // Write out number of utf16 characters written to the stream.
5730   if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5731 
5732   // Only null-terminate if there's space.
5733   if (write_null && (write_capacity == -1 ||
5734                      (current_write - write_start) < write_capacity)) {
5735     *current_write++ = '\0';
5736   }
5737   return static_cast<int>(current_write - write_start);
5738 }
5739 }  // anonymous namespace
5740 
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5741 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5742                       int* nchars_ref, int options) const {
5743   i::Handle<i::String> str = Utils::OpenHandle(this);
5744   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5745   API_RCS_SCOPE(isolate, String, WriteUtf8);
5746   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5747   str = i::String::Flatten(isolate, str);
5748   i::DisallowGarbageCollection no_gc;
5749   i::String::FlatContent content = str->GetFlatContent(no_gc);
5750   if (content.IsOneByte()) {
5751     return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5752                                   options, nchars_ref);
5753   } else {
5754     return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5755                                    options, nchars_ref);
5756   }
5757 }
5758 
5759 template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5760 static inline int WriteHelper(i::Isolate* isolate, const String* string,
5761                               CharType* buffer, int start, int length,
5762                               int options) {
5763   API_RCS_SCOPE(isolate, String, Write);
5764   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5765   DCHECK(start >= 0 && length >= -1);
5766   i::Handle<i::String> str = Utils::OpenHandle(string);
5767   str = i::String::Flatten(isolate, str);
5768   int end = start + length;
5769   if ((length == -1) || (length > str->length() - start)) end = str->length();
5770   if (end < 0) return 0;
5771   int write_length = end - start;
5772   if (start < end) i::String::WriteToFlat(*str, buffer, start, write_length);
5773   if (!(options & String::NO_NULL_TERMINATION) &&
5774       (length == -1 || write_length < length)) {
5775     buffer[write_length] = '\0';
5776   }
5777   return write_length;
5778 }
5779 
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5780 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5781                          int length, int options) const {
5782   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5783                      start, length, options);
5784 }
5785 
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5786 int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5787                   int options) const {
5788   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5789                      start, length, options);
5790 }
5791 
IsExternal() const5792 bool v8::String::IsExternal() const {
5793   i::Handle<i::String> str = Utils::OpenHandle(this);
5794   return i::StringShape(*str).IsExternal();
5795 }
5796 
IsExternalTwoByte() const5797 bool v8::String::IsExternalTwoByte() const {
5798   i::Handle<i::String> str = Utils::OpenHandle(this);
5799   return i::StringShape(*str).IsExternalTwoByte();
5800 }
5801 
IsExternalOneByte() const5802 bool v8::String::IsExternalOneByte() const {
5803   i::Handle<i::String> str = Utils::OpenHandle(this);
5804   return i::StringShape(*str).IsExternalOneByte();
5805 }
5806 
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5807 void v8::String::VerifyExternalStringResource(
5808     v8::String::ExternalStringResource* value) const {
5809   i::DisallowGarbageCollection no_gc;
5810   i::String str = *Utils::OpenHandle(this);
5811   const v8::String::ExternalStringResource* expected;
5812 
5813   if (str.IsThinString()) {
5814     str = i::ThinString::cast(str).actual();
5815   }
5816 
5817   if (i::StringShape(str).IsExternalTwoByte()) {
5818     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5819     expected = reinterpret_cast<const ExternalStringResource*>(resource);
5820   } else {
5821     expected = nullptr;
5822   }
5823   CHECK_EQ(expected, value);
5824 }
5825 
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5826 void v8::String::VerifyExternalStringResourceBase(
5827     v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5828   i::DisallowGarbageCollection no_gc;
5829   i::String str = *Utils::OpenHandle(this);
5830   const v8::String::ExternalStringResourceBase* expected;
5831   Encoding expectedEncoding;
5832 
5833   if (str.IsThinString()) {
5834     str = i::ThinString::cast(str).actual();
5835   }
5836 
5837   if (i::StringShape(str).IsExternalOneByte()) {
5838     const void* resource = i::ExternalOneByteString::cast(str).resource();
5839     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5840     expectedEncoding = ONE_BYTE_ENCODING;
5841   } else if (i::StringShape(str).IsExternalTwoByte()) {
5842     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5843     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5844     expectedEncoding = TWO_BYTE_ENCODING;
5845   } else {
5846     expected = nullptr;
5847     expectedEncoding =
5848         str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5849   }
5850   CHECK_EQ(expected, value);
5851   CHECK_EQ(expectedEncoding, encoding);
5852 }
5853 
GetExternalStringResourceSlow() const5854 String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5855   i::DisallowGarbageCollection no_gc;
5856   using I = internal::Internals;
5857   i::String str = *Utils::OpenHandle(this);
5858 
5859   if (str.IsThinString()) {
5860     str = i::ThinString::cast(str).actual();
5861   }
5862 
5863   if (i::StringShape(str).IsExternalTwoByte()) {
5864     internal::Isolate* isolate = I::GetIsolateForSandbox(str.ptr());
5865     internal::Address value = I::ReadExternalPointerField(
5866         isolate, str.ptr(), I::kStringResourceOffset,
5867         internal::kExternalStringResourceTag);
5868     return reinterpret_cast<String::ExternalStringResource*>(value);
5869   }
5870   return nullptr;
5871 }
5872 
UpdateDataCache()5873 void String::ExternalStringResource::UpdateDataCache() {
5874   DCHECK(IsCacheable());
5875   cached_data_ = data();
5876 }
5877 
CheckCachedDataInvariants() const5878 void String::ExternalStringResource::CheckCachedDataInvariants() const {
5879   DCHECK(IsCacheable() && cached_data_ != nullptr);
5880 }
5881 
UpdateDataCache()5882 void String::ExternalOneByteStringResource::UpdateDataCache() {
5883   DCHECK(IsCacheable());
5884   cached_data_ = data();
5885 }
5886 
CheckCachedDataInvariants() const5887 void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5888   DCHECK(IsCacheable() && cached_data_ != nullptr);
5889 }
5890 
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5891 String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5892     String::Encoding* encoding_out) const {
5893   i::DisallowGarbageCollection no_gc;
5894   using I = internal::Internals;
5895   ExternalStringResourceBase* resource = nullptr;
5896   i::String str = *Utils::OpenHandle(this);
5897 
5898   if (str.IsThinString()) {
5899     str = i::ThinString::cast(str).actual();
5900   }
5901 
5902   internal::Address string = str.ptr();
5903   int type =
5904       I::GetInstanceType(string) & I::kStringRepresentationAndEncodingMask;
5905   *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5906   if (i::StringShape(str).IsExternalOneByte() ||
5907       i::StringShape(str).IsExternalTwoByte()) {
5908     internal::Isolate* isolate = I::GetIsolateForSandbox(string);
5909     internal::Address value =
5910         I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5911                                     internal::kExternalStringResourceTag);
5912     resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5913   }
5914   return resource;
5915 }
5916 
5917 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5918 v8::String::GetExternalOneByteStringResource() const {
5919   i::DisallowGarbageCollection no_gc;
5920   i::String str = *Utils::OpenHandle(this);
5921   if (i::StringShape(str).IsExternalOneByte()) {
5922     return i::ExternalOneByteString::cast(str).resource();
5923   } else if (str.IsThinString()) {
5924     str = i::ThinString::cast(str).actual();
5925     if (i::StringShape(str).IsExternalOneByte()) {
5926       return i::ExternalOneByteString::cast(str).resource();
5927     }
5928   }
5929   return nullptr;
5930 }
5931 
Description(Isolate * isolate) const5932 Local<Value> Symbol::Description(Isolate* isolate) const {
5933   i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5934   i::Handle<i::Object> description(sym->description(),
5935                                    reinterpret_cast<i::Isolate*>(isolate));
5936   return Utils::ToLocal(description);
5937 }
5938 
Name() const5939 Local<Value> Private::Name() const {
5940   const Symbol* sym = reinterpret_cast<const Symbol*>(this);
5941   i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym);
5942   // v8::Private symbols are created by API and are therefore writable, so we
5943   // can always recover an Isolate.
5944   i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym);
5945   return sym->Description(reinterpret_cast<Isolate*>(isolate));
5946 }
5947 
Value() const5948 double Number::Value() const {
5949   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5950   return obj->Number();
5951 }
5952 
Value() const5953 bool Boolean::Value() const {
5954   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5955   return obj->IsTrue();
5956 }
5957 
Value() const5958 int64_t Integer::Value() const {
5959   i::Object obj = *Utils::OpenHandle(this);
5960   if (obj.IsSmi()) {
5961     return i::Smi::ToInt(obj);
5962   } else {
5963     return static_cast<int64_t>(obj.Number());
5964   }
5965 }
5966 
Value() const5967 int32_t Int32::Value() const {
5968   i::Object obj = *Utils::OpenHandle(this);
5969   if (obj.IsSmi()) {
5970     return i::Smi::ToInt(obj);
5971   } else {
5972     return static_cast<int32_t>(obj.Number());
5973   }
5974 }
5975 
Value() const5976 uint32_t Uint32::Value() const {
5977   i::Object obj = *Utils::OpenHandle(this);
5978   if (obj.IsSmi()) {
5979     return i::Smi::ToInt(obj);
5980   } else {
5981     return static_cast<uint32_t>(obj.Number());
5982   }
5983 }
5984 
InternalFieldCount() const5985 int v8::Object::InternalFieldCount() const {
5986   i::JSReceiver self = *Utils::OpenHandle(this);
5987   if (!self.IsJSObject()) return 0;
5988   return i::JSObject::cast(self).GetEmbedderFieldCount();
5989 }
5990 
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5991 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5992                             const char* location) {
5993   return Utils::ApiCheck(
5994       obj->IsJSObject() &&
5995           (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5996       location, "Internal field out of bounds");
5997 }
5998 
SlowGetInternalField(int index)5999 Local<Value> v8::Object::SlowGetInternalField(int index) {
6000   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6001   const char* location = "v8::Object::GetInternalField()";
6002   if (!InternalFieldOK(obj, index, location)) return Local<Value>();
6003   i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
6004                              obj->GetIsolate());
6005   return Utils::ToLocal(value);
6006 }
6007 
6008 template<typename T>
SetInternalFieldImpl(v8::Object * receiver,int index,v8::Local<T> value)6009 void SetInternalFieldImpl(v8::Object* receiver, int index, v8::Local<T> value) {
6010   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(receiver);
6011   const char* location = "v8::Object::SetInternalField()";
6012   if (!InternalFieldOK(obj, index, location)) return;
6013   i::Handle<i::Object> val = Utils::OpenHandle(*value);
6014   i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
6015 }
6016 
SetInternalField(int index,v8::Local<Value> value)6017 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
6018   SetInternalFieldImpl(this, index, value);
6019 }
6020 
6021 /**
6022  * These are Node.js-specific extentions used to avoid breaking changes in
6023  * Node.js v20.x.
6024  */
SetInternalFieldForNodeCore(int index,v8::Local<Module> value)6025 void v8::Object::SetInternalFieldForNodeCore(int index,
6026                                              v8::Local<Module> value) {
6027   SetInternalFieldImpl(this, index, value);
6028 }
6029 
SetInternalFieldForNodeCore(int index,v8::Local<UnboundScript> value)6030 void v8::Object::SetInternalFieldForNodeCore(int index,
6031                                              v8::Local<UnboundScript> value) {
6032   SetInternalFieldImpl(this, index, value);
6033 }
6034 
SlowGetAlignedPointerFromInternalField(int index)6035 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
6036   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6037   const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
6038   if (!InternalFieldOK(obj, index, location)) return nullptr;
6039   void* result;
6040   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
6041                       .ToAlignedPointer(obj->GetIsolate(), &result),
6042                   location, "Unaligned pointer");
6043   return result;
6044 }
6045 
SetAlignedPointerInInternalField(int index,void * value)6046 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
6047   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6048   const char* location = "v8::Object::SetAlignedPointerInInternalField()";
6049   if (!InternalFieldOK(obj, index, location)) return;
6050 
6051   i::DisallowGarbageCollection no_gc;
6052 
6053   // There's no need to invalidate slots as embedder fields are always
6054   // tagged.
6055   obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
6056                                            i::InvalidateRecordedSlots::kNo);
6057 
6058   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
6059                       .store_aligned_pointer(obj->GetIsolate(), value),
6060                   location, "Unaligned pointer");
6061   DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6062   internal::WriteBarrier::MarkingFromInternalFields(i::JSObject::cast(*obj));
6063 
6064 #ifdef VERIFY_HEAP
6065   obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6066 #endif  // VERIFY_HEAP
6067 }
6068 
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])6069 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
6070                                                    void* values[]) {
6071   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6072 
6073   i::DisallowGarbageCollection no_gc;
6074   // There's no need to invalidate slots as embedder fields are always
6075   // tagged.
6076   obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
6077                                            i::InvalidateRecordedSlots::kNo);
6078 
6079   const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6080   i::JSObject js_obj = i::JSObject::cast(*obj);
6081   int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
6082   for (int i = 0; i < argc; i++) {
6083     int index = indices[i];
6084     if (!Utils::ApiCheck(index < nof_embedder_fields, location,
6085                          "Internal field out of bounds")) {
6086       return;
6087     }
6088     void* value = values[i];
6089     Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
6090                         .store_aligned_pointer(obj->GetIsolate(), value),
6091                     location, "Unaligned pointer");
6092     DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6093   }
6094   internal::WriteBarrier::MarkingFromInternalFields(js_obj);
6095 
6096 #ifdef VERIFY_HEAP
6097   obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6098 #endif  // VERIFY_HEAP
6099 }
6100 
6101 // --- E n v i r o n m e n t ---
6102 
InitializePlatform(Platform * platform)6103 void v8::V8::InitializePlatform(Platform* platform) {
6104   i::V8::InitializePlatform(platform);
6105 }
6106 
6107 #ifdef V8_SANDBOX
InitializeSandbox()6108 bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); }
6109 #endif
6110 
DisposePlatform()6111 void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); }
6112 
Initialize(const int build_config)6113 bool v8::V8::Initialize(const int build_config) {
6114   const bool kEmbedderPointerCompression =
6115       (build_config & kPointerCompression) != 0;
6116   if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
6117     FATAL(
6118         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6119         "pointer compression is %s while on V8 side it's %s.",
6120         kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
6121         COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6122   }
6123 
6124   const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
6125   if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
6126     FATAL(
6127         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6128         "Smi value size is %d while on V8 side it's %d.",
6129         kEmbedderSmiValueSize, internal::kSmiValueSize);
6130   }
6131 
6132   const bool kEmbedderSandboxedExternalPointers =
6133       (build_config & kSandboxedExternalPointers) != 0;
6134   if (kEmbedderSandboxedExternalPointers !=
6135       V8_SANDBOXED_EXTERNAL_POINTERS_BOOL) {
6136     FATAL(
6137         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6138         "sandboxed external pointers is %s while on V8 side it's %s.",
6139         kEmbedderSandboxedExternalPointers ? "ENABLED" : "DISABLED",
6140         V8_SANDBOXED_EXTERNAL_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6141   }
6142 
6143   const bool kEmbedderSandbox = (build_config & kSandbox) != 0;
6144   if (kEmbedderSandbox != V8_SANDBOX_BOOL) {
6145     FATAL(
6146         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6147         "sandbox is %s while on V8 side it's %s.",
6148         kEmbedderSandbox ? "ENABLED" : "DISABLED",
6149         V8_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
6150   }
6151 
6152   i::V8::Initialize();
6153   return true;
6154 }
6155 
6156 #if V8_OS_LINUX || V8_OS_DARWIN
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)6157 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
6158                                    void* context) {
6159 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6160   return i::trap_handler::TryHandleSignal(sig_code, info, context);
6161 #else
6162   return false;
6163 #endif
6164 }
6165 #endif
6166 
6167 #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)6168 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
6169 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6170   return i::trap_handler::TryHandleWasmTrap(exception);
6171 #else
6172   return false;
6173 #endif
6174 }
6175 #endif
6176 
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)6177 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6178 #if V8_ENABLE_WEBASSEMBLY
6179   return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
6180 #else
6181   return false;
6182 #endif
6183 }
6184 
6185 #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6186 void V8::SetUnhandledExceptionCallback(
6187     UnhandledExceptionCallback unhandled_exception_callback) {
6188 #if defined(V8_OS_WIN64)
6189   v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
6190       unhandled_exception_callback);
6191 #else
6192   // Not implemented, port needed.
6193 #endif  // V8_OS_WIN64
6194 }
6195 #endif  // V8_OS_WIN
6196 
SetFatalMemoryErrorCallback(v8::OOMErrorCallback oom_error_callback)6197 void v8::V8::SetFatalMemoryErrorCallback(
6198     v8::OOMErrorCallback oom_error_callback) {
6199   g_oom_error_callback = oom_error_callback;
6200 }
6201 
SetEntropySource(EntropySource entropy_source)6202 void v8::V8::SetEntropySource(EntropySource entropy_source) {
6203   base::RandomNumberGenerator::SetEntropySource(entropy_source);
6204 }
6205 
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6206 void v8::V8::SetReturnAddressLocationResolver(
6207     ReturnAddressLocationResolver return_address_resolver) {
6208   i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6209 }
6210 
Dispose()6211 bool v8::V8::Dispose() {
6212   i::V8::Dispose();
6213   return true;
6214 }
6215 
SharedMemoryStatistics()6216 SharedMemoryStatistics::SharedMemoryStatistics()
6217     : read_only_space_size_(0),
6218       read_only_space_used_size_(0),
6219       read_only_space_physical_size_(0) {}
6220 
HeapStatistics()6221 HeapStatistics::HeapStatistics()
6222     : total_heap_size_(0),
6223       total_heap_size_executable_(0),
6224       total_physical_size_(0),
6225       total_available_size_(0),
6226       used_heap_size_(0),
6227       heap_size_limit_(0),
6228       malloced_memory_(0),
6229       external_memory_(0),
6230       peak_malloced_memory_(0),
6231       does_zap_garbage_(false),
6232       number_of_native_contexts_(0),
6233       number_of_detached_contexts_(0) {}
6234 
HeapSpaceStatistics()6235 HeapSpaceStatistics::HeapSpaceStatistics()
6236     : space_name_(nullptr),
6237       space_size_(0),
6238       space_used_size_(0),
6239       space_available_size_(0),
6240       physical_space_size_(0) {}
6241 
HeapObjectStatistics()6242 HeapObjectStatistics::HeapObjectStatistics()
6243     : object_type_(nullptr),
6244       object_sub_type_(nullptr),
6245       object_count_(0),
6246       object_size_(0) {}
6247 
HeapCodeStatistics()6248 HeapCodeStatistics::HeapCodeStatistics()
6249     : code_and_metadata_size_(0),
6250       bytecode_and_metadata_size_(0),
6251       external_script_source_size_(0),
6252       cpu_profiler_metadata_size_(0) {}
6253 
InitializeICU(const char * icu_data_file)6254 bool v8::V8::InitializeICU(const char* icu_data_file) {
6255   return i::InitializeICU(icu_data_file);
6256 }
6257 
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6258 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6259                                           const char* icu_data_file) {
6260   return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6261 }
6262 
InitializeExternalStartupData(const char * directory_path)6263 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6264   i::InitializeExternalStartupData(directory_path);
6265 }
6266 
6267 // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)6268 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6269   i::InitializeExternalStartupDataFromFile(snapshot_blob);
6270 }
6271 
GetVersion()6272 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6273 
6274 #ifdef V8_SANDBOX
GetSandboxAddressSpace()6275 VirtualAddressSpace* v8::V8::GetSandboxAddressSpace() {
6276   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6277                   "v8::V8::GetSandboxAddressSpace",
6278                   "The sandbox must be initialized first.");
6279   return i::GetProcessWideSandbox()->address_space();
6280 }
6281 
GetVirtualMemoryCagePageAllocator()6282 PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() {
6283   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6284                   "v8::V8::GetVirtualMemoryCagePageAllocator",
6285                   "The sandbox must be initialized first.");
6286   return i::GetProcessWideSandbox()->page_allocator();
6287 }
6288 
GetSandboxSizeInBytes()6289 size_t v8::V8::GetSandboxSizeInBytes() {
6290   if (!i::GetProcessWideSandbox()->is_initialized()) {
6291     return 0;
6292   } else {
6293     return i::GetProcessWideSandbox()->size();
6294   }
6295 }
6296 
IsSandboxConfiguredSecurely()6297 bool v8::V8::IsSandboxConfiguredSecurely() {
6298   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6299                   "v8::V8::IsSandoxConfiguredSecurely",
6300                   "The sandbox must be initialized first.");
6301   // TODO(saelo) For now, we only treat a partially reserved sandbox as
6302   // insecure. Once we use sandboxed pointers, which assume that the sandbox
6303   // has a fixed size, we'll also treat sandboxes with a smaller size as
6304   // insecure because these pointers can then access memory outside of them.
6305   return !i::GetProcessWideSandbox()->is_partially_reserved();
6306 }
6307 #endif
6308 
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6309 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6310   i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6311 }
6312 
6313 template <typename ObjectType>
6314 struct InvokeBootstrapper;
6315 
6316 template <>
6317 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6318   i::Handle<i::Context> Invoke(
6319       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6320       v8::Local<v8::ObjectTemplate> global_proxy_template,
6321       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6322       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6323       v8::MicrotaskQueue* microtask_queue) {
6324     return isolate->bootstrapper()->CreateEnvironment(
6325         maybe_global_proxy, global_proxy_template, extensions,
6326         context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6327   }
6328 };
6329 
6330 template <>
6331 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6332   i::Handle<i::JSGlobalProxy> Invoke(
6333       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6334       v8::Local<v8::ObjectTemplate> global_proxy_template,
6335       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6336       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6337       v8::MicrotaskQueue* microtask_queue) {
6338     USE(extensions);
6339     USE(context_snapshot_index);
6340     return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6341                                                      global_proxy_template);
6342   }
6343 };
6344 
6345 template <typename ObjectType>
CreateEnvironment(i::Isolate * isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> maybe_global_template,v8::MaybeLocal<Value> maybe_global_proxy,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6346 static i::Handle<ObjectType> CreateEnvironment(
6347     i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6348     v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6349     v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6350     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6351     v8::MicrotaskQueue* microtask_queue) {
6352   i::Handle<ObjectType> result;
6353 
6354   {
6355     ENTER_V8_FOR_NEW_CONTEXT(isolate);
6356     v8::Local<ObjectTemplate> proxy_template;
6357     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6358     i::Handle<i::FunctionTemplateInfo> global_constructor;
6359     i::Handle<i::HeapObject> named_interceptor(
6360         isolate->factory()->undefined_value());
6361     i::Handle<i::HeapObject> indexed_interceptor(
6362         isolate->factory()->undefined_value());
6363 
6364     if (!maybe_global_template.IsEmpty()) {
6365       v8::Local<v8::ObjectTemplate> global_template =
6366           maybe_global_template.ToLocalChecked();
6367       // Make sure that the global_template has a constructor.
6368       global_constructor = EnsureConstructor(isolate, *global_template);
6369 
6370       // Create a fresh template for the global proxy object.
6371       proxy_template =
6372           ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
6373       proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6374 
6375       // Set the global template to be the prototype template of
6376       // global proxy template.
6377       i::FunctionTemplateInfo::SetPrototypeTemplate(
6378           isolate, proxy_constructor, Utils::OpenHandle(*global_template));
6379 
6380       proxy_template->SetInternalFieldCount(
6381           global_template->InternalFieldCount());
6382 
6383       // Migrate security handlers from global_template to
6384       // proxy_template.  Temporarily removing access check
6385       // information from the global template.
6386       if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
6387         i::FunctionTemplateInfo::SetAccessCheckInfo(
6388             isolate, proxy_constructor,
6389             i::handle(global_constructor->GetAccessCheckInfo(), isolate));
6390         proxy_constructor->set_needs_access_check(
6391             global_constructor->needs_access_check());
6392         global_constructor->set_needs_access_check(false);
6393         i::FunctionTemplateInfo::SetAccessCheckInfo(
6394             isolate, global_constructor,
6395             i::ReadOnlyRoots(isolate).undefined_value_handle());
6396       }
6397 
6398       // Same for other interceptors. If the global constructor has
6399       // interceptors, we need to replace them temporarily with noop
6400       // interceptors, so the map is correctly marked as having interceptors,
6401       // but we don't invoke any.
6402       if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
6403         named_interceptor =
6404             handle(global_constructor->GetNamedPropertyHandler(), isolate);
6405         i::FunctionTemplateInfo::SetNamedPropertyHandler(
6406             isolate, global_constructor,
6407             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6408       }
6409       if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
6410               isolate)) {
6411         indexed_interceptor =
6412             handle(global_constructor->GetIndexedPropertyHandler(), isolate);
6413         i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6414             isolate, global_constructor,
6415             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6416       }
6417     }
6418 
6419     i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6420     if (!maybe_global_proxy.IsEmpty()) {
6421       maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6422           Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6423     }
6424     // Create the environment.
6425     InvokeBootstrapper<ObjectType> invoke;
6426     result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6427                            context_snapshot_index, embedder_fields_deserializer,
6428                            microtask_queue);
6429 
6430     // Restore the access check info and interceptors on the global template.
6431     if (!maybe_global_template.IsEmpty()) {
6432       DCHECK(!global_constructor.is_null());
6433       DCHECK(!proxy_constructor.is_null());
6434       i::FunctionTemplateInfo::SetAccessCheckInfo(
6435           isolate, global_constructor,
6436           i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6437       global_constructor->set_needs_access_check(
6438           proxy_constructor->needs_access_check());
6439       i::FunctionTemplateInfo::SetNamedPropertyHandler(
6440           isolate, global_constructor, named_interceptor);
6441       i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6442           isolate, global_constructor, indexed_interceptor);
6443     }
6444   }
6445   // Leave V8.
6446 
6447   return result;
6448 }
6449 
NewContext(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6450 Local<Context> NewContext(
6451     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6452     v8::MaybeLocal<ObjectTemplate> global_template,
6453     v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6454     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6455     v8::MicrotaskQueue* microtask_queue) {
6456   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6457   // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6458   // fail.
6459   // Sanity-check that the isolate is initialized and usable.
6460   CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT());
6461 
6462   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6463   API_RCS_SCOPE(isolate, Context, New);
6464   i::HandleScope scope(isolate);
6465   ExtensionConfiguration no_extensions;
6466   if (extensions == nullptr) extensions = &no_extensions;
6467   i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6468       isolate, extensions, global_template, global_object,
6469       context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6470   if (env.is_null()) {
6471     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6472     return Local<Context>();
6473   }
6474   return Utils::ToLocal(scope.CloseAndEscape(env));
6475 }
6476 
New(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,DeserializeInternalFieldsCallback internal_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6477 Local<Context> v8::Context::New(
6478     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6479     v8::MaybeLocal<ObjectTemplate> global_template,
6480     v8::MaybeLocal<Value> global_object,
6481     DeserializeInternalFieldsCallback internal_fields_deserializer,
6482     v8::MicrotaskQueue* microtask_queue) {
6483   return NewContext(external_isolate, extensions, global_template,
6484                     global_object, 0, internal_fields_deserializer,
6485                     microtask_queue);
6486 }
6487 
FromSnapshot(v8::Isolate * external_isolate,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::ExtensionConfiguration * extensions,MaybeLocal<Value> global_object,v8::MicrotaskQueue * microtask_queue)6488 MaybeLocal<Context> v8::Context::FromSnapshot(
6489     v8::Isolate* external_isolate, size_t context_snapshot_index,
6490     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6491     v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6492     v8::MicrotaskQueue* microtask_queue) {
6493   size_t index_including_default_context = context_snapshot_index + 1;
6494   if (!i::Snapshot::HasContextSnapshot(
6495           reinterpret_cast<i::Isolate*>(external_isolate),
6496           index_including_default_context)) {
6497     return MaybeLocal<Context>();
6498   }
6499   return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6500                     global_object, index_including_default_context,
6501                     embedder_fields_deserializer, microtask_queue);
6502 }
6503 
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6504 MaybeLocal<Object> v8::Context::NewRemoteContext(
6505     v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6506     v8::MaybeLocal<v8::Value> global_object) {
6507   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6508   API_RCS_SCOPE(isolate, Context, NewRemoteContext);
6509   i::HandleScope scope(isolate);
6510   i::Handle<i::FunctionTemplateInfo> global_constructor =
6511       EnsureConstructor(isolate, *global_template);
6512   Utils::ApiCheck(global_constructor->needs_access_check(),
6513                   "v8::Context::NewRemoteContext",
6514                   "Global template needs to have access checks enabled.");
6515   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6516       i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6517       isolate);
6518   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6519                   "v8::Context::NewRemoteContext",
6520                   "Global template needs to have access check handlers.");
6521   i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6522       isolate, nullptr, global_template, global_object, 0,
6523       DeserializeInternalFieldsCallback(), nullptr);
6524   if (global_proxy.is_null()) {
6525     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6526     return MaybeLocal<Object>();
6527   }
6528   return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6529 }
6530 
SetSecurityToken(Local<Value> token)6531 void v8::Context::SetSecurityToken(Local<Value> token) {
6532   i::Handle<i::Context> env = Utils::OpenHandle(this);
6533   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6534   env->set_security_token(*token_handle);
6535 }
6536 
UseDefaultSecurityToken()6537 void v8::Context::UseDefaultSecurityToken() {
6538   i::Handle<i::Context> env = Utils::OpenHandle(this);
6539   env->set_security_token(env->global_object());
6540 }
6541 
GetSecurityToken()6542 Local<Value> v8::Context::GetSecurityToken() {
6543   i::Handle<i::Context> env = Utils::OpenHandle(this);
6544   i::Isolate* isolate = env->GetIsolate();
6545   i::Object security_token = env->security_token();
6546   i::Handle<i::Object> token_handle(security_token, isolate);
6547   return Utils::ToLocal(token_handle);
6548 }
6549 
GetIsolate()6550 v8::Isolate* Context::GetIsolate() {
6551   i::Handle<i::Context> env = Utils::OpenHandle(this);
6552   return reinterpret_cast<Isolate*>(env->GetIsolate());
6553 }
6554 
GetMicrotaskQueue()6555 v8::MicrotaskQueue* Context::GetMicrotaskQueue() {
6556   i::Handle<i::Context> env = Utils::OpenHandle(this);
6557   Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue",
6558                   "Must be calld on a native context");
6559   return i::Handle<i::NativeContext>::cast(env)->microtask_queue();
6560 }
6561 
Global()6562 v8::Local<v8::Object> Context::Global() {
6563   i::Handle<i::Context> context = Utils::OpenHandle(this);
6564   i::Isolate* isolate = context->GetIsolate();
6565   i::Handle<i::Object> global(context->global_proxy(), isolate);
6566   // TODO(chromium:324812): This should always return the global proxy
6567   // but can't presently as calls to GetProtoype will return the wrong result.
6568   if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6569           context->global_object())) {
6570     global = i::Handle<i::Object>(context->global_object(), isolate);
6571   }
6572   return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6573 }
6574 
DetachGlobal()6575 void Context::DetachGlobal() {
6576   i::Handle<i::Context> context = Utils::OpenHandle(this);
6577   i::Isolate* isolate = context->GetIsolate();
6578   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6579   isolate->DetachGlobal(context);
6580 }
6581 
GetExtrasBindingObject()6582 Local<v8::Object> Context::GetExtrasBindingObject() {
6583   i::Handle<i::Context> context = Utils::OpenHandle(this);
6584   i::Isolate* isolate = context->GetIsolate();
6585   i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6586   return Utils::ToLocal(binding);
6587 }
6588 
AllowCodeGenerationFromStrings(bool allow)6589 void Context::AllowCodeGenerationFromStrings(bool allow) {
6590   i::Handle<i::Context> context = Utils::OpenHandle(this);
6591   i::Isolate* isolate = context->GetIsolate();
6592   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6593   context->set_allow_code_gen_from_strings(
6594       allow ? i::ReadOnlyRoots(isolate).true_value()
6595             : i::ReadOnlyRoots(isolate).false_value());
6596 }
6597 
IsCodeGenerationFromStringsAllowed() const6598 bool Context::IsCodeGenerationFromStringsAllowed() const {
6599   i::Context context = *Utils::OpenHandle(this);
6600   return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6601 }
6602 
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6603 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6604   i::Handle<i::Context> context = Utils::OpenHandle(this);
6605   i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6606   context->set_error_message_for_code_gen_from_strings(*error_handle);
6607 }
6608 
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6609 void Context::SetAbortScriptExecution(
6610     Context::AbortScriptExecutionCallback callback) {
6611   i::Handle<i::Context> context = Utils::OpenHandle(this);
6612   i::Isolate* isolate = context->GetIsolate();
6613   if (callback == nullptr) {
6614     context->set_script_execution_callback(
6615         i::ReadOnlyRoots(isolate).undefined_value());
6616   } else {
6617     SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6618                       callback);
6619   }
6620 }
6621 
GetContinuationPreservedEmbedderData() const6622 Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6623   i::Handle<i::Context> context = Utils::OpenHandle(this);
6624   i::Isolate* isolate = context->GetIsolate();
6625   i::Handle<i::Object> data(
6626       context->native_context().continuation_preserved_embedder_data(),
6627       isolate);
6628   return ToApiHandle<Object>(data);
6629 }
6630 
SetContinuationPreservedEmbedderData(Local<Value> data)6631 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6632   i::Handle<i::Context> context = Utils::OpenHandle(this);
6633   i::Isolate* isolate = context->GetIsolate();
6634   if (data.IsEmpty())
6635     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6636   context->native_context().set_continuation_preserved_embedder_data(
6637       *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6638 }
6639 
SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6640 void v8::Context::SetPromiseHooks(Local<Function> init_hook,
6641                                   Local<Function> before_hook,
6642                                   Local<Function> after_hook,
6643                                   Local<Function> resolve_hook) {
6644 #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6645   i::Handle<i::Context> context = Utils::OpenHandle(this);
6646   i::Isolate* isolate = context->GetIsolate();
6647 
6648   i::Handle<i::Object> init = isolate->factory()->undefined_value();
6649   i::Handle<i::Object> before = isolate->factory()->undefined_value();
6650   i::Handle<i::Object> after = isolate->factory()->undefined_value();
6651   i::Handle<i::Object> resolve = isolate->factory()->undefined_value();
6652 
6653   bool has_hook = false;
6654 
6655   if (!init_hook.IsEmpty()) {
6656     init = Utils::OpenHandle(*init_hook);
6657     has_hook = true;
6658   }
6659   if (!before_hook.IsEmpty()) {
6660     before = Utils::OpenHandle(*before_hook);
6661     has_hook = true;
6662   }
6663   if (!after_hook.IsEmpty()) {
6664     after = Utils::OpenHandle(*after_hook);
6665     has_hook = true;
6666   }
6667   if (!resolve_hook.IsEmpty()) {
6668     resolve = Utils::OpenHandle(*resolve_hook);
6669     has_hook = true;
6670   }
6671 
6672   isolate->SetHasContextPromiseHooks(has_hook);
6673 
6674   context->native_context().set_promise_hook_init_function(*init);
6675   context->native_context().set_promise_hook_before_function(*before);
6676   context->native_context().set_promise_hook_after_function(*after);
6677   context->native_context().set_promise_hook_resolve_function(*resolve);
6678 #else   // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6679   Utils::ApiCheck(false, "v8::Context::SetPromiseHook",
6680                   "V8 was compiled without JavaScript Promise hooks");
6681 #endif  // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6682 }
6683 
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6684 MaybeLocal<Context> metrics::Recorder::GetContext(
6685     Isolate* isolate, metrics::Recorder::ContextId id) {
6686   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6687   return i_isolate->GetContextFromRecorderContextId(id);
6688 }
6689 
GetContextId(Local<Context> context)6690 metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6691     Local<Context> context) {
6692   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6693   i::Isolate* isolate = i_context->GetIsolate();
6694   return isolate->GetOrRegisterRecorderContextId(
6695       handle(i_context->native_context(), isolate));
6696 }
6697 
Get(v8::Isolate * isolate)6698 metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6699   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6700   return *i_isolate->GetCurrentLongTaskStats();
6701 }
6702 
6703 namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6704 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6705                                             i::FixedArray list, size_t index) {
6706   if (index < static_cast<size_t>(list.length())) {
6707     int int_index = static_cast<int>(index);
6708     i::Object object = list.get(int_index);
6709     if (!object.IsTheHole(isolate)) {
6710       list.set_the_hole(isolate, int_index);
6711       // Shrink the list so that the last element is not the hole (unless it's
6712       // the first element, because we don't want to end up with a non-canonical
6713       // empty FixedArray).
6714       int last = list.length() - 1;
6715       while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6716       if (last != -1) list.Shrink(isolate, last + 1);
6717       return i::Handle<i::Object>(object, isolate).location();
6718     }
6719   }
6720   return nullptr;
6721 }
6722 }  // anonymous namespace
6723 
GetDataFromSnapshotOnce(size_t index)6724 i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6725   auto context = Utils::OpenHandle(this);
6726   i::Isolate* i_isolate = context->GetIsolate();
6727   i::FixedArray list = context->serialized_objects();
6728   return GetSerializedDataFromFixedArray(i_isolate, list, index);
6729 }
6730 
NewInstance(Local<Context> context)6731 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6732   PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6733   auto self = Utils::OpenHandle(this);
6734   Local<Object> result;
6735   has_pending_exception = !ToLocal<Object>(
6736       i::ApiNatives::InstantiateObject(isolate, self), &result);
6737   RETURN_ON_FAILED_EXECUTION(Object);
6738   RETURN_ESCAPED(result);
6739 }
6740 
CheckCast(Data * that)6741 void v8::ObjectTemplate::CheckCast(Data* that) {
6742   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6743   Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6744                   "Value is not an ObjectTemplate");
6745 }
6746 
CheckCast(Data * that)6747 void v8::FunctionTemplate::CheckCast(Data* that) {
6748   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6749   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6750                   "Value is not a FunctionTemplate");
6751 }
6752 
CheckCast(Data * that)6753 void v8::Signature::CheckCast(Data* that) {
6754   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6755   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6756                   "Value is not a Signature");
6757 }
6758 
CheckCast(Data * that)6759 void v8::AccessorSignature::CheckCast(Data* that) {
6760   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6761   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6762                   "Value is not an AccessorSignature");
6763 }
6764 
GetFunction(Local<Context> context)6765 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6766   PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6767   auto self = Utils::OpenHandle(this);
6768   Local<Function> result;
6769   has_pending_exception =
6770       !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6771   RETURN_ON_FAILED_EXECUTION(Function);
6772   RETURN_ESCAPED(result);
6773 }
6774 
NewRemoteInstance()6775 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6776   auto self = Utils::OpenHandle(this);
6777   i::Isolate* isolate = self->GetIsolate();
6778   API_RCS_SCOPE(isolate, FunctionTemplate, NewRemoteInstance);
6779   i::HandleScope scope(isolate);
6780   i::Handle<i::FunctionTemplateInfo> constructor =
6781       EnsureConstructor(isolate, *InstanceTemplate());
6782   Utils::ApiCheck(constructor->needs_access_check(),
6783                   "v8::FunctionTemplate::NewRemoteInstance",
6784                   "InstanceTemplate needs to have access checks enabled.");
6785   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6786       i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6787   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6788                   "v8::FunctionTemplate::NewRemoteInstance",
6789                   "InstanceTemplate needs to have access check handlers.");
6790   i::Handle<i::JSObject> object;
6791   if (!i::ApiNatives::InstantiateRemoteObject(
6792            Utils::OpenHandle(*InstanceTemplate()))
6793            .ToHandle(&object)) {
6794     if (isolate->has_pending_exception()) {
6795       isolate->OptionalRescheduleException(true);
6796     }
6797     return MaybeLocal<Object>();
6798   }
6799   return Utils::ToLocal(scope.CloseAndEscape(object));
6800 }
6801 
HasInstance(v8::Local<v8::Value> value)6802 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6803   auto self = Utils::OpenHandle(this);
6804   auto obj = Utils::OpenHandle(*value);
6805   if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6806     return true;
6807   }
6808   if (obj->IsJSGlobalProxy()) {
6809     // If it's a global proxy, then test with the global object. Note that the
6810     // inner global object may not necessarily be a JSGlobalObject.
6811     i::PrototypeIterator iter(self->GetIsolate(),
6812                               i::JSObject::cast(*obj).map());
6813     // The global proxy should always have a prototype, as it is a bug to call
6814     // this on a detached JSGlobalProxy.
6815     DCHECK(!iter.IsAtEnd());
6816     return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6817   }
6818   return false;
6819 }
6820 
IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6821 bool FunctionTemplate::IsLeafTemplateForApiObject(
6822     v8::Local<v8::Value> value) const {
6823   i::DisallowGarbageCollection no_gc;
6824 
6825   i::Object object = *Utils::OpenHandle(*value);
6826 
6827   auto self = Utils::OpenHandle(this);
6828   return self->IsLeafTemplateForApiObject(object);
6829 }
6830 
New(Isolate * isolate,void * value)6831 Local<External> v8::External::New(Isolate* isolate, void* value) {
6832   STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6833   // Nullptr is not allowed here because serialization/deserialization of
6834   // nullptr external api references is not possible as nullptr is used as an
6835   // external_references table terminator, see v8::SnapshotCreator()
6836   // constructors.
6837   DCHECK_NOT_NULL(value);
6838   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6839   API_RCS_SCOPE(i_isolate, External, New);
6840   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6841   i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6842   return Utils::ExternalToLocal(external);
6843 }
6844 
Value() const6845 void* External::Value() const {
6846   auto self = Utils::OpenHandle(this);
6847   return i::JSExternalObject::cast(*self).value();
6848 }
6849 
6850 // anonymous namespace for string creation helper functions
6851 namespace {
6852 
StringLength(const char * string)6853 inline int StringLength(const char* string) {
6854   size_t len = strlen(string);
6855   CHECK_GE(i::kMaxInt, len);
6856   return static_cast<int>(len);
6857 }
6858 
StringLength(const uint8_t * string)6859 inline int StringLength(const uint8_t* string) {
6860   return StringLength(reinterpret_cast<const char*>(string));
6861 }
6862 
StringLength(const uint16_t * string)6863 inline int StringLength(const uint16_t* string) {
6864   size_t length = 0;
6865   while (string[length] != '\0') length++;
6866   CHECK_GE(i::kMaxInt, length);
6867   return static_cast<int>(length);
6868 }
6869 
6870 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6871 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6872                                            NewStringType type,
6873                                            base::Vector<const char> string) {
6874   if (type == NewStringType::kInternalized) {
6875     return factory->InternalizeUtf8String(string);
6876   }
6877   return factory->NewStringFromUtf8(string);
6878 }
6879 
6880 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6881 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6882                                            NewStringType type,
6883                                            base::Vector<const uint8_t> string) {
6884   if (type == NewStringType::kInternalized) {
6885     return factory->InternalizeString(string);
6886   }
6887   return factory->NewStringFromOneByte(string);
6888 }
6889 
6890 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6891 inline i::MaybeHandle<i::String> NewString(
6892     i::Factory* factory, NewStringType type,
6893     base::Vector<const uint16_t> string) {
6894   if (type == NewStringType::kInternalized) {
6895     return factory->InternalizeString(string);
6896   }
6897   return factory->NewStringFromTwoByte(string);
6898 }
6899 
6900 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6901 
6902 }  // anonymous namespace
6903 
6904 // TODO(dcarney): throw a context free exception.
6905 #define NEW_STRING(isolate, class_name, function_name, Char, data, type,   \
6906                    length)                                                 \
6907   MaybeLocal<String> result;                                               \
6908   if (length == 0) {                                                       \
6909     result = String::Empty(isolate);                                       \
6910   } else if (length > i::String::kMaxLength) {                             \
6911     result = MaybeLocal<String>();                                         \
6912   } else {                                                                 \
6913     i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6914     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);                            \
6915     API_RCS_SCOPE(i_isolate, class_name, function_name);                   \
6916     if (length < 0) length = StringLength(data);                           \
6917     i::Handle<i::String> handle_result =                                   \
6918         NewString(i_isolate->factory(), type,                              \
6919                   base::Vector<const Char>(data, length))                  \
6920             .ToHandleChecked();                                            \
6921     result = Utils::ToLocal(handle_result);                                \
6922   }
6923 
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6924 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6925                                          NewStringType type, int length) {
6926   DCHECK_LE(length, i::String::kMaxLength);
6927   i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6928   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6929   API_RCS_SCOPE(i_isolate, String, NewFromUtf8Literal);
6930   i::Handle<i::String> handle_result =
6931       NewString(i_isolate->factory(), type,
6932                 base::Vector<const char>(literal, length))
6933           .ToHandleChecked();
6934   return Utils::ToLocal(handle_result);
6935 }
6936 
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6937 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6938                                        NewStringType type, int length) {
6939   NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6940   return result;
6941 }
6942 
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6943 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6944                                           NewStringType type, int length) {
6945   NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6946   return result;
6947 }
6948 
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6949 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6950                                           const uint16_t* data,
6951                                           NewStringType type, int length) {
6952   NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6953   return result;
6954 }
6955 
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6956 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6957                                  Local<String> right) {
6958   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6959   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6960   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6961   API_RCS_SCOPE(isolate, String, Concat);
6962   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6963   // If we are steering towards a range error, do not wait for the error to be
6964   // thrown, and return the null handle instead.
6965   if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6966     return Local<String>();
6967   }
6968   i::Handle<i::String> result = isolate->factory()
6969                                     ->NewConsString(left_string, right_string)
6970                                     .ToHandleChecked();
6971   return Utils::ToLocal(result);
6972 }
6973 
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6974 MaybeLocal<String> v8::String::NewExternalTwoByte(
6975     Isolate* isolate, v8::String::ExternalStringResource* resource) {
6976   CHECK(resource && resource->data());
6977   // TODO(dcarney): throw a context free exception.
6978   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6979     return MaybeLocal<String>();
6980   }
6981   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6982   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6983   API_RCS_SCOPE(i_isolate, String, NewExternalTwoByte);
6984   if (resource->length() > 0) {
6985     i::Handle<i::String> string = i_isolate->factory()
6986                                       ->NewExternalStringFromTwoByte(resource)
6987                                       .ToHandleChecked();
6988     return Utils::ToLocal(string);
6989   } else {
6990     // The resource isn't going to be used, free it immediately.
6991     resource->Dispose();
6992     return Utils::ToLocal(i_isolate->factory()->empty_string());
6993   }
6994 }
6995 
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6996 MaybeLocal<String> v8::String::NewExternalOneByte(
6997     Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6998   CHECK_NOT_NULL(resource);
6999   // TODO(dcarney): throw a context free exception.
7000   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
7001     return MaybeLocal<String>();
7002   }
7003   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7004   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7005   API_RCS_SCOPE(i_isolate, String, NewExternalOneByte);
7006   if (resource->length() == 0) {
7007     // The resource isn't going to be used, free it immediately.
7008     resource->Dispose();
7009     return Utils::ToLocal(i_isolate->factory()->empty_string());
7010   }
7011   CHECK_NOT_NULL(resource->data());
7012   i::Handle<i::String> string = i_isolate->factory()
7013                                     ->NewExternalStringFromOneByte(resource)
7014                                     .ToHandleChecked();
7015   return Utils::ToLocal(string);
7016 }
7017 
MakeExternal(v8::String::ExternalStringResource * resource)7018 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
7019   i::DisallowGarbageCollection no_gc;
7020 
7021   i::String obj = *Utils::OpenHandle(this);
7022 
7023   if (obj.IsThinString()) {
7024     obj = i::ThinString::cast(obj).actual();
7025   }
7026 
7027   if (!obj.SupportsExternalization()) {
7028     return false;
7029   }
7030 
7031   // It is safe to call GetIsolateFromWritableHeapObject because
7032   // SupportsExternalization already checked that the object is writable.
7033   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
7034   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7035 
7036   CHECK(resource && resource->data());
7037 
7038   bool result = obj.MakeExternal(resource);
7039   DCHECK(result);
7040   DCHECK(obj.IsExternalString());
7041   return result;
7042 }
7043 
MakeExternal(v8::String::ExternalOneByteStringResource * resource)7044 bool v8::String::MakeExternal(
7045     v8::String::ExternalOneByteStringResource* resource) {
7046   i::DisallowGarbageCollection no_gc;
7047 
7048   i::String obj = *Utils::OpenHandle(this);
7049 
7050   if (obj.IsThinString()) {
7051     obj = i::ThinString::cast(obj).actual();
7052   }
7053 
7054   if (!obj.SupportsExternalization()) {
7055     return false;
7056   }
7057 
7058   // It is safe to call GetIsolateFromWritableHeapObject because
7059   // SupportsExternalization already checked that the object is writable.
7060   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
7061   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7062 
7063   CHECK(resource && resource->data());
7064 
7065   bool result = obj.MakeExternal(resource);
7066   DCHECK_IMPLIES(result, obj.IsExternalString());
7067   return result;
7068 }
7069 
CanMakeExternal() const7070 bool v8::String::CanMakeExternal() const {
7071   i::String obj = *Utils::OpenHandle(this);
7072 
7073   if (obj.IsThinString()) {
7074     obj = i::ThinString::cast(obj).actual();
7075   }
7076 
7077   if (!obj.SupportsExternalization()) {
7078     return false;
7079   }
7080 
7081   // Only old space strings should be externalized.
7082   return !i::Heap::InYoungGeneration(obj);
7083 }
7084 
StringEquals(Local<String> that) const7085 bool v8::String::StringEquals(Local<String> that) const {
7086   auto self = Utils::OpenHandle(this);
7087   auto other = Utils::OpenHandle(*that);
7088   return self->Equals(*other);
7089 }
7090 
GetIsolate()7091 Isolate* v8::Object::GetIsolate() {
7092   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7093   return reinterpret_cast<Isolate*>(i_isolate);
7094 }
7095 
New(Isolate * isolate)7096 Local<v8::Object> v8::Object::New(Isolate* isolate) {
7097   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7098   API_RCS_SCOPE(i_isolate, Object, New);
7099   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7100   i::Handle<i::JSObject> obj =
7101       i_isolate->factory()->NewJSObject(i_isolate->object_function());
7102   return Utils::ToLocal(obj);
7103 }
7104 
7105 namespace {
7106 
7107 // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference
7108 // in the return types of the different Add functions:
7109 // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns
7110 // Handle.
7111 template <typename T>
ToHandle(i::Handle<T> h)7112 i::Handle<T> ToHandle(i::Handle<T> h) {
7113   return h;
7114 }
7115 template <typename T>
ToHandle(i::MaybeHandle<T> h)7116 i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
7117   return h.ToHandleChecked();
7118 }
7119 
7120 template <typename Dictionary>
AddPropertiesAndElementsToObject(i::Isolate * i_isolate,i::Handle<Dictionary> & properties,i::Handle<i::FixedArrayBase> & elements,Local<Name> * names,Local<Value> * values,size_t length)7121 void AddPropertiesAndElementsToObject(i::Isolate* i_isolate,
7122                                       i::Handle<Dictionary>& properties,
7123                                       i::Handle<i::FixedArrayBase>& elements,
7124                                       Local<Name>* names, Local<Value>* values,
7125                                       size_t length) {
7126   for (size_t i = 0; i < length; ++i) {
7127     i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
7128     i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
7129 
7130     // See if the {name} is a valid array index, in which case we need to
7131     // add the {name}/{value} pair to the {elements}, otherwise they end
7132     // up in the {properties} backing store.
7133     uint32_t index;
7134     if (name->AsArrayIndex(&index)) {
7135       // If this is the first element, allocate a proper
7136       // dictionary elements backing store for {elements}.
7137       if (!elements->IsNumberDictionary()) {
7138         elements =
7139             i::NumberDictionary::New(i_isolate, static_cast<int>(length));
7140       }
7141       elements = i::NumberDictionary::Set(
7142           i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
7143           value);
7144     } else {
7145       // Internalize the {name} first.
7146       name = i_isolate->factory()->InternalizeName(name);
7147       i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
7148       if (entry.is_not_found()) {
7149         // Add the {name}/{value} pair as a new entry.
7150         properties = ToHandle(Dictionary::Add(
7151             i_isolate, properties, name, value, i::PropertyDetails::Empty()));
7152       } else {
7153         // Overwrite the {entry} with the {value}.
7154         properties->ValueAtPut(entry, *value);
7155       }
7156     }
7157   }
7158 }
7159 
7160 }  // namespace
7161 
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)7162 Local<v8::Object> v8::Object::New(Isolate* isolate,
7163                                   Local<Value> prototype_or_null,
7164                                   Local<Name>* names, Local<Value>* values,
7165                                   size_t length) {
7166   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7167   i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
7168   if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
7169                        "v8::Object::New", "prototype must be null or object")) {
7170     return Local<v8::Object>();
7171   }
7172   API_RCS_SCOPE(i_isolate, Object, New);
7173   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7174 
7175   i::Handle<i::FixedArrayBase> elements =
7176       i_isolate->factory()->empty_fixed_array();
7177 
7178   // We assume that this API is mostly used to create objects with named
7179   // properties, and so we default to creating a properties backing store
7180   // large enough to hold all of them, while we start with no elements
7181   // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
7182   if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
7183     i::Handle<i::SwissNameDictionary> properties =
7184         i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length));
7185     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7186                                      values, length);
7187     i::Handle<i::JSObject> obj =
7188         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7189             i::Handle<i::HeapObject>::cast(proto), properties, elements);
7190     return Utils::ToLocal(obj);
7191   } else {
7192     i::Handle<i::NameDictionary> properties =
7193         i::NameDictionary::New(i_isolate, static_cast<int>(length));
7194     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7195                                      values, length);
7196     i::Handle<i::JSObject> obj =
7197         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7198             i::Handle<i::HeapObject>::cast(proto), properties, elements);
7199     return Utils::ToLocal(obj);
7200   }
7201 }
7202 
New(Isolate * isolate,double value)7203 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
7204   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7205   API_RCS_SCOPE(i_isolate, NumberObject, New);
7206   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7207   i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
7208   i::Handle<i::Object> obj =
7209       i::Object::ToObject(i_isolate, number).ToHandleChecked();
7210   return Utils::ToLocal(obj);
7211 }
7212 
ValueOf() const7213 double v8::NumberObject::ValueOf() const {
7214   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7215   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7216       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7217   API_RCS_SCOPE(js_primitive_wrapper->GetIsolate(), NumberObject, NumberValue);
7218   return js_primitive_wrapper->value().Number();
7219 }
7220 
New(Isolate * isolate,int64_t value)7221 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
7222   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7223   API_RCS_SCOPE(i_isolate, BigIntObject, New);
7224   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7225   i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
7226   i::Handle<i::Object> obj =
7227       i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
7228   return Utils::ToLocal(obj);
7229 }
7230 
ValueOf() const7231 Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
7232   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7233   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7234       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7235   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7236   API_RCS_SCOPE(isolate, BigIntObject, BigIntValue);
7237   return Utils::ToLocal(i::Handle<i::BigInt>(
7238       i::BigInt::cast(js_primitive_wrapper->value()), isolate));
7239 }
7240 
New(Isolate * isolate,bool value)7241 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7242   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7243   API_RCS_SCOPE(i_isolate, BooleanObject, New);
7244   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7245   i::Handle<i::Object> boolean(value
7246                                    ? i::ReadOnlyRoots(i_isolate).true_value()
7247                                    : i::ReadOnlyRoots(i_isolate).false_value(),
7248                                i_isolate);
7249   i::Handle<i::Object> obj =
7250       i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7251   return Utils::ToLocal(obj);
7252 }
7253 
ValueOf() const7254 bool v8::BooleanObject::ValueOf() const {
7255   i::Object obj = *Utils::OpenHandle(this);
7256   i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
7257   i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
7258   API_RCS_SCOPE(isolate, BooleanObject, BooleanValue);
7259   return js_primitive_wrapper.value().IsTrue(isolate);
7260 }
7261 
New(Isolate * v8_isolate,Local<String> value)7262 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
7263                                        Local<String> value) {
7264   i::Handle<i::String> string = Utils::OpenHandle(*value);
7265   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7266   API_RCS_SCOPE(isolate, StringObject, New);
7267   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7268   i::Handle<i::Object> obj =
7269       i::Object::ToObject(isolate, string).ToHandleChecked();
7270   return Utils::ToLocal(obj);
7271 }
7272 
ValueOf() const7273 Local<v8::String> v8::StringObject::ValueOf() const {
7274   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7275   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7276       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7277   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7278   API_RCS_SCOPE(isolate, StringObject, StringValue);
7279   return Utils::ToLocal(i::Handle<i::String>(
7280       i::String::cast(js_primitive_wrapper->value()), isolate));
7281 }
7282 
New(Isolate * isolate,Local<Symbol> value)7283 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7284   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7285   API_RCS_SCOPE(i_isolate, SymbolObject, New);
7286   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7287   i::Handle<i::Object> obj =
7288       i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
7289           .ToHandleChecked();
7290   return Utils::ToLocal(obj);
7291 }
7292 
ValueOf() const7293 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7294   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7295   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7296       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7297   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7298   API_RCS_SCOPE(isolate, SymbolObject, SymbolValue);
7299   return Utils::ToLocal(i::Handle<i::Symbol>(
7300       i::Symbol::cast(js_primitive_wrapper->value()), isolate));
7301 }
7302 
New(Local<Context> context,double time)7303 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7304   if (std::isnan(time)) {
7305     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7306     time = std::numeric_limits<double>::quiet_NaN();
7307   }
7308   PREPARE_FOR_EXECUTION(context, Date, New, Value);
7309   Local<Value> result;
7310   has_pending_exception = !ToLocal<Value>(
7311       i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7312       &result);
7313   RETURN_ON_FAILED_EXECUTION(Value);
7314   RETURN_ESCAPED(result);
7315 }
7316 
ValueOf() const7317 double v8::Date::ValueOf() const {
7318   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7319   i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7320   API_RCS_SCOPE(jsdate->GetIsolate(), Date, NumberValue);
7321   return jsdate->value().Number();
7322 }
7323 
7324 // Assert that the static TimeZoneDetection cast in
7325 // DateTimeConfigurationChangeNotification is valid.
7326 #define TIME_ZONE_DETECTION_ASSERT_EQ(value)                     \
7327   STATIC_ASSERT(                                                 \
7328       static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
7329       static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
7330 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7331 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7332 #undef TIME_ZONE_DETECTION_ASSERT_EQ
7333 
7334 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7335                                        Local<String> pattern, Flags flags) {
7336   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7337   Local<v8::RegExp> result;
7338   has_pending_exception =
7339       !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7340                                         static_cast<i::JSRegExp::Flags>(flags)),
7341                        &result);
7342   RETURN_ON_FAILED_EXECUTION(RegExp);
7343   RETURN_ESCAPED(result);
7344 }
7345 
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7346 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
7347     Local<Context> context, Local<String> pattern, Flags flags,
7348     uint32_t backtrack_limit) {
7349   Utils::ApiCheck(i::Smi::IsValid(backtrack_limit),
7350                   "v8::RegExp::NewWithBacktrackLimit",
7351                   "backtrack_limit is too large or too small.");
7352   Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit,
7353                   "v8::RegExp::NewWithBacktrackLimit",
7354                   "Must set backtrack_limit");
7355   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7356   Local<v8::RegExp> result;
7357   has_pending_exception = !ToLocal<RegExp>(
7358       i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7359                        static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
7360       &result);
7361   RETURN_ON_FAILED_EXECUTION(RegExp);
7362   RETURN_ESCAPED(result);
7363 }
7364 
GetSource() const7365 Local<v8::String> v8::RegExp::GetSource() const {
7366   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7367   return Utils::ToLocal(
7368       i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate()));
7369 }
7370 
7371 // Assert that the static flags cast in GetFlags is valid.
7372 #define REGEXP_FLAG_ASSERT_EQ(flag)                   \
7373   STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7374                 static_cast<int>(i::JSRegExp::flag))
7375 REGEXP_FLAG_ASSERT_EQ(kNone);
7376 REGEXP_FLAG_ASSERT_EQ(kGlobal);
7377 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7378 REGEXP_FLAG_ASSERT_EQ(kMultiline);
7379 REGEXP_FLAG_ASSERT_EQ(kSticky);
7380 REGEXP_FLAG_ASSERT_EQ(kUnicode);
7381 REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7382 REGEXP_FLAG_ASSERT_EQ(kLinear);
7383 #undef REGEXP_FLAG_ASSERT_EQ
7384 
GetFlags() const7385 v8::RegExp::Flags v8::RegExp::GetFlags() const {
7386   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7387   return RegExp::Flags(static_cast<int>(obj->flags()));
7388 }
7389 
Exec(Local<Context> context,Local<v8::String> subject)7390 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
7391                                         Local<v8::String> subject) {
7392   PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
7393 
7394   i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
7395   i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
7396 
7397   // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
7398   // mind. It fetches the 'exec' property and then calls it through JSEntry.
7399   // Unfortunately, this is currently the only full implementation of
7400   // RegExp.prototype.exec available in C++.
7401   Local<v8::Object> result;
7402   has_pending_exception = !ToLocal<Object>(
7403       i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
7404                                  isolate->factory()->undefined_value()),
7405       &result);
7406 
7407   RETURN_ON_FAILED_EXECUTION(Object);
7408   RETURN_ESCAPED(result);
7409 }
7410 
New(Isolate * isolate,int length)7411 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7412   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7413   API_RCS_SCOPE(i_isolate, Array, New);
7414   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7415   int real_length = length > 0 ? length : 0;
7416   i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7417   i::Handle<i::Object> length_obj =
7418       i_isolate->factory()->NewNumberFromInt(real_length);
7419   obj->set_length(*length_obj);
7420   return Utils::ToLocal(obj);
7421 }
7422 
New(Isolate * isolate,Local<Value> * elements,size_t length)7423 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
7424                                 size_t length) {
7425   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7426   i::Factory* factory = i_isolate->factory();
7427   API_RCS_SCOPE(i_isolate, Array, New);
7428   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7429   int len = static_cast<int>(length);
7430 
7431   i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
7432   for (int i = 0; i < len; i++) {
7433     i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
7434     result->set(i, *element);
7435   }
7436 
7437   return Utils::ToLocal(
7438       factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
7439 }
7440 
Length() const7441 uint32_t v8::Array::Length() const {
7442   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7443   i::Object length = obj->length();
7444   if (length.IsSmi()) {
7445     return i::Smi::ToInt(length);
7446   } else {
7447     return static_cast<uint32_t>(length.Number());
7448   }
7449 }
7450 
New(Isolate * isolate)7451 Local<v8::Map> v8::Map::New(Isolate* isolate) {
7452   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7453   API_RCS_SCOPE(i_isolate, Map, New);
7454   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7455   i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7456   return Utils::ToLocal(obj);
7457 }
7458 
Size() const7459 size_t v8::Map::Size() const {
7460   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7461   return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7462 }
7463 
Clear()7464 void Map::Clear() {
7465   auto self = Utils::OpenHandle(this);
7466   i::Isolate* isolate = self->GetIsolate();
7467   API_RCS_SCOPE(isolate, Map, Clear);
7468   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7469   i::JSMap::Clear(isolate, self);
7470 }
7471 
Get(Local<Context> context,Local<Value> key)7472 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7473   PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7474   auto self = Utils::OpenHandle(this);
7475   Local<Value> result;
7476   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7477   has_pending_exception =
7478       !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
7479                                                 self, arraysize(argv), argv),
7480                       &result);
7481   RETURN_ON_FAILED_EXECUTION(Value);
7482   RETURN_ESCAPED(result);
7483 }
7484 
Set(Local<Context> context,Local<Value> key,Local<Value> value)7485 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7486                          Local<Value> value) {
7487   PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7488   auto self = Utils::OpenHandle(this);
7489   i::Handle<i::Object> result;
7490   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7491                                  Utils::OpenHandle(*value)};
7492   has_pending_exception =
7493       !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
7494                                  arraysize(argv), argv)
7495            .ToHandle(&result);
7496   RETURN_ON_FAILED_EXECUTION(Map);
7497   RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7498 }
7499 
Has(Local<Context> context,Local<Value> key)7500 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7501   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7502   ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7503   auto self = Utils::OpenHandle(this);
7504   i::Handle<i::Object> result;
7505   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7506   has_pending_exception =
7507       !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
7508                                  arraysize(argv), argv)
7509            .ToHandle(&result);
7510   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7511   return Just(result->IsTrue(isolate));
7512 }
7513 
Delete(Local<Context> context,Local<Value> key)7514 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7515   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7516   ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7517   auto self = Utils::OpenHandle(this);
7518   i::Handle<i::Object> result;
7519   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7520   has_pending_exception =
7521       !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
7522                                  arraysize(argv), argv)
7523            .ToHandle(&result);
7524   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7525   return Just(result->IsTrue(isolate));
7526 }
7527 
7528 namespace {
7529 
7530 enum class MapAsArrayKind {
7531   kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7532   kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7533   kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7534 };
7535 
7536 enum class SetAsArrayKind {
7537   kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7538   kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7539 };
7540 
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7541 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7542                                  int offset, MapAsArrayKind kind) {
7543   i::Factory* factory = isolate->factory();
7544   i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7545                                      isolate);
7546   const bool collect_keys =
7547       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7548   const bool collect_values =
7549       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7550   int capacity = table->UsedCapacity();
7551   int max_length =
7552       (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7553   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7554   int result_index = 0;
7555   {
7556     i::DisallowGarbageCollection no_gc;
7557     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7558     for (int i = offset; i < capacity; ++i) {
7559       i::InternalIndex entry(i);
7560       i::Object key = table->KeyAt(entry);
7561       if (key == the_hole) continue;
7562       if (collect_keys) result->set(result_index++, key);
7563       if (collect_values) result->set(result_index++, table->ValueAt(entry));
7564     }
7565   }
7566   DCHECK_GE(max_length, result_index);
7567   if (result_index == 0) return factory->NewJSArray(0);
7568   result->Shrink(isolate, result_index);
7569   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7570                                          result_index);
7571 }
7572 
7573 }  // namespace
7574 
AsArray() const7575 Local<Array> Map::AsArray() const {
7576   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7577   i::Isolate* isolate = obj->GetIsolate();
7578   API_RCS_SCOPE(isolate, Map, AsArray);
7579   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7580   return Utils::ToLocal(
7581       MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7582 }
7583 
New(Isolate * isolate)7584 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7585   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7586   API_RCS_SCOPE(i_isolate, Set, New);
7587   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7588   i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7589   return Utils::ToLocal(obj);
7590 }
7591 
Size() const7592 size_t v8::Set::Size() const {
7593   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7594   return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7595 }
7596 
Clear()7597 void Set::Clear() {
7598   auto self = Utils::OpenHandle(this);
7599   i::Isolate* isolate = self->GetIsolate();
7600   API_RCS_SCOPE(isolate, Set, Clear);
7601   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7602   i::JSSet::Clear(isolate, self);
7603 }
7604 
Add(Local<Context> context,Local<Value> key)7605 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7606   PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7607   auto self = Utils::OpenHandle(this);
7608   i::Handle<i::Object> result;
7609   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7610   has_pending_exception =
7611       !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7612                                  arraysize(argv), argv)
7613            .ToHandle(&result);
7614   RETURN_ON_FAILED_EXECUTION(Set);
7615   RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7616 }
7617 
Has(Local<Context> context,Local<Value> key)7618 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7619   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7620   ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7621   auto self = Utils::OpenHandle(this);
7622   i::Handle<i::Object> result;
7623   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7624   has_pending_exception =
7625       !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7626                                  arraysize(argv), argv)
7627            .ToHandle(&result);
7628   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7629   return Just(result->IsTrue(isolate));
7630 }
7631 
Delete(Local<Context> context,Local<Value> key)7632 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7633   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7634   ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7635   auto self = Utils::OpenHandle(this);
7636   i::Handle<i::Object> result;
7637   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7638   has_pending_exception =
7639       !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7640                                  arraysize(argv), argv)
7641            .ToHandle(&result);
7642   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7643   return Just(result->IsTrue(isolate));
7644 }
7645 
7646 namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7647 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7648                                  int offset, SetAsArrayKind kind) {
7649   i::Factory* factory = isolate->factory();
7650   i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7651                                      isolate);
7652   // Elements skipped by |offset| may already be deleted.
7653   int capacity = table->UsedCapacity();
7654   const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7655   int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7656   if (max_length == 0) return factory->NewJSArray(0);
7657   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7658   int result_index = 0;
7659   {
7660     i::DisallowGarbageCollection no_gc;
7661     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7662     for (int i = offset; i < capacity; ++i) {
7663       i::InternalIndex entry(i);
7664       i::Object key = table->KeyAt(entry);
7665       if (key == the_hole) continue;
7666       result->set(result_index++, key);
7667       if (collect_key_values) result->set(result_index++, key);
7668     }
7669   }
7670   DCHECK_GE(max_length, result_index);
7671   if (result_index == 0) return factory->NewJSArray(0);
7672   result->Shrink(isolate, result_index);
7673   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7674                                          result_index);
7675 }
7676 }  // namespace
7677 
AsArray() const7678 Local<Array> Set::AsArray() const {
7679   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7680   i::Isolate* isolate = obj->GetIsolate();
7681   API_RCS_SCOPE(isolate, Set, AsArray);
7682   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7683   return Utils::ToLocal(
7684       SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7685 }
7686 
New(Local<Context> context)7687 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7688   PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7689   Local<Promise::Resolver> result;
7690   has_pending_exception =
7691       !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7692   RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7693   RETURN_ESCAPED(result);
7694 }
7695 
GetPromise()7696 Local<Promise> Promise::Resolver::GetPromise() {
7697   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7698   return Local<Promise>::Cast(Utils::ToLocal(promise));
7699 }
7700 
Resolve(Local<Context> context,Local<Value> value)7701 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7702                                        Local<Value> value) {
7703   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7704   ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7705            i::HandleScope);
7706   auto self = Utils::OpenHandle(this);
7707   auto promise = i::Handle<i::JSPromise>::cast(self);
7708 
7709   if (promise->status() != Promise::kPending) {
7710     return Just(true);
7711   }
7712 
7713   has_pending_exception =
7714       i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7715   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7716   return Just(true);
7717 }
7718 
Reject(Local<Context> context,Local<Value> value)7719 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7720                                       Local<Value> value) {
7721   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7722   ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7723            i::HandleScope);
7724   auto self = Utils::OpenHandle(this);
7725   auto promise = i::Handle<i::JSPromise>::cast(self);
7726 
7727   if (promise->status() != Promise::kPending) {
7728     return Just(true);
7729   }
7730 
7731   has_pending_exception =
7732       i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7733   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7734   return Just(true);
7735 }
7736 
Catch(Local<Context> context,Local<Function> handler)7737 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7738                                    Local<Function> handler) {
7739   PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7740   auto self = Utils::OpenHandle(this);
7741   i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(),
7742                                  Utils::OpenHandle(*handler)};
7743   i::Handle<i::Object> result;
7744   // Do not call the built-in Promise.prototype.catch!
7745   // v8::Promise should not call out to a monkeypatched Promise.prototype.then
7746   // as the implementation of Promise.prototype.catch does.
7747   has_pending_exception =
7748       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7749                                  arraysize(argv), argv)
7750            .ToHandle(&result);
7751   RETURN_ON_FAILED_EXECUTION(Promise);
7752   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7753 }
7754 
Then(Local<Context> context,Local<Function> handler)7755 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7756                                   Local<Function> handler) {
7757   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7758   auto self = Utils::OpenHandle(this);
7759   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7760   i::Handle<i::Object> result;
7761   has_pending_exception =
7762       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7763                                  arraysize(argv), argv)
7764            .ToHandle(&result);
7765   RETURN_ON_FAILED_EXECUTION(Promise);
7766   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7767 }
7768 
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7769 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7770                                   Local<Function> on_fulfilled,
7771                                   Local<Function> on_rejected) {
7772   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7773   auto self = Utils::OpenHandle(this);
7774   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7775                                  Utils::OpenHandle(*on_rejected)};
7776   i::Handle<i::Object> result;
7777   has_pending_exception =
7778       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7779                                  arraysize(argv), argv)
7780            .ToHandle(&result);
7781   RETURN_ON_FAILED_EXECUTION(Promise);
7782   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7783 }
7784 
HasHandler() const7785 bool Promise::HasHandler() const {
7786   i::JSReceiver promise = *Utils::OpenHandle(this);
7787   i::Isolate* isolate = promise.GetIsolate();
7788   API_RCS_SCOPE(isolate, Promise, HasRejectHandler);
7789   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7790   if (!promise.IsJSPromise()) return false;
7791   return i::JSPromise::cast(promise).has_handler();
7792 }
7793 
Result()7794 Local<Value> Promise::Result() {
7795   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7796   i::Isolate* isolate = promise->GetIsolate();
7797   API_RCS_SCOPE(isolate, Promise, Result);
7798   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7799   Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7800                   "Promise is still pending");
7801   i::Handle<i::Object> result(js_promise->result(), isolate);
7802   return Utils::ToLocal(result);
7803 }
7804 
State()7805 Promise::PromiseState Promise::State() {
7806   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7807   API_RCS_SCOPE(promise->GetIsolate(), Promise, Status);
7808   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7809   return static_cast<PromiseState>(js_promise->status());
7810 }
7811 
MarkAsHandled()7812 void Promise::MarkAsHandled() {
7813   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7814   js_promise->set_has_handler(true);
7815 }
7816 
MarkAsSilent()7817 void Promise::MarkAsSilent() {
7818   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7819   js_promise->set_is_silent(true);
7820 }
7821 
GetTarget()7822 Local<Value> Proxy::GetTarget() {
7823   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7824   i::Handle<i::Object> target(self->target(), self->GetIsolate());
7825   return Utils::ToLocal(target);
7826 }
7827 
GetHandler()7828 Local<Value> Proxy::GetHandler() {
7829   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7830   i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7831   return Utils::ToLocal(handler);
7832 }
7833 
IsRevoked() const7834 bool Proxy::IsRevoked() const {
7835   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7836   return self->IsRevoked();
7837 }
7838 
Revoke()7839 void Proxy::Revoke() {
7840   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7841   i::JSProxy::Revoke(self);
7842 }
7843 
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7844 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7845                              Local<Object> local_handler) {
7846   PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7847   i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7848   i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7849   Local<Proxy> result;
7850   has_pending_exception =
7851       !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7852   RETURN_ON_FAILED_EXECUTION(Proxy);
7853   RETURN_ESCAPED(result);
7854 }
7855 
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7856 CompiledWasmModule::CompiledWasmModule(
7857     std::shared_ptr<internal::wasm::NativeModule> native_module,
7858     const char* source_url, size_t url_length)
7859     : native_module_(std::move(native_module)),
7860       source_url_(source_url, url_length) {
7861   CHECK_NOT_NULL(native_module_);
7862 }
7863 
Serialize()7864 OwnedBuffer CompiledWasmModule::Serialize() {
7865 #if V8_ENABLE_WEBASSEMBLY
7866   TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7867   i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7868   size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7869   std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7870   if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7871     return {};
7872   return {std::move(buffer), buffer_size};
7873 #else
7874   UNREACHABLE();
7875 #endif  // V8_ENABLE_WEBASSEMBLY
7876 }
7877 
GetWireBytesRef()7878 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7879 #if V8_ENABLE_WEBASSEMBLY
7880   base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7881   return {bytes_vec.begin(), bytes_vec.size()};
7882 #else
7883   UNREACHABLE();
7884 #endif  // V8_ENABLE_WEBASSEMBLY
7885 }
7886 
Buffer()7887 Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() {
7888 #if V8_ENABLE_WEBASSEMBLY
7889   i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this);
7890   i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate());
7891   return Utils::ToLocal(buffer);
7892 #else
7893   UNREACHABLE();
7894 #endif  // V8_ENABLE_WEBASSEMBLY
7895 }
7896 
GetCompiledModule()7897 CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7898 #if V8_ENABLE_WEBASSEMBLY
7899   auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7900   auto url =
7901       i::handle(i::String::cast(obj->script().name()), obj->GetIsolate());
7902   int length;
7903   std::unique_ptr<char[]> cstring =
7904       url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7905   return CompiledWasmModule(std::move(obj->shared_native_module()),
7906                             cstring.get(), length);
7907 #else
7908   UNREACHABLE();
7909 #endif  // V8_ENABLE_WEBASSEMBLY
7910 }
7911 
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7912 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7913     Isolate* isolate, const CompiledWasmModule& compiled_module) {
7914 #if V8_ENABLE_WEBASSEMBLY
7915   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7916   i::Handle<i::WasmModuleObject> module_object =
7917       i::wasm::GetWasmEngine()->ImportNativeModule(
7918           i_isolate, compiled_module.native_module_,
7919           base::VectorOf(compiled_module.source_url()));
7920   return Local<WasmModuleObject>::Cast(
7921       Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7922 #else
7923   UNREACHABLE();
7924 #endif  // V8_ENABLE_WEBASSEMBLY
7925 }
7926 
Compile(Isolate * isolate,MemorySpan<const uint8_t> wire_bytes)7927 MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
7928     Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) {
7929 #if V8_ENABLE_WEBASSEMBLY
7930   const uint8_t* start = wire_bytes.data();
7931   size_t length = wire_bytes.size();
7932   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7933   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7934     return MaybeLocal<WasmModuleObject>();
7935   }
7936   i::MaybeHandle<i::JSObject> maybe_compiled;
7937   {
7938     i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
7939     auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
7940     maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
7941         i_isolate, enabled_features, &thrower,
7942         i::wasm::ModuleWireBytes(start, start + length));
7943   }
7944   CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception());
7945   if (maybe_compiled.is_null()) {
7946     i_isolate->OptionalRescheduleException(false);
7947     return MaybeLocal<WasmModuleObject>();
7948   }
7949   return Local<WasmModuleObject>::Cast(
7950       Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7951 #else
7952   Utils::ApiCheck(false, "WasmModuleObject::Compile",
7953                   "WebAssembly support is not enabled.");
7954   UNREACHABLE();
7955 #endif  // V8_ENABLE_WEBASSEMBLY
7956 }
7957 
WasmModuleObjectBuilderStreaming(Isolate * isolate)7958 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7959     Isolate* isolate) {
7960   USE(isolate_);
7961 }
7962 
GetPromise()7963 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7964 
OnBytesReceived(const uint8_t * bytes,size_t size)7965 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7966                                                        size_t size) {}
7967 
Finish()7968 void WasmModuleObjectBuilderStreaming::Finish() {}
7969 
Abort(MaybeLocal<Value> exception)7970 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7971 
Reallocate(void * data,size_t old_length,size_t new_length)7972 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7973                                              size_t new_length) {
7974   if (old_length == new_length) return data;
7975   uint8_t* new_data =
7976       reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7977   if (new_data == nullptr) return nullptr;
7978   size_t bytes_to_copy = std::min(old_length, new_length);
7979   memcpy(new_data, data, bytes_to_copy);
7980   if (new_length > bytes_to_copy) {
7981     memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7982   }
7983   Free(data, old_length);
7984   return new_data;
7985 }
7986 
7987 // static
NewDefaultAllocator()7988 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7989   return new ArrayBufferAllocator();
7990 }
7991 
IsDetachable() const7992 bool v8::ArrayBuffer::IsDetachable() const {
7993   return Utils::OpenHandle(this)->is_detachable();
7994 }
7995 
WasDetached() const7996 bool v8::ArrayBuffer::WasDetached() const {
7997   return Utils::OpenHandle(this)->was_detached();
7998 }
7999 
8000 namespace {
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)8001 std::shared_ptr<i::BackingStore> ToInternal(
8002     std::shared_ptr<i::BackingStoreBase> backing_store) {
8003   return std::static_pointer_cast<i::BackingStore>(backing_store);
8004 }
8005 }  // namespace
8006 
Detach()8007 void v8::ArrayBuffer::Detach() {
8008   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8009   i::Isolate* isolate = obj->GetIsolate();
8010   Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
8011                   "Only detachable ArrayBuffers can be detached");
8012   API_RCS_SCOPE(isolate, ArrayBuffer, Detach);
8013   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8014   obj->Detach();
8015 }
8016 
ByteLength() const8017 size_t v8::ArrayBuffer::ByteLength() const {
8018   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8019   return obj->byte_length();
8020 }
8021 
New(Isolate * isolate,size_t byte_length)8022 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
8023   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8024   API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
8025   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8026   i::MaybeHandle<i::JSArrayBuffer> result =
8027       i_isolate->factory()->NewJSArrayBufferAndBackingStore(
8028           byte_length, i::InitializedFlag::kZeroInitialized);
8029 
8030   i::Handle<i::JSArrayBuffer> array_buffer;
8031   if (!result.ToHandle(&array_buffer)) {
8032     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8033     // version that throws an exception or otherwise does not crash.
8034     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
8035   }
8036 
8037   return Utils::ToLocal(array_buffer);
8038 }
8039 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8040 Local<ArrayBuffer> v8::ArrayBuffer::New(
8041     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
8042   CHECK_IMPLIES(backing_store->ByteLength() != 0,
8043                 backing_store->Data() != nullptr);
8044   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8045   API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
8046   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8047   std::shared_ptr<i::BackingStore> i_backing_store(
8048       ToInternal(std::move(backing_store)));
8049   Utils::ApiCheck(
8050       !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
8051       "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
8052   i::Handle<i::JSArrayBuffer> obj =
8053       i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
8054   return Utils::ToLocal(obj);
8055 }
8056 
NewBackingStore(Isolate * isolate,size_t byte_length)8057 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
8058     Isolate* isolate, size_t byte_length) {
8059   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8060   API_RCS_SCOPE(i_isolate, ArrayBuffer, NewBackingStore);
8061   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8062   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8063   std::unique_ptr<i::BackingStoreBase> backing_store =
8064       i::BackingStore::Allocate(i_isolate, byte_length,
8065                                 i::SharedFlag::kNotShared,
8066                                 i::InitializedFlag::kZeroInitialized);
8067   if (!backing_store) {
8068     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
8069   }
8070   return std::unique_ptr<v8::BackingStore>(
8071       static_cast<v8::BackingStore*>(backing_store.release()));
8072 }
8073 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8074 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
8075     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8076     void* deleter_data) {
8077   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8078   std::unique_ptr<i::BackingStoreBase> backing_store =
8079       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8080                                       i::SharedFlag::kNotShared);
8081   return std::unique_ptr<v8::BackingStore>(
8082       static_cast<v8::BackingStore*>(backing_store.release()));
8083 }
8084 
Buffer()8085 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
8086   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8087   i::Handle<i::JSArrayBuffer> buffer;
8088   if (obj->IsJSDataView()) {
8089     i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
8090                                        obj->GetIsolate());
8091     DCHECK(data_view->buffer().IsJSArrayBuffer());
8092     buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
8093                        data_view->GetIsolate());
8094   } else {
8095     DCHECK(obj->IsJSTypedArray());
8096     buffer = i::JSTypedArray::cast(*obj).GetBuffer();
8097   }
8098   return Utils::ToLocal(buffer);
8099 }
8100 
CopyContents(void * dest,size_t byte_length)8101 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
8102   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8103   size_t bytes_to_copy = std::min(byte_length, self->byte_length());
8104   if (bytes_to_copy) {
8105     i::DisallowGarbageCollection no_gc;
8106     i::Isolate* isolate = self->GetIsolate();
8107     const char* source;
8108     if (self->IsJSTypedArray()) {
8109       i::Handle<i::JSTypedArray> array(i::JSTypedArray::cast(*self), isolate);
8110       source = reinterpret_cast<char*>(array->DataPtr());
8111     } else {
8112       DCHECK(self->IsJSDataView());
8113       i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*self), isolate);
8114       source = reinterpret_cast<char*>(data_view->data_pointer());
8115     }
8116     memcpy(dest, source, bytes_to_copy);
8117   }
8118   return bytes_to_copy;
8119 }
8120 
HasBuffer() const8121 bool v8::ArrayBufferView::HasBuffer() const {
8122   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8123   if (!self->IsJSTypedArray()) return true;
8124   auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
8125   return !typed_array->is_on_heap();
8126 }
8127 
ByteOffset()8128 size_t v8::ArrayBufferView::ByteOffset() {
8129   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8130   return obj->WasDetached() ? 0 : obj->byte_offset();
8131 }
8132 
ByteLength()8133 size_t v8::ArrayBufferView::ByteLength() {
8134   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8135   return obj->WasDetached() ? 0 : obj->byte_length();
8136 }
8137 
Length()8138 size_t v8::TypedArray::Length() {
8139   i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8140   return obj->WasDetached() ? 0 : obj->length();
8141 }
8142 
8143 static_assert(
8144     v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
8145     "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
8146 
8147 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype)                           \
8148   Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer,     \
8149                                       size_t byte_offset, size_t length) { \
8150     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();  \
8151     API_RCS_SCOPE(isolate, Type##Array, New);                              \
8152     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8153     if (!Utils::ApiCheck(length <= kMaxLength,                             \
8154                          "v8::" #Type                                      \
8155                          "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
8156                          "length exceeds max allowed value")) {            \
8157       return Local<Type##Array>();                                         \
8158     }                                                                      \
8159     i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
8160     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8161         i::kExternal##Type##Array, buffer, byte_offset, length);           \
8162     return Utils::ToLocal##Type##Array(obj);                               \
8163   }                                                                        \
8164   Local<Type##Array> Type##Array::New(                                     \
8165       Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset,    \
8166       size_t length) {                                                     \
8167     CHECK(i::FLAG_harmony_sharedarraybuffer);                              \
8168     i::Isolate* isolate =                                                  \
8169         Utils::OpenHandle(*shared_array_buffer)->GetIsolate();             \
8170     API_RCS_SCOPE(isolate, Type##Array, New);                              \
8171     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8172     if (!Utils::ApiCheck(                                                  \
8173             length <= kMaxLength,                                          \
8174             "v8::" #Type                                                   \
8175             "Array::New(Local<SharedArrayBuffer>, size_t, size_t)",        \
8176             "length exceeds max allowed value")) {                         \
8177       return Local<Type##Array>();                                         \
8178     }                                                                      \
8179     i::Handle<i::JSArrayBuffer> buffer =                                   \
8180         Utils::OpenHandle(*shared_array_buffer);                           \
8181     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8182         i::kExternal##Type##Array, buffer, byte_offset, length);           \
8183     return Utils::ToLocal##Type##Array(obj);                               \
8184   }
8185 
TYPED_ARRAYS(TYPED_ARRAY_NEW)8186 TYPED_ARRAYS(TYPED_ARRAY_NEW)
8187 #undef TYPED_ARRAY_NEW
8188 
8189 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
8190                               size_t byte_offset, size_t byte_length) {
8191   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
8192   i::Isolate* isolate = buffer->GetIsolate();
8193   API_RCS_SCOPE(isolate, DataView, New);
8194   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8195   i::Handle<i::JSDataView> obj =
8196       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8197   return Utils::ToLocal(obj);
8198 }
8199 
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)8200 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
8201                               size_t byte_offset, size_t byte_length) {
8202   CHECK(i::FLAG_harmony_sharedarraybuffer);
8203   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
8204   i::Isolate* isolate = buffer->GetIsolate();
8205   API_RCS_SCOPE(isolate, DataView, New);
8206   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8207   i::Handle<i::JSDataView> obj =
8208       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8209   return Utils::ToLocal(obj);
8210 }
8211 
ByteLength() const8212 size_t v8::SharedArrayBuffer::ByteLength() const {
8213   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8214   return obj->byte_length();
8215 }
8216 
New(Isolate * isolate,size_t byte_length)8217 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
8218                                                     size_t byte_length) {
8219   CHECK(i::FLAG_harmony_sharedarraybuffer);
8220   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8221   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8222   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8223 
8224   std::unique_ptr<i::BackingStore> backing_store =
8225       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8226                                 i::InitializedFlag::kZeroInitialized);
8227 
8228   if (!backing_store) {
8229     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8230     // version that throws an exception or otherwise does not crash.
8231     i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
8232   }
8233 
8234   i::Handle<i::JSArrayBuffer> obj =
8235       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
8236   return Utils::ToLocalShared(obj);
8237 }
8238 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8239 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
8240     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
8241   CHECK(i::FLAG_harmony_sharedarraybuffer);
8242   CHECK_IMPLIES(backing_store->ByteLength() != 0,
8243                 backing_store->Data() != nullptr);
8244   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8245   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8246   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8247   std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
8248   Utils::ApiCheck(
8249       i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
8250       "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
8251   i::Handle<i::JSArrayBuffer> obj =
8252       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
8253   return Utils::ToLocalShared(obj);
8254 }
8255 
NewBackingStore(Isolate * isolate,size_t byte_length)8256 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8257     Isolate* isolate, size_t byte_length) {
8258   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8259   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, NewBackingStore);
8260   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8261   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8262   std::unique_ptr<i::BackingStoreBase> backing_store =
8263       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8264                                 i::InitializedFlag::kZeroInitialized);
8265   if (!backing_store) {
8266     i::FatalProcessOutOfMemory(i_isolate,
8267                                "v8::SharedArrayBuffer::NewBackingStore");
8268   }
8269   return std::unique_ptr<v8::BackingStore>(
8270       static_cast<v8::BackingStore*>(backing_store.release()));
8271 }
8272 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8273 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8274     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8275     void* deleter_data) {
8276   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8277   std::unique_ptr<i::BackingStoreBase> backing_store =
8278       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8279                                       i::SharedFlag::kShared);
8280   return std::unique_ptr<v8::BackingStore>(
8281       static_cast<v8::BackingStore*>(backing_store.release()));
8282 }
8283 
New(Isolate * isolate,Local<String> name)8284 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8285   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8286   API_RCS_SCOPE(i_isolate, Symbol, New);
8287   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8288   i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8289   if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8290   return Utils::ToLocal(result);
8291 }
8292 
For(Isolate * isolate,Local<String> name)8293 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8294   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8295   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8296   return Utils::ToLocal(
8297       i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8298 }
8299 
ForApi(Isolate * isolate,Local<String> name)8300 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8301   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8302   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8303   return Utils::ToLocal(
8304       i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8305 }
8306 
8307 #define WELL_KNOWN_SYMBOLS(V)                 \
8308   V(AsyncIterator, async_iterator)            \
8309   V(HasInstance, has_instance)                \
8310   V(IsConcatSpreadable, is_concat_spreadable) \
8311   V(Iterator, iterator)                       \
8312   V(Match, match)                             \
8313   V(Replace, replace)                         \
8314   V(Search, search)                           \
8315   V(Split, split)                             \
8316   V(ToPrimitive, to_primitive)                \
8317   V(ToStringTag, to_string_tag)               \
8318   V(Unscopables, unscopables)
8319 
8320 #define SYMBOL_GETTER(Name, name)                                   \
8321   Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) {           \
8322     i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8323     return Utils::ToLocal(i_isolate->factory()->name##_symbol());   \
8324   }
8325 
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8326 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8327 
8328 #undef SYMBOL_GETTER
8329 #undef WELL_KNOWN_SYMBOLS
8330 
8331 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8332   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8333   API_RCS_SCOPE(i_isolate, Private, New);
8334   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8335   i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8336   if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8337   Local<Symbol> result = Utils::ToLocal(symbol);
8338   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8339 }
8340 
ForApi(Isolate * isolate,Local<String> name)8341 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8342   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8343   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8344   Local<Symbol> result = Utils::ToLocal(
8345       i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8346   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8347 }
8348 
New(Isolate * isolate,double value)8349 Local<Number> v8::Number::New(Isolate* isolate, double value) {
8350   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8351   if (std::isnan(value)) {
8352     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8353     value = std::numeric_limits<double>::quiet_NaN();
8354   }
8355   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8356   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8357   return Utils::NumberToLocal(result);
8358 }
8359 
New(Isolate * isolate,int32_t value)8360 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8361   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8362   if (i::Smi::IsValid(value)) {
8363     return Utils::IntegerToLocal(
8364         i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8365   }
8366   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8367   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8368   return Utils::IntegerToLocal(result);
8369 }
8370 
NewFromUnsigned(Isolate * isolate,uint32_t value)8371 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8372   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8373   bool fits_into_int32_t = (value & (1 << 31)) == 0;
8374   if (fits_into_int32_t) {
8375     return Integer::New(isolate, static_cast<int32_t>(value));
8376   }
8377   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8378   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8379   return Utils::IntegerToLocal(result);
8380 }
8381 
New(Isolate * isolate,int64_t value)8382 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8383   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8384   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8385   i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8386   return Utils::ToLocal(result);
8387 }
8388 
NewFromUnsigned(Isolate * isolate,uint64_t value)8389 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8390   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8391   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8392   i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8393   return Utils::ToLocal(result);
8394 }
8395 
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8396 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8397                                             int sign_bit, int word_count,
8398                                             const uint64_t* words) {
8399   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8400   ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8401                      MaybeLocal<BigInt>(), InternalEscapableScope);
8402   i::MaybeHandle<i::BigInt> result =
8403       i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8404   has_pending_exception = result.is_null();
8405   RETURN_ON_FAILED_EXECUTION(BigInt);
8406   RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8407 }
8408 
Uint64Value(bool * lossless) const8409 uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8410   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8411   return handle->AsUint64(lossless);
8412 }
8413 
Int64Value(bool * lossless) const8414 int64_t v8::BigInt::Int64Value(bool* lossless) const {
8415   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8416   return handle->AsInt64(lossless);
8417 }
8418 
WordCount() const8419 int BigInt::WordCount() const {
8420   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8421   return handle->Words64Count();
8422 }
8423 
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8424 void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8425                           uint64_t* words) const {
8426   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8427   return handle->ToWordsArray64(sign_bit, word_count, words);
8428 }
8429 
ReportExternalAllocationLimitReached()8430 void Isolate::ReportExternalAllocationLimitReached() {
8431   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8432   if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8433   heap->ReportExternalMemoryPressure();
8434 }
8435 
GetHeapProfiler()8436 HeapProfiler* Isolate::GetHeapProfiler() {
8437   i::HeapProfiler* heap_profiler =
8438       reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8439   return reinterpret_cast<HeapProfiler*>(heap_profiler);
8440 }
8441 
SetIdle(bool is_idle)8442 void Isolate::SetIdle(bool is_idle) {
8443   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8444   isolate->SetIdle(is_idle);
8445 }
8446 
GetArrayBufferAllocator()8447 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8448   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8449   return isolate->array_buffer_allocator();
8450 }
8451 
InContext()8452 bool Isolate::InContext() {
8453   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8454   return !isolate->context().is_null();
8455 }
8456 
ClearKeptObjects()8457 void Isolate::ClearKeptObjects() {
8458   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8459   isolate->ClearKeptObjects();
8460 }
8461 
GetCurrentContext()8462 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8463   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8464   i::Context context = isolate->context();
8465   if (context.is_null()) return Local<Context>();
8466   i::Context native_context = context.native_context();
8467   if (native_context.is_null()) return Local<Context>();
8468   return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8469 }
8470 
GetEnteredOrMicrotaskContext()8471 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8472   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8473   i::Handle<i::Object> last =
8474       isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8475   if (last.is_null()) return Local<Context>();
8476   DCHECK(last->IsNativeContext());
8477   return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8478 }
8479 
GetIncumbentContext()8480 v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8481   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8482   i::Handle<i::Context> context = isolate->GetIncumbentContext();
8483   return Utils::ToLocal(context);
8484 }
8485 
ThrowError(v8::Local<v8::String> message)8486 v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8487   return ThrowException(v8::Exception::Error(message));
8488 }
8489 
ThrowException(v8::Local<v8::Value> value)8490 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8491   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8492   ENTER_V8_DO_NOT_USE(isolate);
8493   // If we're passed an empty handle, we throw an undefined exception
8494   // to deal more gracefully with out of memory situations.
8495   if (value.IsEmpty()) {
8496     isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8497   } else {
8498     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8499   }
8500   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8501 }
8502 
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8503 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8504                                     GCType gc_type) {
8505   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8506   isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8507 }
8508 
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8509 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8510                                        void* data) {
8511   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8512   isolate->heap()->RemoveGCPrologueCallback(callback, data);
8513 }
8514 
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8515 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8516                                     GCType gc_type) {
8517   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8518   isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8519 }
8520 
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8521 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8522                                        void* data) {
8523   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8524   isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8525 }
8526 
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8527 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8528                                       GCCallbackFlags flags, void* data) {
8529   reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8530 }
8531 
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8532 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8533   void* data = reinterpret_cast<void*>(callback);
8534   AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8535 }
8536 
RemoveGCPrologueCallback(GCCallback callback)8537 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8538   void* data = reinterpret_cast<void*>(callback);
8539   RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8540 }
8541 
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8542 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8543   void* data = reinterpret_cast<void*>(callback);
8544   AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8545 }
8546 
RemoveGCEpilogueCallback(GCCallback callback)8547 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8548   void* data = reinterpret_cast<void*>(callback);
8549   RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8550 }
8551 
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8552 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8553   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8554   CHECK_NULL(isolate->heap()->cpp_heap());
8555   isolate->heap()->SetEmbedderHeapTracer(tracer);
8556 }
8557 
GetEmbedderHeapTracer()8558 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8559   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8560   return isolate->heap()->GetEmbedderHeapTracer();
8561 }
8562 
SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8563 void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8564   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8565   isolate->heap()->SetEmbedderRootsHandler(handler);
8566 }
8567 
AttachCppHeap(CppHeap * cpp_heap)8568 void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
8569   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8570   CHECK_NULL(GetEmbedderHeapTracer());
8571   isolate->heap()->AttachCppHeap(cpp_heap);
8572 }
8573 
DetachCppHeap()8574 void Isolate::DetachCppHeap() {
8575   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8576   isolate->heap()->DetachCppHeap();
8577 }
8578 
GetCppHeap() const8579 CppHeap* Isolate::GetCppHeap() const {
8580   const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8581   return isolate->heap()->cpp_heap();
8582 }
8583 
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8584 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8585     GetExternallyAllocatedMemoryInBytesCallback callback) {
8586   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8587   isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8588 }
8589 
TerminateExecution()8590 void Isolate::TerminateExecution() {
8591   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8592   isolate->stack_guard()->RequestTerminateExecution();
8593 }
8594 
IsExecutionTerminating()8595 bool Isolate::IsExecutionTerminating() {
8596   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8597   return IsExecutionTerminatingCheck(isolate);
8598 }
8599 
CancelTerminateExecution()8600 void Isolate::CancelTerminateExecution() {
8601   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8602   isolate->stack_guard()->ClearTerminateExecution();
8603   isolate->CancelTerminateExecution();
8604 }
8605 
RequestInterrupt(InterruptCallback callback,void * data)8606 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8607   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8608   isolate->RequestInterrupt(callback, data);
8609 }
8610 
HasPendingBackgroundTasks()8611 bool Isolate::HasPendingBackgroundTasks() {
8612 #if V8_ENABLE_WEBASSEMBLY
8613   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8614   return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate);
8615 #else
8616   return false;
8617 #endif  // V8_ENABLE_WEBASSEMBLY
8618 }
8619 
RequestGarbageCollectionForTesting(GarbageCollectionType type)8620 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8621   Utils::ApiCheck(i::FLAG_expose_gc,
8622                   "v8::Isolate::RequestGarbageCollectionForTesting",
8623                   "Must use --expose-gc");
8624   if (type == kMinorGarbageCollection) {
8625     reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8626         i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8627         kGCCallbackFlagForced);
8628   } else {
8629     DCHECK_EQ(kFullGarbageCollection, type);
8630     reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8631         i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8632         kGCCallbackFlagForced);
8633   }
8634 }
8635 
RequestGarbageCollectionForTesting(GarbageCollectionType type,EmbedderHeapTracer::EmbedderStackState stack_state)8636 void Isolate::RequestGarbageCollectionForTesting(
8637     GarbageCollectionType type,
8638     EmbedderHeapTracer::EmbedderStackState stack_state) {
8639   base::Optional<i::EmbedderStackStateScope> stack_scope;
8640   if (type == kFullGarbageCollection) {
8641     stack_scope.emplace(reinterpret_cast<i::Isolate*>(this)->heap(),
8642                         i::EmbedderStackStateScope::kExplicitInvocation,
8643                         stack_state);
8644   }
8645   RequestGarbageCollectionForTesting(type);
8646 }
8647 
GetCurrent()8648 Isolate* Isolate::GetCurrent() {
8649   i::Isolate* isolate = i::Isolate::Current();
8650   return reinterpret_cast<Isolate*>(isolate);
8651 }
8652 
TryGetCurrent()8653 Isolate* Isolate::TryGetCurrent() {
8654   i::Isolate* isolate = i::Isolate::TryGetCurrent();
8655   return reinterpret_cast<Isolate*>(isolate);
8656 }
8657 
IsCurrent() const8658 bool Isolate::IsCurrent() const {
8659   return reinterpret_cast<const i::Isolate*>(this)->IsCurrent();
8660 }
8661 
8662 // static
Allocate()8663 Isolate* Isolate::Allocate() {
8664   return reinterpret_cast<Isolate*>(i::Isolate::New());
8665 }
8666 
8667 Isolate::CreateParams::CreateParams() = default;
8668 
8669 Isolate::CreateParams::~CreateParams() = default;
8670 
8671 // static
8672 // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8673 void Isolate::Initialize(Isolate* isolate,
8674                          const v8::Isolate::CreateParams& params) {
8675   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8676   TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.IsolateInitialize");
8677   if (auto allocator = params.array_buffer_allocator_shared) {
8678     CHECK(params.array_buffer_allocator == nullptr ||
8679           params.array_buffer_allocator == allocator.get());
8680     i_isolate->set_array_buffer_allocator(allocator.get());
8681     i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8682   } else {
8683     CHECK_NOT_NULL(params.array_buffer_allocator);
8684     i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8685   }
8686   if (params.snapshot_blob != nullptr) {
8687     i_isolate->set_snapshot_blob(params.snapshot_blob);
8688   } else {
8689     i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8690   }
8691 
8692   if (params.fatal_error_callback) {
8693     isolate->SetFatalErrorHandler(params.fatal_error_callback);
8694   }
8695 
8696   if (params.oom_error_callback) {
8697     isolate->SetOOMErrorHandler(params.oom_error_callback);
8698   }
8699 
8700   if (params.counter_lookup_callback) {
8701     isolate->SetCounterFunction(params.counter_lookup_callback);
8702   }
8703 
8704   if (params.create_histogram_callback) {
8705     isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8706   }
8707 
8708   if (params.add_histogram_sample_callback) {
8709     isolate->SetAddHistogramSampleFunction(
8710         params.add_histogram_sample_callback);
8711   }
8712 
8713   i_isolate->set_api_external_references(params.external_references);
8714   i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8715 
8716   i_isolate->heap()->ConfigureHeap(params.constraints);
8717   if (params.constraints.stack_limit() != nullptr) {
8718     uintptr_t limit =
8719         reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8720     i_isolate->stack_guard()->SetStackLimit(limit);
8721   }
8722 
8723   if (params.experimental_attach_to_shared_isolate != nullptr) {
8724     i_isolate->set_shared_isolate(reinterpret_cast<i::Isolate*>(
8725         params.experimental_attach_to_shared_isolate));
8726   }
8727 
8728   // TODO(v8:2487): Once we got rid of Isolate::Current(), we can remove this.
8729   Isolate::Scope isolate_scope(isolate);
8730   if (i_isolate->snapshot_blob() == nullptr) {
8731     FATAL(
8732         "V8 snapshot blob was not set during initialization. This can mean "
8733         "that the snapshot blob file is corrupted or missing.");
8734   }
8735   if (!i::Snapshot::Initialize(i_isolate)) {
8736     // If snapshot data was provided and we failed to deserialize it must
8737     // have been corrupted.
8738     FATAL(
8739         "Failed to deserialize the V8 snapshot blob. This can mean that the "
8740         "snapshot blob file is corrupted or missing.");
8741   }
8742 
8743   {
8744     // Set up code event handlers. Needs to be after i::Snapshot::Initialize
8745     // because that is where we add the isolate to WasmEngine.
8746     auto code_event_handler = params.code_event_handler;
8747     if (code_event_handler) {
8748       isolate->SetJitCodeEventHandler(kJitCodeEventEnumExisting,
8749                                       code_event_handler);
8750     }
8751   }
8752 
8753   i_isolate->set_only_terminate_in_safe_scope(
8754       params.only_terminate_in_safe_scope);
8755   i_isolate->set_embedder_wrapper_type_index(
8756       params.embedder_wrapper_type_index);
8757   i_isolate->set_embedder_wrapper_object_index(
8758       params.embedder_wrapper_object_index);
8759 
8760   if (!i::V8::GetCurrentPlatform()
8761            ->GetForegroundTaskRunner(isolate)
8762            ->NonNestableTasksEnabled()) {
8763     FATAL(
8764         "The current platform's foreground task runner does not have "
8765         "non-nestable tasks enabled. The embedder must provide one.");
8766   }
8767 }
8768 
New(const Isolate::CreateParams & params)8769 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8770   Isolate* isolate = Allocate();
8771   Initialize(isolate, params);
8772   return isolate;
8773 }
8774 
Dispose()8775 void Isolate::Dispose() {
8776   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8777   if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8778                        "Disposing the isolate that is entered by a thread.")) {
8779     return;
8780   }
8781   i::Isolate::Delete(isolate);
8782 }
8783 
DumpAndResetStats()8784 void Isolate::DumpAndResetStats() {
8785   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8786   isolate->DumpAndResetStats();
8787 }
8788 
DiscardThreadSpecificMetadata()8789 void Isolate::DiscardThreadSpecificMetadata() {
8790   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8791   isolate->DiscardPerThreadDataForThisThread();
8792 }
8793 
Enter()8794 void Isolate::Enter() {
8795   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8796   isolate->Enter();
8797 }
8798 
Exit()8799 void Isolate::Exit() {
8800   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8801   isolate->Exit();
8802 }
8803 
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8804 void Isolate::SetAbortOnUncaughtExceptionCallback(
8805     AbortOnUncaughtExceptionCallback callback) {
8806   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8807   isolate->SetAbortOnUncaughtExceptionCallback(callback);
8808 }
8809 
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8810 void Isolate::SetHostImportModuleDynamicallyCallback(
8811     HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8812   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8813   isolate->SetHostImportModuleDynamicallyCallback(callback);
8814 }
8815 
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8816 void Isolate::SetHostImportModuleDynamicallyCallback(
8817     HostImportModuleDynamicallyCallback callback) {
8818   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8819   isolate->SetHostImportModuleDynamicallyCallback(callback);
8820 }
8821 
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8822 void Isolate::SetHostInitializeImportMetaObjectCallback(
8823     HostInitializeImportMetaObjectCallback callback) {
8824   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8825   isolate->SetHostInitializeImportMetaObjectCallback(callback);
8826 }
8827 
SetHostCreateShadowRealmContextCallback(HostCreateShadowRealmContextCallback callback)8828 void Isolate::SetHostCreateShadowRealmContextCallback(
8829     HostCreateShadowRealmContextCallback callback) {
8830   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8831   isolate->SetHostCreateShadowRealmContextCallback(callback);
8832 }
8833 
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8834 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8835   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8836   isolate->SetPrepareStackTraceCallback(callback);
8837 }
8838 
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8839 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8840     Isolate* isolate,
8841     Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8842     : on_failure_(on_failure), isolate_(isolate) {
8843   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8844   switch (on_failure_) {
8845     case CRASH_ON_FAILURE:
8846       i::DisallowJavascriptExecution::Open(i_isolate,
8847                                            &was_execution_allowed_assert_);
8848       break;
8849     case THROW_ON_FAILURE:
8850       i::ThrowOnJavascriptExecution::Open(i_isolate,
8851                                           &was_execution_allowed_throws_);
8852       break;
8853     case DUMP_ON_FAILURE:
8854       i::DumpOnJavascriptExecution::Open(i_isolate,
8855                                          &was_execution_allowed_dump_);
8856       break;
8857     default:
8858       UNREACHABLE();
8859   }
8860 }
8861 
~DisallowJavascriptExecutionScope()8862 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8863   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8864   switch (on_failure_) {
8865     case CRASH_ON_FAILURE:
8866       i::DisallowJavascriptExecution::Close(i_isolate,
8867                                             was_execution_allowed_assert_);
8868       break;
8869     case THROW_ON_FAILURE:
8870       i::ThrowOnJavascriptExecution::Close(i_isolate,
8871                                            was_execution_allowed_throws_);
8872       break;
8873     case DUMP_ON_FAILURE:
8874       i::DumpOnJavascriptExecution::Close(i_isolate,
8875                                           was_execution_allowed_dump_);
8876       break;
8877     default:
8878       UNREACHABLE();
8879   }
8880 }
8881 
AllowJavascriptExecutionScope(Isolate * isolate)8882 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8883     Isolate* isolate)
8884     : isolate_(isolate) {
8885   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8886   i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_);
8887   i::NoThrowOnJavascriptExecution::Open(i_isolate,
8888                                         &was_execution_allowed_throws_);
8889   i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_);
8890 }
8891 
~AllowJavascriptExecutionScope()8892 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8893   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8894   i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_);
8895   i::NoThrowOnJavascriptExecution::Close(i_isolate,
8896                                          was_execution_allowed_throws_);
8897   i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_);
8898 }
8899 
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8900 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8901     Isolate* isolate, MicrotaskQueue* microtask_queue)
8902     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8903       microtask_queue_(microtask_queue
8904                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8905                            : isolate_->default_microtask_queue()) {
8906   isolate_->thread_local_top()->IncrementCallDepth(this);
8907   microtask_queue_->IncrementMicrotasksSuppressions();
8908 }
8909 
~SuppressMicrotaskExecutionScope()8910 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8911   microtask_queue_->DecrementMicrotasksSuppressions();
8912   isolate_->thread_local_top()->DecrementCallDepth(this);
8913 }
8914 
SafeForTerminationScope(v8::Isolate * isolate)8915 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8916     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8917       prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8918   isolate_->set_next_v8_call_is_safe_for_termination(true);
8919 }
8920 
~SafeForTerminationScope()8921 Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8922   isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8923 }
8924 
GetDataFromSnapshotOnce(size_t index)8925 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8926   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8927   i::FixedArray list = i_isolate->heap()->serialized_objects();
8928   return GetSerializedDataFromFixedArray(i_isolate, list, index);
8929 }
8930 
GetHeapStatistics(HeapStatistics * heap_statistics)8931 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8932   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8933   i::Heap* heap = isolate->heap();
8934 
8935   // The order of acquiring memory statistics is important here. We query in
8936   // this order because of concurrent allocation: 1) used memory 2) comitted
8937   // physical memory 3) committed memory. Therefore the condition used <=
8938   // committed physical <= committed should hold.
8939   heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8940   heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8941   DCHECK_LE(heap_statistics->used_global_handles_size_,
8942             heap_statistics->total_global_handles_size_);
8943 
8944   heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8945   heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8946   heap_statistics->total_heap_size_ = heap->CommittedMemory();
8947 
8948   heap_statistics->total_available_size_ = heap->Available();
8949 
8950   if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8951     i::ReadOnlySpace* ro_space = heap->read_only_space();
8952     heap_statistics->used_heap_size_ += ro_space->Size();
8953     heap_statistics->total_physical_size_ +=
8954         ro_space->CommittedPhysicalMemory();
8955     heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8956   }
8957 
8958   // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8959   // this and add DCHECK.
8960   DCHECK_LE(heap_statistics->used_heap_size_,
8961             heap_statistics->total_heap_size_);
8962 
8963   heap_statistics->total_heap_size_executable_ =
8964       heap->CommittedMemoryExecutable();
8965   heap_statistics->heap_size_limit_ = heap->MaxReserved();
8966   // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8967   // API becomes available we should report the malloced memory separately. For
8968   // now we just add the values, thereby over-approximating the peak slightly.
8969   heap_statistics->malloced_memory_ =
8970       isolate->allocator()->GetCurrentMemoryUsage() +
8971       isolate->string_table()->GetCurrentMemoryUsage();
8972   // On 32-bit systems backing_store_bytes() might overflow size_t temporarily
8973   // due to concurrent array buffer sweeping.
8974   heap_statistics->external_memory_ =
8975       isolate->heap()->backing_store_bytes() < SIZE_MAX
8976           ? static_cast<size_t>(isolate->heap()->backing_store_bytes())
8977           : SIZE_MAX;
8978   heap_statistics->peak_malloced_memory_ =
8979       isolate->allocator()->GetMaxMemoryUsage();
8980   heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8981   heap_statistics->number_of_detached_contexts_ =
8982       heap->NumberOfDetachedContexts();
8983   heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8984 
8985 #if V8_ENABLE_WEBASSEMBLY
8986   heap_statistics->malloced_memory_ +=
8987       i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage();
8988   heap_statistics->peak_malloced_memory_ +=
8989       i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage();
8990 #endif  // V8_ENABLE_WEBASSEMBLY
8991 }
8992 
DeserializeOrCompile(Isolate * v8_isolate,MemorySpan<const uint8_t> wire_bytes,MemorySpan<const uint8_t> wasm_cache_data,bool & cacheRejected)8993 MaybeLocal<WasmModuleObject> WasmModuleObject::DeserializeOrCompile(
8994     Isolate* v8_isolate, MemorySpan<const uint8_t> wire_bytes,
8995     MemorySpan<const uint8_t> wasm_cache_data, bool& cacheRejected) {
8996 #if V8_ENABLE_WEBASSEMBLY
8997   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
8998   i::MaybeHandle<i::WasmModuleObject> maybe_mdoule =
8999       i::wasm::DeserializeNativeModule(
9000           i_isolate,
9001           base::Vector<const uint8_t>(wasm_cache_data.data(),
9002                                       wasm_cache_data.size()),
9003           base::Vector<const uint8_t>(wire_bytes.data(), wire_bytes.size()),
9004           {});
9005   cacheRejected = maybe_mdoule.is_null();
9006   if (!cacheRejected) {
9007     // Deserialize successfully
9008     return Local<WasmModuleObject>::Cast(Utils::ToLocal(
9009         i::Handle<i::JSObject>::cast(maybe_mdoule.ToHandleChecked())));
9010   }
9011   return Compile(v8_isolate, wire_bytes);
9012 #else
9013   Utils::ApiCheck(false, "WasmModuleObject::DeserializeOrCompile",
9014                   "WebAssembly support is not enabled");
9015   UNREACHABLE();
9016 #endif  // V8_ENABLE_WEBASSEMBLY
9017 }
9018 
CompileFunction(Isolate * v8_isolate,uint32_t function_index,WasmExecutionTier tier)9019 bool WasmModuleObject::CompileFunction(Isolate* v8_isolate,
9020                                        uint32_t function_index,
9021                                        WasmExecutionTier tier) {
9022 #if V8_ENABLE_WEBASSEMBLY
9023   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9024   auto module = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
9025   auto* native_module = module->native_module();
9026   uint32_t num_imported_functions = native_module->num_imported_functions();
9027   uint32_t num_functions = native_module->num_functions();
9028   // Check function index out of range.
9029   if (function_index < num_imported_functions || function_index >= num_functions) {
9030     return false;
9031   }
9032 
9033   // Update the static_assert once i::wasm::ExecutionTier changed.
9034   static_assert(static_cast<uint8_t>(v8::WasmExecutionTier::kNone) ==
9035                 static_cast<uint8_t>(i::wasm::ExecutionTier::kNone));
9036   static_assert(static_cast<uint8_t>(v8::WasmExecutionTier::kLiftoff) ==
9037                 static_cast<uint8_t>(i::wasm::ExecutionTier::kLiftoff));
9038   static_assert(static_cast<uint8_t>(v8::WasmExecutionTier::kTurbofan) ==
9039                 static_cast<uint8_t>(i::wasm::ExecutionTier::kTurbofan));
9040   auto executionTier =
9041       static_cast<i::wasm::ExecutionTier>(static_cast<uint8_t>(tier));
9042   i::wasm::GetWasmEngine()->CompileFunction(i_isolate,
9043                                             module->native_module(),
9044                                             function_index, executionTier);
9045   if (native_module->compilation_state()->failed()) {
9046     return false;
9047   }
9048   return true;
9049 #else
9050   Utils::ApiCheck(false, "WasmModuleObject::CompileFunction",
9051                   "WebAssembly support is not enabled");
9052   UNREACHABLE();
9053 #endif  // V8_ENABLE_WEBASSEMBLY
9054 }
9055 
NumberOfHeapSpaces()9056 size_t Isolate::NumberOfHeapSpaces() {
9057   return i::LAST_SPACE - i::FIRST_SPACE + 1;
9058 }
9059 
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)9060 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
9061                                      size_t index) {
9062   if (!space_statistics) return false;
9063   if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
9064     return false;
9065 
9066   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9067   i::Heap* heap = isolate->heap();
9068 
9069   i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
9070   space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
9071 
9072   if (allocation_space == i::RO_SPACE) {
9073     if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
9074       // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
9075       space_statistics->space_size_ = 0;
9076       space_statistics->space_used_size_ = 0;
9077       space_statistics->space_available_size_ = 0;
9078       space_statistics->physical_space_size_ = 0;
9079     } else {
9080       i::ReadOnlySpace* space = heap->read_only_space();
9081       space_statistics->space_size_ = space->CommittedMemory();
9082       space_statistics->space_used_size_ = space->Size();
9083       space_statistics->space_available_size_ = 0;
9084       space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
9085     }
9086   } else {
9087     i::Space* space = heap->space(static_cast<int>(index));
9088     space_statistics->space_size_ = space ? space->CommittedMemory() : 0;
9089     space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0;
9090     space_statistics->space_available_size_ = space ? space->Available() : 0;
9091     space_statistics->physical_space_size_ =
9092         space ? space->CommittedPhysicalMemory() : 0;
9093   }
9094   return true;
9095 }
9096 
NumberOfTrackedHeapObjectTypes()9097 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
9098   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9099   i::Heap* heap = isolate->heap();
9100   return heap->NumberOfTrackedHeapObjectTypes();
9101 }
9102 
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)9103 bool Isolate::GetHeapObjectStatisticsAtLastGC(
9104     HeapObjectStatistics* object_statistics, size_t type_index) {
9105   if (!object_statistics) return false;
9106   if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
9107 
9108   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9109   i::Heap* heap = isolate->heap();
9110   if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
9111 
9112   const char* object_type;
9113   const char* object_sub_type;
9114   size_t object_count = heap->ObjectCountAtLastGC(type_index);
9115   size_t object_size = heap->ObjectSizeAtLastGC(type_index);
9116   if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
9117     // There should be no objects counted when the type is unknown.
9118     DCHECK_EQ(object_count, 0U);
9119     DCHECK_EQ(object_size, 0U);
9120     return false;
9121   }
9122 
9123   object_statistics->object_type_ = object_type;
9124   object_statistics->object_sub_type_ = object_sub_type;
9125   object_statistics->object_count_ = object_count;
9126   object_statistics->object_size_ = object_size;
9127   return true;
9128 }
9129 
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)9130 bool Isolate::GetHeapCodeAndMetadataStatistics(
9131     HeapCodeStatistics* code_statistics) {
9132   if (!code_statistics) return false;
9133 
9134   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9135   isolate->heap()->CollectCodeStatistics();
9136 
9137   code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
9138   code_statistics->bytecode_and_metadata_size_ =
9139       isolate->bytecode_and_metadata_size();
9140   code_statistics->external_script_source_size_ =
9141       isolate->external_script_source_size();
9142   code_statistics->cpu_profiler_metadata_size_ =
9143       i::CpuProfiler::GetAllProfilersMemorySize(
9144           reinterpret_cast<i::Isolate*>(isolate));
9145 
9146   return true;
9147 }
9148 
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)9149 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
9150                             MeasureMemoryExecution execution) {
9151   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9152   return isolate->heap()->MeasureMemory(std::move(delegate), execution);
9153 }
9154 
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)9155 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
9156     Isolate* isolate, Local<Context> context,
9157     Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
9158   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9159   i::Handle<i::NativeContext> native_context =
9160       handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
9161   i::Handle<i::JSPromise> js_promise =
9162       i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
9163   return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
9164                                                   mode);
9165 }
9166 
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)9167 void Isolate::GetStackSample(const RegisterState& state, void** frames,
9168                              size_t frames_limit, SampleInfo* sample_info) {
9169   RegisterState regs = state;
9170   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9171   if (i::TickSample::GetStackSample(isolate, &regs,
9172                                     i::TickSample::kSkipCEntryFrame, frames,
9173                                     frames_limit, sample_info)) {
9174     return;
9175   }
9176   sample_info->frames_count = 0;
9177   sample_info->vm_state = OTHER;
9178   sample_info->external_callback_entry = nullptr;
9179 }
9180 
NumberOfPhantomHandleResetsSinceLastCall()9181 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
9182   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9183   return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
9184 }
9185 
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)9186 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
9187     int64_t change_in_bytes) {
9188   // Try to check for unreasonably large or small values from the embedder.
9189   const int64_t kMaxReasonableBytes = int64_t(1) << 60;
9190   const int64_t kMinReasonableBytes = -kMaxReasonableBytes;
9191   STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength);
9192 
9193   CHECK(kMinReasonableBytes <= change_in_bytes &&
9194         change_in_bytes < kMaxReasonableBytes);
9195 
9196   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9197   int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
9198 
9199   if (change_in_bytes <= 0) return amount;
9200 
9201   if (amount > i_isolate->heap()->external_memory_limit()) {
9202     ReportExternalAllocationLimitReached();
9203   }
9204   return amount;
9205 }
9206 
SetEventLogger(LogEventCallback that)9207 void Isolate::SetEventLogger(LogEventCallback that) {
9208   // Do not overwrite the event logger if we want to log explicitly.
9209   if (i::FLAG_log_internal_timer_events) return;
9210   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9211   isolate->set_event_logger(that);
9212 }
9213 
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9214 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
9215   if (callback == nullptr) return;
9216   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9217   isolate->AddBeforeCallEnteredCallback(callback);
9218 }
9219 
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9220 void Isolate::RemoveBeforeCallEnteredCallback(
9221     BeforeCallEnteredCallback callback) {
9222   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9223   isolate->RemoveBeforeCallEnteredCallback(callback);
9224 }
9225 
AddCallCompletedCallback(CallCompletedCallback callback)9226 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
9227   if (callback == nullptr) return;
9228   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9229   isolate->AddCallCompletedCallback(callback);
9230 }
9231 
RemoveCallCompletedCallback(CallCompletedCallback callback)9232 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
9233   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9234   isolate->RemoveCallCompletedCallback(callback);
9235 }
9236 
Wake()9237 void Isolate::AtomicsWaitWakeHandle::Wake() {
9238   reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
9239 }
9240 
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)9241 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
9242   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9243   isolate->SetAtomicsWaitCallback(callback, data);
9244 }
9245 
SetPromiseHook(PromiseHook hook)9246 void Isolate::SetPromiseHook(PromiseHook hook) {
9247   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9248   isolate->SetPromiseHook(hook);
9249 }
9250 
SetPromiseRejectCallback(PromiseRejectCallback callback)9251 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
9252   if (callback == nullptr) return;
9253   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9254   isolate->SetPromiseRejectCallback(callback);
9255 }
9256 
PerformMicrotaskCheckpoint()9257 void Isolate::PerformMicrotaskCheckpoint() {
9258   DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
9259   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9260   isolate->default_microtask_queue()->PerformCheckpoint(this);
9261 }
9262 
EnqueueMicrotask(Local<Function> v8_function)9263 void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
9264   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9265   i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
9266   i::Handle<i::NativeContext> handler_context;
9267   if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
9268           &handler_context))
9269     handler_context = isolate->native_context();
9270   MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
9271   if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
9272 }
9273 
EnqueueMicrotask(MicrotaskCallback callback,void * data)9274 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
9275   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9276   isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
9277 }
9278 
SetMicrotasksPolicy(MicrotasksPolicy policy)9279 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9280   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9281   isolate->default_microtask_queue()->set_microtasks_policy(policy);
9282 }
9283 
GetMicrotasksPolicy() const9284 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
9285   i::Isolate* isolate =
9286       reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
9287   return isolate->default_microtask_queue()->microtasks_policy();
9288 }
9289 
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9290 void Isolate::AddMicrotasksCompletedCallback(
9291     MicrotasksCompletedCallbackWithData callback, void* data) {
9292   DCHECK(callback);
9293   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9294   isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
9295                                                                      data);
9296 }
9297 
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9298 void Isolate::RemoveMicrotasksCompletedCallback(
9299     MicrotasksCompletedCallbackWithData callback, void* data) {
9300   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9301   isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
9302       callback, data);
9303 }
9304 
SetUseCounterCallback(UseCounterCallback callback)9305 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9306   reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9307 }
9308 
SetCounterFunction(CounterLookupCallback callback)9309 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9310   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9311   isolate->counters()->ResetCounterFunction(callback);
9312 }
9313 
SetCreateHistogramFunction(CreateHistogramCallback callback)9314 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9315   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9316   isolate->counters()->ResetCreateHistogramFunction(callback);
9317 }
9318 
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)9319 void Isolate::SetAddHistogramSampleFunction(
9320     AddHistogramSampleCallback callback) {
9321   reinterpret_cast<i::Isolate*>(this)
9322       ->counters()
9323       ->SetAddHistogramSampleFunction(callback);
9324 }
9325 
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)9326 void Isolate::SetMetricsRecorder(
9327     const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
9328   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9329   isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder);
9330 }
9331 
SetAddCrashKeyCallback(AddCrashKeyCallback callback)9332 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
9333   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9334   isolate->SetAddCrashKeyCallback(callback);
9335 }
9336 
IdleNotificationDeadline(double deadline_in_seconds)9337 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
9338   // Returning true tells the caller that it need not
9339   // continue to call IdleNotification.
9340   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9341   if (!i::FLAG_use_idle_notification) return true;
9342   return isolate->heap()->IdleNotification(deadline_in_seconds);
9343 }
9344 
LowMemoryNotification()9345 void Isolate::LowMemoryNotification() {
9346   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9347   {
9348     i::NestedTimedHistogramScope idle_notification_scope(
9349         isolate->counters()->gc_low_memory_notification());
9350     TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9351     isolate->heap()->CollectAllAvailableGarbage(
9352         i::GarbageCollectionReason::kLowMemoryNotification);
9353   }
9354 }
9355 
ContextDisposedNotification(bool dependant_context)9356 int Isolate::ContextDisposedNotification(bool dependant_context) {
9357   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9358 #if V8_ENABLE_WEBASSEMBLY
9359   if (!dependant_context) {
9360     if (!isolate->context().is_null()) {
9361       // We left the current context, we can abort all WebAssembly compilations
9362       // of that context.
9363       // A handle scope for the native context.
9364       i::HandleScope handle_scope(isolate);
9365       i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext(
9366           isolate->native_context());
9367     }
9368   }
9369 #endif  // V8_ENABLE_WEBASSEMBLY
9370   // TODO(ahaas): move other non-heap activity out of the heap call.
9371   return isolate->heap()->NotifyContextDisposed(dependant_context);
9372 }
9373 
IsolateInForegroundNotification()9374 void Isolate::IsolateInForegroundNotification() {
9375   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9376   return isolate->IsolateInForegroundNotification();
9377 }
9378 
IsolateInBackgroundNotification()9379 void Isolate::IsolateInBackgroundNotification() {
9380   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9381   return isolate->IsolateInBackgroundNotification();
9382 }
9383 
MemoryPressureNotification(MemoryPressureLevel level)9384 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9385   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9386   bool on_isolate_thread =
9387       isolate->was_locker_ever_used()
9388           ? isolate->thread_manager()->IsLockedByCurrentThread()
9389           : i::ThreadId::Current() == isolate->thread_id();
9390   isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9391 }
9392 
ClearCachesForTesting()9393 void Isolate::ClearCachesForTesting() {
9394   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9395   isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9396   isolate->ClearSerializerData();
9397 }
9398 
EnableMemorySavingsMode()9399 void Isolate::EnableMemorySavingsMode() {
9400   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9401   isolate->EnableMemorySavingsMode();
9402 }
9403 
DisableMemorySavingsMode()9404 void Isolate::DisableMemorySavingsMode() {
9405   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9406   isolate->DisableMemorySavingsMode();
9407 }
9408 
SetRAILMode(RAILMode rail_mode)9409 void Isolate::SetRAILMode(RAILMode rail_mode) {
9410   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9411   return isolate->SetRAILMode(rail_mode);
9412 }
9413 
UpdateLoadStartTime()9414 void Isolate::UpdateLoadStartTime() {
9415   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9416   isolate->UpdateLoadStartTime();
9417 }
9418 
IncreaseHeapLimitForDebugging()9419 void Isolate::IncreaseHeapLimitForDebugging() {
9420   // No-op.
9421 }
9422 
RestoreOriginalHeapLimit()9423 void Isolate::RestoreOriginalHeapLimit() {
9424   // No-op.
9425 }
9426 
IsHeapLimitIncreasedForDebugging()9427 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9428 
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9429 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9430                                      JitCodeEventHandler event_handler) {
9431   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9432   // Ensure that logging is initialized for our isolate.
9433   isolate->InitializeLoggingAndCounters();
9434   isolate->logger()->SetCodeEventHandler(options, event_handler);
9435 }
9436 
SetStackLimit(uintptr_t stack_limit)9437 void Isolate::SetStackLimit(uintptr_t stack_limit) {
9438   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9439   CHECK(stack_limit);
9440   isolate->stack_guard()->SetStackLimit(stack_limit);
9441 }
9442 
GetCodeRange(void ** start,size_t * length_in_bytes)9443 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9444   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9445   const base::AddressRegion& code_region = isolate->heap()->code_region();
9446   *start = reinterpret_cast<void*>(code_region.begin());
9447   *length_in_bytes = code_region.size();
9448 }
9449 
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9450 void Isolate::GetEmbeddedCodeRange(const void** start,
9451                                    size_t* length_in_bytes) {
9452   // Note, we should return the embedded code rande from the .text section here.
9453   i::EmbeddedData d = i::EmbeddedData::FromBlob();
9454   *start = reinterpret_cast<const void*>(d.code());
9455   *length_in_bytes = d.code_size();
9456 }
9457 
GetJSEntryStubs()9458 JSEntryStubs Isolate::GetJSEntryStubs() {
9459   JSEntryStubs entry_stubs;
9460 
9461   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9462   std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = {
9463       {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub},
9464        {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9465        {i::Builtin::kJSRunMicrotasksEntry,
9466         &entry_stubs.js_run_microtasks_entry_stub}}};
9467   for (auto& pair : stubs) {
9468     i::Code js_entry = FromCodeT(isolate->builtins()->code(pair.first));
9469     pair.second->code.start =
9470         reinterpret_cast<const void*>(js_entry.InstructionStart());
9471     pair.second->code.length_in_bytes = js_entry.InstructionSize();
9472   }
9473 
9474   return entry_stubs;
9475 }
9476 
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9477 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9478 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9479   // Not implemented on other platforms.
9480   UNREACHABLE();
9481 #else
9482 
9483   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9484   std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9485 
9486   DCHECK_NOT_NULL(code_pages);
9487 
9488   // Copy as many elements into the output vector as we can. If the
9489   // caller-provided buffer is not big enough, we fill it, and the caller can
9490   // provide a bigger one next time. We do it this way because allocation is not
9491   // allowed in signal handlers.
9492   size_t limit = std::min(capacity, code_pages->size());
9493   for (size_t i = 0; i < limit; i++) {
9494     code_pages_out[i] = code_pages->at(i);
9495   }
9496   return code_pages->size();
9497 #endif
9498 }
9499 
9500 #define CALLBACK_SETTER(ExternalName, Type, InternalName)      \
9501   void Isolate::Set##ExternalName(Type callback) {             \
9502     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9503     isolate->set_##InternalName(callback);                     \
9504   }
9505 
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9506 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9507 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9508 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9509                 ModifyCodeGenerationFromStringsCallback2,
9510                 modify_code_gen_callback2)
9511 CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9512                 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9513 
9514 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9515 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9516 
9517 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9518                 wasm_streaming_callback)
9519 
9520 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9521                 wasm_load_source_map_callback)
9522 
9523 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9524                 wasm_simd_enabled_callback)
9525 
9526 CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9527                 wasm_exceptions_enabled_callback)
9528 
9529 CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9530                 WasmDynamicTieringEnabledCallback,
9531                 wasm_dynamic_tiering_enabled_callback)
9532 
9533 CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9534                 SharedArrayBufferConstructorEnabledCallback,
9535                 sharedarraybuffer_constructor_enabled_callback)
9536 
9537 void Isolate::InstallConditionalFeatures(Local<Context> context) {
9538   v8::HandleScope handle_scope(this);
9539   v8::Context::Scope context_scope(context);
9540   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9541   isolate->InstallConditionalFeatures(Utils::OpenHandle(*context));
9542 #if V8_ENABLE_WEBASSEMBLY
9543   if (i::FLAG_expose_wasm) {
9544     i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context));
9545   }
9546 #endif  // V8_ENABLE_WEBASSEMBLY
9547 }
9548 
AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9549 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9550                                        void* data) {
9551   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9552   isolate->heap()->AddNearHeapLimitCallback(callback, data);
9553 }
9554 
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9555 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9556                                           size_t heap_limit) {
9557   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9558   isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9559 }
9560 
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9561 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9562   DCHECK_GT(threshold_percent, 0.0);
9563   DCHECK_LT(threshold_percent, 1.0);
9564   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9565   isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9566 }
9567 
IsDead()9568 bool Isolate::IsDead() {
9569   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9570   return isolate->IsDead();
9571 }
9572 
AddMessageListener(MessageCallback that,Local<Value> data)9573 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9574   return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9575 }
9576 
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9577 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9578                                                int message_levels,
9579                                                Local<Value> data) {
9580   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9581   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9582   i::HandleScope scope(isolate);
9583   i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9584   i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9585   i::Handle<i::Foreign> foreign =
9586       isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9587   listener->set(0, *foreign);
9588   listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9589                                   : *Utils::OpenHandle(*data));
9590   listener->set(2, i::Smi::FromInt(message_levels));
9591   list = i::TemplateList::Add(isolate, list, listener);
9592   isolate->heap()->SetMessageListeners(*list);
9593   return true;
9594 }
9595 
RemoveMessageListeners(MessageCallback that)9596 void Isolate::RemoveMessageListeners(MessageCallback that) {
9597   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9598   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9599   i::HandleScope scope(isolate);
9600   i::DisallowGarbageCollection no_gc;
9601   i::TemplateList listeners = isolate->heap()->message_listeners();
9602   for (int i = 0; i < listeners.length(); i++) {
9603     if (listeners.get(i).IsUndefined(isolate)) continue;  // skip deleted ones
9604     i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9605     i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9606     if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9607       listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9608     }
9609   }
9610 }
9611 
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9612 void Isolate::SetFailedAccessCheckCallbackFunction(
9613     FailedAccessCheckCallback callback) {
9614   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9615   isolate->SetFailedAccessCheckCallback(callback);
9616 }
9617 
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9618 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9619     bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9620   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9621   isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9622                                                      options);
9623 }
9624 
VisitExternalResources(ExternalResourceVisitor * visitor)9625 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9626   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9627   isolate->heap()->VisitExternalResources(visitor);
9628 }
9629 
IsInUse()9630 bool Isolate::IsInUse() {
9631   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9632   return isolate->IsInUse();
9633 }
9634 
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9635 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9636   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9637   i::DisallowGarbageCollection no_gc;
9638   isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9639 }
9640 
VisitWeakHandles(PersistentHandleVisitor * visitor)9641 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9642   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9643   i::DisallowGarbageCollection no_gc;
9644   isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9645 }
9646 
SetAllowAtomicsWait(bool allow)9647 void Isolate::SetAllowAtomicsWait(bool allow) {
9648   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9649   isolate->set_allow_atomics_wait(allow);
9650 }
9651 
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9652 void v8::Isolate::DateTimeConfigurationChangeNotification(
9653     TimeZoneDetection time_zone_detection) {
9654   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9655   API_RCS_SCOPE(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9656   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9657   i_isolate->date_cache()->ResetDateCache(
9658       static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9659 #ifdef V8_INTL_SUPPORT
9660   i_isolate->clear_cached_icu_object(
9661       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9662   i_isolate->clear_cached_icu_object(
9663       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9664   i_isolate->clear_cached_icu_object(
9665       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9666 #endif  // V8_INTL_SUPPORT
9667 }
9668 
LocaleConfigurationChangeNotification()9669 void v8::Isolate::LocaleConfigurationChangeNotification() {
9670   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9671   API_RCS_SCOPE(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9672   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9673 
9674 #ifdef V8_INTL_SUPPORT
9675   i_isolate->ResetDefaultLocale();
9676 #endif  // V8_INTL_SUPPORT
9677 }
9678 
IsCodeLike(v8::Isolate * isolate) const9679 bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
9680   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9681   API_RCS_SCOPE(i_isolate, Object, IsCodeLike);
9682   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9683   i::HandleScope scope(i_isolate);
9684   return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9685 }
9686 
9687 // static
New(Isolate * isolate,MicrotasksPolicy policy)9688 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9689                                                     MicrotasksPolicy policy) {
9690   auto microtask_queue =
9691       i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9692   microtask_queue->set_microtasks_policy(policy);
9693   std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9694   return ret;
9695 }
9696 
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9697 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9698     : MicrotasksScope(isolate, nullptr, type) {}
9699 
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9700 MicrotasksScope::MicrotasksScope(Isolate* isolate,
9701                                  MicrotaskQueue* microtask_queue,
9702                                  MicrotasksScope::Type type)
9703     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9704       microtask_queue_(microtask_queue
9705                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9706                            : isolate_->default_microtask_queue()),
9707       run_(type == MicrotasksScope::kRunMicrotasks) {
9708   if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9709 #ifdef DEBUG
9710   if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9711 #endif
9712 }
9713 
~MicrotasksScope()9714 MicrotasksScope::~MicrotasksScope() {
9715   if (run_) {
9716     microtask_queue_->DecrementMicrotasksScopeDepth();
9717     if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9718         !isolate_->has_scheduled_exception()) {
9719       DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9720                      isolate_->scheduled_exception() ==
9721                          i::ReadOnlyRoots(isolate_).termination_exception());
9722       microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9723     }
9724   }
9725 #ifdef DEBUG
9726   if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9727 #endif
9728 }
9729 
9730 // static
PerformCheckpoint(Isolate * v8_isolate)9731 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9732   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9733   auto* microtask_queue = isolate->default_microtask_queue();
9734   microtask_queue->PerformCheckpoint(v8_isolate);
9735 }
9736 
9737 // static
GetCurrentDepth(Isolate * v8_isolate)9738 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9739   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9740   auto* microtask_queue = isolate->default_microtask_queue();
9741   return microtask_queue->GetMicrotasksScopeDepth();
9742 }
9743 
9744 // static
IsRunningMicrotasks(Isolate * v8_isolate)9745 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9746   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9747   auto* microtask_queue = isolate->default_microtask_queue();
9748   return microtask_queue->IsRunningMicrotasks();
9749 }
9750 
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9751 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9752     : str_(nullptr), length_(0) {
9753   if (obj.IsEmpty()) return;
9754   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9755   ENTER_V8_DO_NOT_USE(i_isolate);
9756   i::HandleScope scope(i_isolate);
9757   Local<Context> context = isolate->GetCurrentContext();
9758   TryCatch try_catch(isolate);
9759   Local<String> str;
9760   if (!obj->ToString(context).ToLocal(&str)) return;
9761   length_ = str->Utf8Length(isolate);
9762   str_ = i::NewArray<char>(length_ + 1);
9763   str->WriteUtf8(isolate, str_);
9764 }
9765 
~Utf8Value()9766 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9767 
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9768 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9769     : str_(nullptr), length_(0) {
9770   if (obj.IsEmpty()) return;
9771   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9772   ENTER_V8_DO_NOT_USE(i_isolate);
9773   i::HandleScope scope(i_isolate);
9774   Local<Context> context = isolate->GetCurrentContext();
9775   TryCatch try_catch(isolate);
9776   Local<String> str;
9777   if (!obj->ToString(context).ToLocal(&str)) return;
9778   length_ = str->Length();
9779   str_ = i::NewArray<uint16_t>(length_ + 1);
9780   str->Write(isolate, str_);
9781 }
9782 
~Value()9783 String::Value::~Value() { i::DeleteArray(str_); }
9784 
9785 #define DEFINE_ERROR(NAME, name)                                         \
9786   Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) {      \
9787     i::Isolate* isolate = i::Isolate::Current();                         \
9788     API_RCS_SCOPE(isolate, NAME, New);                                   \
9789     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                            \
9790     i::Object error;                                                     \
9791     {                                                                    \
9792       i::HandleScope scope(isolate);                                     \
9793       i::Handle<i::String> message = Utils::OpenHandle(*raw_message);    \
9794       i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9795       error = *isolate->factory()->NewError(constructor, message);       \
9796     }                                                                    \
9797     i::Handle<i::Object> result(error, isolate);                         \
9798     return Utils::ToLocal(result);                                       \
9799   }
9800 
DEFINE_ERROR(RangeError,range_error)9801 DEFINE_ERROR(RangeError, range_error)
9802 DEFINE_ERROR(ReferenceError, reference_error)
9803 DEFINE_ERROR(SyntaxError, syntax_error)
9804 DEFINE_ERROR(TypeError, type_error)
9805 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9806 DEFINE_ERROR(WasmLinkError, wasm_link_error)
9807 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9808 DEFINE_ERROR(Error, error)
9809 
9810 #undef DEFINE_ERROR
9811 
9812 Local<Message> Exception::CreateMessage(Isolate* isolate,
9813                                         Local<Value> exception) {
9814   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9815   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9816   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9817   i::HandleScope scope(i_isolate);
9818   return Utils::MessageToLocal(
9819       scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9820 }
9821 
GetStackTrace(Local<Value> exception)9822 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9823   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9824   if (!obj->IsJSObject()) return Local<StackTrace>();
9825   i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9826   i::Isolate* isolate = js_obj->GetIsolate();
9827   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9828   return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9829 }
9830 
PreviewEntries(bool * is_key_value)9831 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
9832   if (IsMap()) {
9833     *is_key_value = true;
9834     return Map::Cast(this)->AsArray();
9835   }
9836   if (IsSet()) {
9837     *is_key_value = false;
9838     return Set::Cast(this)->AsArray();
9839   }
9840 
9841   i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
9842   i::Isolate* isolate = object->GetIsolate();
9843   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
9844   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9845   if (object->IsJSWeakCollection()) {
9846     *is_key_value = object->IsJSWeakMap();
9847     return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9848         i::Handle<i::JSWeakCollection>::cast(object), 0));
9849   }
9850   if (object->IsJSMapIterator()) {
9851     i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
9852     MapAsArrayKind const kind =
9853         static_cast<MapAsArrayKind>(it->map().instance_type());
9854     *is_key_value = kind == MapAsArrayKind::kEntries;
9855     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9856     return Utils::ToLocal(
9857         MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9858   }
9859   if (object->IsJSSetIterator()) {
9860     i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9861     SetAsArrayKind const kind =
9862         static_cast<SetAsArrayKind>(it->map().instance_type());
9863     *is_key_value = kind == SetAsArrayKind::kEntries;
9864     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9865     return Utils::ToLocal(
9866         SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9867   }
9868   return v8::MaybeLocal<v8::Array>();
9869 }
9870 
GetFunctionName() const9871 Local<String> CpuProfileNode::GetFunctionName() const {
9872   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9873   i::Isolate* isolate = node->isolate();
9874   const i::CodeEntry* entry = node->entry();
9875   i::Handle<i::String> name =
9876       isolate->factory()->InternalizeUtf8String(entry->name());
9877   return ToApiHandle<String>(name);
9878 }
9879 
GetFunctionNameStr() const9880 const char* CpuProfileNode::GetFunctionNameStr() const {
9881   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9882   return node->entry()->name();
9883 }
9884 
GetScriptId() const9885 int CpuProfileNode::GetScriptId() const {
9886   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9887   const i::CodeEntry* entry = node->entry();
9888   return entry->script_id();
9889 }
9890 
GetScriptResourceName() const9891 Local<String> CpuProfileNode::GetScriptResourceName() const {
9892   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9893   i::Isolate* isolate = node->isolate();
9894   return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9895       node->entry()->resource_name()));
9896 }
9897 
GetScriptResourceNameStr() const9898 const char* CpuProfileNode::GetScriptResourceNameStr() const {
9899   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9900   return node->entry()->resource_name();
9901 }
9902 
IsScriptSharedCrossOrigin() const9903 bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9904   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9905   return node->entry()->is_shared_cross_origin();
9906 }
9907 
GetLineNumber() const9908 int CpuProfileNode::GetLineNumber() const {
9909   return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9910 }
9911 
GetColumnNumber() const9912 int CpuProfileNode::GetColumnNumber() const {
9913   return reinterpret_cast<const i::ProfileNode*>(this)
9914       ->entry()
9915       ->column_number();
9916 }
9917 
GetHitLineCount() const9918 unsigned int CpuProfileNode::GetHitLineCount() const {
9919   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9920   return node->GetHitLineCount();
9921 }
9922 
GetLineTicks(LineTick * entries,unsigned int length) const9923 bool CpuProfileNode::GetLineTicks(LineTick* entries,
9924                                   unsigned int length) const {
9925   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9926   return node->GetLineTicks(entries, length);
9927 }
9928 
GetBailoutReason() const9929 const char* CpuProfileNode::GetBailoutReason() const {
9930   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9931   return node->entry()->bailout_reason();
9932 }
9933 
GetHitCount() const9934 unsigned CpuProfileNode::GetHitCount() const {
9935   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9936 }
9937 
GetNodeId() const9938 unsigned CpuProfileNode::GetNodeId() const {
9939   return reinterpret_cast<const i::ProfileNode*>(this)->id();
9940 }
9941 
GetSourceType() const9942 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9943   return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9944 }
9945 
GetChildrenCount() const9946 int CpuProfileNode::GetChildrenCount() const {
9947   return static_cast<int>(
9948       reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9949 }
9950 
GetChild(int index) const9951 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9952   const i::ProfileNode* child =
9953       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9954   return reinterpret_cast<const CpuProfileNode*>(child);
9955 }
9956 
GetParent() const9957 const CpuProfileNode* CpuProfileNode::GetParent() const {
9958   const i::ProfileNode* parent =
9959       reinterpret_cast<const i::ProfileNode*>(this)->parent();
9960   return reinterpret_cast<const CpuProfileNode*>(parent);
9961 }
9962 
GetDeoptInfos() const9963 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9964   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9965   return node->deopt_infos();
9966 }
9967 
Delete()9968 void CpuProfile::Delete() {
9969   i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9970   i::CpuProfiler* profiler = profile->cpu_profiler();
9971   DCHECK_NOT_NULL(profiler);
9972   profiler->DeleteProfile(profile);
9973 }
9974 
GetTitle() const9975 Local<String> CpuProfile::GetTitle() const {
9976   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9977   i::Isolate* isolate = profile->top_down()->isolate();
9978   return ToApiHandle<String>(
9979       isolate->factory()->InternalizeUtf8String(profile->title()));
9980 }
9981 
GetTopDownRoot() const9982 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9983   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9984   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9985 }
9986 
GetSample(int index) const9987 const CpuProfileNode* CpuProfile::GetSample(int index) const {
9988   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9989   return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
9990 }
9991 
9992 const int CpuProfileNode::kNoLineNumberInfo;
9993 const int CpuProfileNode::kNoColumnNumberInfo;
9994 
GetSampleTimestamp(int index) const9995 int64_t CpuProfile::GetSampleTimestamp(int index) const {
9996   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9997   return profile->sample(index).timestamp.since_origin().InMicroseconds();
9998 }
9999 
GetSampleState(int index) const10000 StateTag CpuProfile::GetSampleState(int index) const {
10001   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10002   return profile->sample(index).state_tag;
10003 }
10004 
GetSampleEmbedderState(int index) const10005 EmbedderStateTag CpuProfile::GetSampleEmbedderState(int index) const {
10006   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10007   return profile->sample(index).embedder_state_tag;
10008 }
10009 
GetStartTime() const10010 int64_t CpuProfile::GetStartTime() const {
10011   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10012   return profile->start_time().since_origin().InMicroseconds();
10013 }
10014 
GetEndTime() const10015 int64_t CpuProfile::GetEndTime() const {
10016   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10017   return profile->end_time().since_origin().InMicroseconds();
10018 }
10019 
ToInternal(const CpuProfile * profile)10020 static i::CpuProfile* ToInternal(const CpuProfile* profile) {
10021   return const_cast<i::CpuProfile*>(
10022       reinterpret_cast<const i::CpuProfile*>(profile));
10023 }
10024 
Serialize(OutputStream * stream,CpuProfile::SerializationFormat format) const10025 void CpuProfile::Serialize(OutputStream* stream,
10026                            CpuProfile::SerializationFormat format) const {
10027   Utils::ApiCheck(format == kJSON, "v8::CpuProfile::Serialize",
10028                   "Unknown serialization format");
10029   Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::CpuProfile::Serialize",
10030                   "Invalid stream chunk size");
10031   i::CpuProfileJSONSerializer serializer(ToInternal(this));
10032   serializer.Serialize(stream);
10033 }
10034 
GetSamplesCount() const10035 int CpuProfile::GetSamplesCount() const {
10036   return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
10037 }
10038 
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)10039 CpuProfiler* CpuProfiler::New(Isolate* isolate,
10040                               CpuProfilingNamingMode naming_mode,
10041                               CpuProfilingLoggingMode logging_mode) {
10042   return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
10043       reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
10044 }
10045 
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)10046 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
10047                                          unsigned max_samples,
10048                                          int sampling_interval_us,
10049                                          MaybeLocal<Context> filter_context)
10050     : mode_(mode),
10051       max_samples_(max_samples),
10052       sampling_interval_us_(sampling_interval_us) {
10053   if (!filter_context.IsEmpty()) {
10054     Local<Context> local_filter_context = filter_context.ToLocalChecked();
10055     filter_context_.Reset(local_filter_context->GetIsolate(),
10056                           local_filter_context);
10057     filter_context_.SetWeak();
10058   }
10059 }
10060 
raw_filter_context() const10061 void* CpuProfilingOptions::raw_filter_context() const {
10062   return reinterpret_cast<void*>(
10063       i::Context::cast(*Utils::OpenPersistent(filter_context_))
10064           .native_context()
10065           .address());
10066 }
10067 
Dispose()10068 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
10069 
10070 // static
CollectSample(Isolate * isolate)10071 void CpuProfiler::CollectSample(Isolate* isolate) {
10072   i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
10073 }
10074 
SetSamplingInterval(int us)10075 void CpuProfiler::SetSamplingInterval(int us) {
10076   DCHECK_GE(us, 0);
10077   return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
10078       base::TimeDelta::FromMicroseconds(us));
10079 }
10080 
SetUsePreciseSampling(bool use_precise_sampling)10081 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
10082   reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
10083       use_precise_sampling);
10084 }
10085 
Start(CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)10086 CpuProfilingResult CpuProfiler::Start(
10087     CpuProfilingOptions options,
10088     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
10089   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10090       options, std::move(delegate));
10091 }
10092 
Start(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)10093 CpuProfilingResult CpuProfiler::Start(
10094     Local<String> title, CpuProfilingOptions options,
10095     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
10096   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10097       *Utils::OpenHandle(*title), options, std::move(delegate));
10098 }
10099 
Start(Local<String> title,bool record_samples)10100 CpuProfilingResult CpuProfiler::Start(Local<String> title,
10101                                       bool record_samples) {
10102   CpuProfilingOptions options(
10103       kLeafNodeLineNumbers,
10104       record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
10105   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10106       *Utils::OpenHandle(*title), options);
10107 }
10108 
Start(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)10109 CpuProfilingResult CpuProfiler::Start(Local<String> title,
10110                                       CpuProfilingMode mode,
10111                                       bool record_samples,
10112                                       unsigned max_samples) {
10113   CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
10114   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10115       *Utils::OpenHandle(*title), options);
10116 }
10117 
StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)10118 CpuProfilingStatus CpuProfiler::StartProfiling(
10119     Local<String> title, CpuProfilingOptions options,
10120     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
10121   return Start(title, options, std::move(delegate)).status;
10122 }
10123 
StartProfiling(Local<String> title,bool record_samples)10124 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10125                                                bool record_samples) {
10126   return Start(title, record_samples).status;
10127 }
10128 
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)10129 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10130                                                CpuProfilingMode mode,
10131                                                bool record_samples,
10132                                                unsigned max_samples) {
10133   return Start(title, mode, record_samples, max_samples).status;
10134 }
10135 
StopProfiling(Local<String> title)10136 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
10137   return reinterpret_cast<CpuProfile*>(
10138       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
10139           *Utils::OpenHandle(*title)));
10140 }
10141 
Stop(ProfilerId id)10142 CpuProfile* CpuProfiler::Stop(ProfilerId id) {
10143   return reinterpret_cast<CpuProfile*>(
10144       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id));
10145 }
10146 
UseDetailedSourcePositionsForProfiling(Isolate * isolate)10147 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
10148   reinterpret_cast<i::Isolate*>(isolate)
10149       ->SetDetailedSourcePositionsForProfiling(true);
10150 }
10151 
GetCodeStartAddress()10152 uintptr_t CodeEvent::GetCodeStartAddress() {
10153   return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10154 }
10155 
GetCodeSize()10156 size_t CodeEvent::GetCodeSize() {
10157   return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10158 }
10159 
GetFunctionName()10160 Local<String> CodeEvent::GetFunctionName() {
10161   return ToApiHandle<String>(
10162       reinterpret_cast<i::CodeEvent*>(this)->function_name);
10163 }
10164 
GetScriptName()10165 Local<String> CodeEvent::GetScriptName() {
10166   return ToApiHandle<String>(
10167       reinterpret_cast<i::CodeEvent*>(this)->script_name);
10168 }
10169 
GetScriptLine()10170 int CodeEvent::GetScriptLine() {
10171   return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10172 }
10173 
GetScriptColumn()10174 int CodeEvent::GetScriptColumn() {
10175   return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10176 }
10177 
GetCodeType()10178 CodeEventType CodeEvent::GetCodeType() {
10179   return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10180 }
10181 
GetComment()10182 const char* CodeEvent::GetComment() {
10183   return reinterpret_cast<i::CodeEvent*>(this)->comment;
10184 }
10185 
GetPreviousCodeStartAddress()10186 uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10187   return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10188 }
10189 
GetCodeEventTypeName(CodeEventType code_event_type)10190 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
10191   switch (code_event_type) {
10192     case kUnknownType:
10193       return "Unknown";
10194 #define V(Name)       \
10195   case k##Name##Type: \
10196     return #Name;
10197       CODE_EVENTS_LIST(V)
10198 #undef V
10199   }
10200   // The execution should never pass here
10201   UNREACHABLE();
10202 }
10203 
CodeEventHandler(Isolate * isolate)10204 CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10205   internal_listener_ =
10206       new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10207 }
10208 
~CodeEventHandler()10209 CodeEventHandler::~CodeEventHandler() {
10210   delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10211 }
10212 
Enable()10213 void CodeEventHandler::Enable() {
10214   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10215       ->StartListening(this);
10216 }
10217 
Disable()10218 void CodeEventHandler::Disable() {
10219   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10220       ->StopListening();
10221 }
10222 
ToInternal(const HeapGraphEdge * edge)10223 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10224   return const_cast<i::HeapGraphEdge*>(
10225       reinterpret_cast<const i::HeapGraphEdge*>(edge));
10226 }
10227 
GetType() const10228 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10229   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10230 }
10231 
GetName() const10232 Local<Value> HeapGraphEdge::GetName() const {
10233   i::HeapGraphEdge* edge = ToInternal(this);
10234   i::Isolate* isolate = edge->isolate();
10235   switch (edge->type()) {
10236     case i::HeapGraphEdge::kContextVariable:
10237     case i::HeapGraphEdge::kInternal:
10238     case i::HeapGraphEdge::kProperty:
10239     case i::HeapGraphEdge::kShortcut:
10240     case i::HeapGraphEdge::kWeak:
10241       return ToApiHandle<String>(
10242           isolate->factory()->InternalizeUtf8String(edge->name()));
10243     case i::HeapGraphEdge::kElement:
10244     case i::HeapGraphEdge::kHidden:
10245       return ToApiHandle<Number>(
10246           isolate->factory()->NewNumberFromInt(edge->index()));
10247     default:
10248       UNREACHABLE();
10249   }
10250 }
10251 
GetFromNode() const10252 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10253   const i::HeapEntry* from = ToInternal(this)->from();
10254   return reinterpret_cast<const HeapGraphNode*>(from);
10255 }
10256 
GetToNode() const10257 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10258   const i::HeapEntry* to = ToInternal(this)->to();
10259   return reinterpret_cast<const HeapGraphNode*>(to);
10260 }
10261 
ToInternal(const HeapGraphNode * entry)10262 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10263   return const_cast<i::HeapEntry*>(
10264       reinterpret_cast<const i::HeapEntry*>(entry));
10265 }
10266 
GetType() const10267 HeapGraphNode::Type HeapGraphNode::GetType() const {
10268   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10269 }
10270 
GetName() const10271 Local<String> HeapGraphNode::GetName() const {
10272   i::Isolate* isolate = ToInternal(this)->isolate();
10273   return ToApiHandle<String>(
10274       isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10275 }
10276 
GetId() const10277 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10278 
GetShallowSize() const10279 size_t HeapGraphNode::GetShallowSize() const {
10280   return ToInternal(this)->self_size();
10281 }
10282 
GetChildrenCount() const10283 int HeapGraphNode::GetChildrenCount() const {
10284   return ToInternal(this)->children_count();
10285 }
10286 
GetChild(int index) const10287 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10288   return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10289 }
10290 
ToInternal(const HeapSnapshot * snapshot)10291 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10292   return const_cast<i::HeapSnapshot*>(
10293       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10294 }
10295 
Delete()10296 void HeapSnapshot::Delete() {
10297   i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10298   if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
10299       isolate->heap_profiler()->IsTakingSnapshot()) {
10300     ToInternal(this)->Delete();
10301   } else {
10302     // If this is the last snapshot, clean up all accessory data as well.
10303     isolate->heap_profiler()->DeleteAllSnapshots();
10304   }
10305 }
10306 
GetRoot() const10307 const HeapGraphNode* HeapSnapshot::GetRoot() const {
10308   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10309 }
10310 
GetNodeById(SnapshotObjectId id) const10311 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10312   return reinterpret_cast<const HeapGraphNode*>(
10313       ToInternal(this)->GetEntryById(id));
10314 }
10315 
GetNodesCount() const10316 int HeapSnapshot::GetNodesCount() const {
10317   return static_cast<int>(ToInternal(this)->entries().size());
10318 }
10319 
GetNode(int index) const10320 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10321   return reinterpret_cast<const HeapGraphNode*>(
10322       &ToInternal(this)->entries().at(index));
10323 }
10324 
GetMaxSnapshotJSObjectId() const10325 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10326   return ToInternal(this)->max_snapshot_js_object_id();
10327 }
10328 
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10329 void HeapSnapshot::Serialize(OutputStream* stream,
10330                              HeapSnapshot::SerializationFormat format) const {
10331   Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
10332                   "Unknown serialization format");
10333   Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
10334                   "Invalid stream chunk size");
10335   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10336   serializer.Serialize(stream);
10337 }
10338 
10339 // static
10340 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10341     HeapProfiler::kUnknownObjectId;
10342 
GetSnapshotCount()10343 int HeapProfiler::GetSnapshotCount() {
10344   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10345 }
10346 
GetHeapSnapshot(int index)10347 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10348   return reinterpret_cast<const HeapSnapshot*>(
10349       reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10350 }
10351 
GetObjectId(Local<Value> value)10352 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10353   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10354   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10355 }
10356 
GetObjectId(NativeObject value)10357 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10358   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10359 }
10360 
FindObjectById(SnapshotObjectId id)10361 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10362   i::Handle<i::Object> obj =
10363       reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10364   if (obj.is_null()) return Local<Value>();
10365   return Utils::ToLocal(obj);
10366 }
10367 
ClearObjectIds()10368 void HeapProfiler::ClearObjectIds() {
10369   reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10370 }
10371 
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)10372 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
10373     ActivityControl* control, ObjectNameResolver* resolver,
10374     bool treat_global_objects_as_roots, bool capture_numeric_value) {
10375   return reinterpret_cast<const HeapSnapshot*>(
10376       reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
10377           control, resolver, treat_global_objects_as_roots,
10378           capture_numeric_value));
10379 }
10380 
StartTrackingHeapObjects(bool track_allocations)10381 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10382   reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10383       track_allocations);
10384 }
10385 
StopTrackingHeapObjects()10386 void HeapProfiler::StopTrackingHeapObjects() {
10387   reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10388 }
10389 
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)10390 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
10391                                             int64_t* timestamp_us) {
10392   i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
10393   return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
10394 }
10395 
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)10396 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
10397                                              int stack_depth,
10398                                              SamplingFlags flags) {
10399   return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
10400       sample_interval, stack_depth, flags);
10401 }
10402 
StopSamplingHeapProfiler()10403 void HeapProfiler::StopSamplingHeapProfiler() {
10404   reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10405 }
10406 
GetAllocationProfile()10407 AllocationProfile* HeapProfiler::GetAllocationProfile() {
10408   return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10409 }
10410 
DeleteAllHeapSnapshots()10411 void HeapProfiler::DeleteAllHeapSnapshots() {
10412   reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10413 }
10414 
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10415 void HeapProfiler::AddBuildEmbedderGraphCallback(
10416     BuildEmbedderGraphCallback callback, void* data) {
10417   reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10418       callback, data);
10419 }
10420 
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10421 void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10422     BuildEmbedderGraphCallback callback, void* data) {
10423   reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10424       callback, data);
10425 }
10426 
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10427 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10428                                               void* data) {
10429   reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10430                                                                        data);
10431 }
10432 
SetStackStart(void * stack_start)10433 void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10434   CHECK(isolate_);
10435   reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10436       stack_start);
10437 }
10438 
FinalizeTracing()10439 void EmbedderHeapTracer::FinalizeTracing() {
10440   if (isolate_) {
10441     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10442     if (isolate->heap()->incremental_marking()->IsMarking()) {
10443       isolate->heap()->FinalizeIncrementalMarkingAtomically(
10444           i::GarbageCollectionReason::kExternalFinalize);
10445     }
10446   }
10447 }
10448 
IncreaseAllocatedSize(size_t bytes)10449 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
10450   if (isolate_) {
10451     i::LocalEmbedderHeapTracer* const tracer =
10452         reinterpret_cast<i::Isolate*>(isolate_)
10453             ->heap()
10454             ->local_embedder_heap_tracer();
10455     DCHECK_NOT_NULL(tracer);
10456     tracer->IncreaseAllocatedSize(bytes);
10457   }
10458 }
10459 
DecreaseAllocatedSize(size_t bytes)10460 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
10461   if (isolate_) {
10462     i::LocalEmbedderHeapTracer* const tracer =
10463         reinterpret_cast<i::Isolate*>(isolate_)
10464             ->heap()
10465             ->local_embedder_heap_tracer();
10466     DCHECK_NOT_NULL(tracer);
10467     tracer->DecreaseAllocatedSize(bytes);
10468   }
10469 }
10470 
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10471 void EmbedderHeapTracer::RegisterEmbedderReference(
10472     const BasicTracedReference<v8::Data>& ref) {
10473   if (ref.IsEmpty()) return;
10474 
10475   i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10476   heap->RegisterExternallyReferencedObject(
10477       reinterpret_cast<i::Address*>(ref.val_));
10478 }
10479 
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10480 void EmbedderHeapTracer::IterateTracedGlobalHandles(
10481     TracedGlobalHandleVisitor* visitor) {
10482   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10483   i::DisallowGarbageCollection no_gc;
10484   isolate->global_handles()->IterateTracedNodes(visitor);
10485 }
10486 
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10487 bool EmbedderHeapTracer::IsRootForNonTracingGC(
10488     const v8::TracedReference<v8::Value>& handle) {
10489   return true;
10490 }
10491 
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10492 void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10493     const v8::TracedReference<v8::Value>& handle) {
10494   UNREACHABLE();
10495 }
10496 
EmbedderStateScope(Isolate * isolate,Local<v8::Context> context,EmbedderStateTag tag)10497 EmbedderStateScope::EmbedderStateScope(Isolate* isolate,
10498                                        Local<v8::Context> context,
10499                                        EmbedderStateTag tag)
10500     : embedder_state_(new internal::EmbedderState(isolate, context, tag)) {}
10501 
10502 // std::unique_ptr's destructor is not compatible with Forward declared
10503 // EmbedderState class.
10504 // Default destructor must be defined in implementation file.
10505 EmbedderStateScope::~EmbedderStateScope() = default;
10506 
CheckValue() const10507 void TracedReferenceBase::CheckValue() const {
10508 #ifdef V8_HOST_ARCH_64_BIT
10509   if (!val_) return;
10510 
10511   CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_));
10512 #endif  // V8_HOST_ARCH_64_BIT
10513 }
10514 
CFunction(const void * address,const CFunctionInfo * type_info)10515 CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
10516     : address_(address), type_info_(type_info) {
10517   CHECK_NOT_NULL(address_);
10518   CHECK_NOT_NULL(type_info_);
10519 }
10520 
CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10521 CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info,
10522                              unsigned int arg_count, const CTypeInfo* arg_info)
10523     : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) {
10524   if (arg_count_ > 0) {
10525     for (unsigned int i = 0; i < arg_count_ - 1; ++i) {
10526       DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType);
10527     }
10528   }
10529 }
10530 
ArgumentInfo(unsigned int index) const10531 const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10532   DCHECK_LT(index, ArgumentCount());
10533   return arg_info_[index];
10534 }
10535 
ValidateIndex(size_t index) const10536 void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10537   DCHECK_LT(index, length_);
10538 }
10539 
RegisterState()10540 RegisterState::RegisterState()
10541     : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10542 RegisterState::~RegisterState() = default;
10543 
RegisterState(const RegisterState & other)10544 RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10545 
operator =(const RegisterState & other)10546 RegisterState& RegisterState::operator=(const RegisterState& other) {
10547   if (&other != this) {
10548     pc = other.pc;
10549     sp = other.sp;
10550     fp = other.fp;
10551     lr = other.lr;
10552     if (other.callee_saved) {
10553       // Make a deep copy if {other.callee_saved} is non-null.
10554       callee_saved =
10555           std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
10556     } else {
10557       // Otherwise, set {callee_saved} to null to match {other}.
10558       callee_saved.reset();
10559     }
10560   }
10561   return *this;
10562 }
10563 
10564 #if !V8_ENABLE_WEBASSEMBLY
10565 // If WebAssembly is disabled, we still need to provide an implementation of the
10566 // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all
10567 // methods are unreachable.
10568 
10569 class WasmStreaming::WasmStreamingImpl {};
10570 
WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10571 WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10572   UNREACHABLE();
10573 }
10574 
10575 WasmStreaming::~WasmStreaming() = default;
10576 
OnBytesReceived(const uint8_t * bytes,size_t size)10577 void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10578   UNREACHABLE();
10579 }
10580 
Finish(bool can_use_compiled_module)10581 void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); }
10582 
Abort(MaybeLocal<Value> exception)10583 void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10584 
SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10585 bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10586   UNREACHABLE();
10587 }
10588 
SetClient(std::shared_ptr<Client> client)10589 void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10590 
SetUrl(const char * url,size_t length)10591 void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10592 
10593 // static
Unpack(Isolate * isolate,Local<Value> value)10594 std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10595                                                      Local<Value> value) {
10596   FATAL("WebAssembly is disabled");
10597 }
10598 #endif  // !V8_ENABLE_WEBASSEMBLY
10599 
10600 namespace internal {
10601 
10602 const size_t HandleScopeImplementer::kEnteredContextsOffset =
10603     offsetof(HandleScopeImplementer, entered_contexts_);
10604 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10605     offsetof(HandleScopeImplementer, is_microtask_context_);
10606 
FreeThreadResources()10607 void HandleScopeImplementer::FreeThreadResources() { Free(); }
10608 
ArchiveThread(char * storage)10609 char* HandleScopeImplementer::ArchiveThread(char* storage) {
10610   HandleScopeData* current = isolate_->handle_scope_data();
10611   handle_scope_data_ = *current;
10612   MemCopy(storage, this, sizeof(*this));
10613 
10614   ResetAfterArchive();
10615   current->Initialize();
10616 
10617   return storage + ArchiveSpacePerThread();
10618 }
10619 
ArchiveSpacePerThread()10620 int HandleScopeImplementer::ArchiveSpacePerThread() {
10621   return sizeof(HandleScopeImplementer);
10622 }
10623 
RestoreThread(char * storage)10624 char* HandleScopeImplementer::RestoreThread(char* storage) {
10625   MemCopy(this, storage, sizeof(*this));
10626   *isolate_->handle_scope_data() = handle_scope_data_;
10627   return storage + ArchiveSpacePerThread();
10628 }
10629 
IterateThis(RootVisitor * v)10630 void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10631 #ifdef DEBUG
10632   bool found_block_before_deferred = false;
10633 #endif
10634   // Iterate over all handles in the blocks except for the last.
10635   for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10636     Address* block = blocks()->at(i);
10637     // Cast possibly-unrelated pointers to plain Address before comparing them
10638     // to avoid undefined behavior.
10639     if (last_handle_before_deferred_block_ != nullptr &&
10640         (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
10641          reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
10642         (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
10643          reinterpret_cast<Address>(block))) {
10644       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10645                            FullObjectSlot(last_handle_before_deferred_block_));
10646       DCHECK(!found_block_before_deferred);
10647 #ifdef DEBUG
10648       found_block_before_deferred = true;
10649 #endif
10650     } else {
10651       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10652                            FullObjectSlot(&block[kHandleBlockSize]));
10653     }
10654   }
10655 
10656   DCHECK(last_handle_before_deferred_block_ == nullptr ||
10657          found_block_before_deferred);
10658 
10659   // Iterate over live handles in the last block (if any).
10660   if (!blocks()->empty()) {
10661     v->VisitRootPointers(Root::kHandleScope, nullptr,
10662                          FullObjectSlot(blocks()->back()),
10663                          FullObjectSlot(handle_scope_data_.next));
10664   }
10665 
10666   DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
10667                                                  &entered_contexts_};
10668   for (unsigned i = 0; i < arraysize(context_lists); i++) {
10669     context_lists[i]->shrink_to_fit();
10670     if (context_lists[i]->empty()) continue;
10671     FullObjectSlot start(&context_lists[i]->front());
10672     v->VisitRootPointers(Root::kHandleScope, nullptr, start,
10673                          start + static_cast<int>(context_lists[i]->size()));
10674   }
10675   // The shape of |entered_contexts_| and |is_microtask_context_| stacks must
10676   // be in sync.
10677   is_microtask_context_.shrink_to_fit();
10678   DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
10679   DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
10680 }
10681 
Iterate(RootVisitor * v)10682 void HandleScopeImplementer::Iterate(RootVisitor* v) {
10683   HandleScopeData* current = isolate_->handle_scope_data();
10684   handle_scope_data_ = *current;
10685   IterateThis(v);
10686 }
10687 
Iterate(RootVisitor * v,char * storage)10688 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10689   HandleScopeImplementer* scope_implementer =
10690       reinterpret_cast<HandleScopeImplementer*>(storage);
10691   scope_implementer->IterateThis(v);
10692   return storage + ArchiveSpacePerThread();
10693 }
10694 
DetachPersistent(Address * prev_limit)10695 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
10696     Address* prev_limit) {
10697   std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
10698   DCHECK_NOT_NULL(prev_limit);
10699 
10700   while (!blocks_.empty()) {
10701     Address* block_start = blocks_.back();
10702     Address* block_limit = &block_start[kHandleBlockSize];
10703     // We should not need to check for SealHandleScope here. Assert this.
10704     DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
10705                    prev_limit == block_limit);
10706     if (prev_limit == block_limit) break;
10707     ph->blocks_.push_back(blocks_.back());
10708 #if DEBUG
10709     ph->ordered_blocks_.insert(blocks_.back());
10710 #endif
10711     blocks_.pop_back();
10712   }
10713 
10714   // ph->blocks_ now contains the blocks installed on the
10715   // HandleScope stack since BeginDeferredScope was called, but in
10716   // reverse order.
10717 
10718   // Switch first and last blocks, such that the last block is the one
10719   // that is potentially half full.
10720   DCHECK(!blocks_.empty() && !ph->blocks_.empty());
10721   std::swap(ph->blocks_.front(), ph->blocks_.back());
10722 
10723   ph->block_next_ = isolate()->handle_scope_data()->next;
10724   Address* block_start = ph->blocks_.back();
10725   ph->block_limit_ = block_start + kHandleBlockSize;
10726 
10727   DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10728   last_handle_before_deferred_block_ = nullptr;
10729   return ph;
10730 }
10731 
BeginDeferredScope()10732 void HandleScopeImplementer::BeginDeferredScope() {
10733   DCHECK_NULL(last_handle_before_deferred_block_);
10734   last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10735 }
10736 
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10737 void InvokeAccessorGetterCallback(
10738     v8::Local<v8::Name> property,
10739     const v8::PropertyCallbackInfo<v8::Value>& info,
10740     v8::AccessorNameGetterCallback getter) {
10741   // Leaving JavaScript.
10742   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10743   RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
10744   Address getter_address = reinterpret_cast<Address>(getter);
10745   ExternalCallbackScope call_scope(isolate, getter_address);
10746   getter(property, info);
10747 }
10748 
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10749 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10750                             v8::FunctionCallback callback) {
10751   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10752   RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
10753   Address callback_address = reinterpret_cast<Address>(callback);
10754   ExternalCallbackScope call_scope(isolate, callback_address);
10755   callback(info);
10756 }
10757 
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10758 void InvokeFinalizationRegistryCleanupFromTask(
10759     Handle<Context> context,
10760     Handle<JSFinalizationRegistry> finalization_registry,
10761     Handle<Object> callback) {
10762   Isolate* isolate = finalization_registry->native_context().GetIsolate();
10763   RCS_SCOPE(isolate,
10764             RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
10765   // Do not use ENTER_V8 because this is always called from a running
10766   // FinalizationRegistryCleanupTask within V8 and we should not log it as an
10767   // API call. This method is implemented here to avoid duplication of the
10768   // exception handling and microtask running logic in CallDepthScope.
10769   if (IsExecutionTerminatingCheck(isolate)) return;
10770   Local<v8::Context> api_context = Utils::ToLocal(context);
10771   CallDepthScope<true> call_depth_scope(isolate, api_context);
10772   VMState<OTHER> state(isolate);
10773   Handle<Object> argv[] = {callback};
10774   if (Execution::CallBuiltin(isolate,
10775                              isolate->finalization_registry_cleanup_some(),
10776                              finalization_registry, arraysize(argv), argv)
10777           .is_null()) {
10778     call_depth_scope.Escape();
10779   }
10780 }
10781 
10782 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10783 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10784 int32_t ConvertDouble(double d) {
10785   return internal::DoubleToInt32(d);
10786 }
10787 
10788 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10789 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10790 uint32_t ConvertDouble(double d) {
10791   return internal::DoubleToUint32(d);
10792 }
10793 
10794 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10795 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10796 float ConvertDouble(double d) {
10797   return internal::DoubleToFloat32(d);
10798 }
10799 
10800 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10801 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10802 double ConvertDouble(double d) {
10803   return d;
10804 }
10805 
10806 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10807 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10808 int64_t ConvertDouble(double d) {
10809   return internal::DoubleToWebIDLInt64(d);
10810 }
10811 
10812 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10813 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10814 uint64_t ConvertDouble(double d) {
10815   return internal::DoubleToWebIDLUint64(d);
10816 }
10817 
10818 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10819 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10820 bool ConvertDouble(double d) {
10821   // Implements https://tc39.es/ecma262/#sec-toboolean.
10822   return !std::isnan(d) && d != 0;
10823 }
10824 
10825 // Undefine macros for jumbo build.
10826 #undef SET_FIELD_WRAPPED
10827 #undef NEW_STRING
10828 #undef CALLBACK_SETTER
10829 
10830 }  // namespace internal
10831 
10832 template <>
10833 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10834 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
10835                                     int32_t>(Local<Array> src, int32_t* dst,
10836                                              uint32_t max_length) {
10837   return CopyAndConvertArrayToCppBuffer<
10838       CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence)
10839           .GetId(),
10840       int32_t>(src, dst, max_length);
10841 }
10842 
10843 template <>
10844 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10845 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
10846                                     uint32_t>(Local<Array> src, uint32_t* dst,
10847                                               uint32_t max_length) {
10848   return CopyAndConvertArrayToCppBuffer<
10849       CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence)
10850           .GetId(),
10851       uint32_t>(src, dst, max_length);
10852 }
10853 
10854 template <>
10855 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10856 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
10857                                     float>(Local<Array> src, float* dst,
10858                                            uint32_t max_length) {
10859   return CopyAndConvertArrayToCppBuffer<
10860       CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence)
10861           .GetId(),
10862       float>(src, dst, max_length);
10863 }
10864 
10865 template <>
10866 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10867 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
10868                                     double>(Local<Array> src, double* dst,
10869                                             uint32_t max_length) {
10870   return CopyAndConvertArrayToCppBuffer<
10871       CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence)
10872           .GetId(),
10873       double>(src, dst, max_length);
10874 }
10875 
10876 }  // namespace v8
10877 
10878 #undef TRACE_BS
10879 #include "src/api/api-macros-undef.h"
10880