• 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::__anon4d9620be0111::SnapshotCreatorData435   explicit SnapshotCreatorData(Isolate* isolate)
436       : isolate_(isolate),
437         default_context_(),
438         contexts_(isolate),
439         created_(false) {}
440 
castv8::__anon4d9620be0111::SnapshotCreatorData441   static SnapshotCreatorData* cast(void* data) {
442     return reinterpret_cast<SnapshotCreatorData*>(data);
443   }
444 
445   ArrayBufferAllocator allocator_;
446   Isolate* isolate_;
447   Persistent<Context> default_context_;
448   SerializeInternalFieldsCallback default_embedder_fields_serializer_;
449   PersistentValueVector<Context> contexts_;
450   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
451   bool created_;
452 };
453 
454 }  // namespace
455 
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)456 SnapshotCreator::SnapshotCreator(Isolate* isolate,
457                                  const intptr_t* external_references,
458                                  StartupData* existing_snapshot) {
459   SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
460   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
461   internal_isolate->set_array_buffer_allocator(&data->allocator_);
462   internal_isolate->set_api_external_references(external_references);
463   internal_isolate->enable_serializer();
464   isolate->Enter();
465   const StartupData* blob = existing_snapshot
466                                 ? existing_snapshot
467                                 : i::Snapshot::DefaultSnapshotBlob();
468   if (blob && blob->raw_size > 0) {
469     internal_isolate->set_snapshot_blob(blob);
470     i::Snapshot::Initialize(internal_isolate);
471   } else {
472     internal_isolate->InitWithoutSnapshot();
473   }
474   data_ = data;
475   // Disable batch compilation during snapshot creation.
476   internal_isolate->baseline_batch_compiler()->set_enabled(false);
477 }
478 
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)479 SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
480                                  StartupData* existing_snapshot)
481     : SnapshotCreator(Isolate::Allocate(), external_references,
482                       existing_snapshot) {}
483 
~SnapshotCreator()484 SnapshotCreator::~SnapshotCreator() {
485   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
486   Isolate* isolate = data->isolate_;
487   isolate->Exit();
488   isolate->Dispose();
489   delete data;
490 }
491 
GetIsolate()492 Isolate* SnapshotCreator::GetIsolate() {
493   return SnapshotCreatorData::cast(data_)->isolate_;
494 }
495 
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)496 void SnapshotCreator::SetDefaultContext(
497     Local<Context> context, SerializeInternalFieldsCallback callback) {
498   DCHECK(!context.IsEmpty());
499   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
500   DCHECK(!data->created_);
501   DCHECK(data->default_context_.IsEmpty());
502   Isolate* isolate = data->isolate_;
503   CHECK_EQ(isolate, context->GetIsolate());
504   data->default_context_.Reset(isolate, context);
505   data->default_embedder_fields_serializer_ = callback;
506 }
507 
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)508 size_t SnapshotCreator::AddContext(Local<Context> context,
509                                    SerializeInternalFieldsCallback callback) {
510   DCHECK(!context.IsEmpty());
511   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
512   DCHECK(!data->created_);
513   Isolate* isolate = data->isolate_;
514   CHECK_EQ(isolate, context->GetIsolate());
515   size_t index = data->contexts_.Size();
516   data->contexts_.Append(context);
517   data->embedder_fields_serializers_.push_back(callback);
518   return index;
519 }
520 
AddData(i::Address object)521 size_t SnapshotCreator::AddData(i::Address object) {
522   DCHECK_NE(object, i::kNullAddress);
523   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
524   DCHECK(!data->created_);
525   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
526   i::HandleScope scope(isolate);
527   i::Handle<i::Object> obj(i::Object(object), isolate);
528   i::Handle<i::ArrayList> list;
529   if (!isolate->heap()->serialized_objects().IsArrayList()) {
530     list = i::ArrayList::New(isolate, 1);
531   } else {
532     list = i::Handle<i::ArrayList>(
533         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
534   }
535   size_t index = static_cast<size_t>(list->Length());
536   list = i::ArrayList::Add(isolate, list, obj);
537   isolate->heap()->SetSerializedObjects(*list);
538   return index;
539 }
540 
AddData(Local<Context> context,i::Address object)541 size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
542   DCHECK_NE(object, i::kNullAddress);
543   DCHECK(!SnapshotCreatorData::cast(data_)->created_);
544   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
545   i::Isolate* isolate = ctx->GetIsolate();
546   i::HandleScope scope(isolate);
547   i::Handle<i::Object> obj(i::Object(object), isolate);
548   i::Handle<i::ArrayList> list;
549   if (!ctx->serialized_objects().IsArrayList()) {
550     list = i::ArrayList::New(isolate, 1);
551   } else {
552     list = i::Handle<i::ArrayList>(
553         i::ArrayList::cast(ctx->serialized_objects()), isolate);
554   }
555   size_t index = static_cast<size_t>(list->Length());
556   list = i::ArrayList::Add(isolate, list, obj);
557   ctx->set_serialized_objects(*list);
558   return index;
559 }
560 
561 namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)562 void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
563   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
564   i::Isolate* isolate = ctx->GetIsolate();
565   if (!ctx->serialized_objects().IsArrayList()) {
566     ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
567   } else {
568     i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
569                                  isolate);
570     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
571     ctx->set_serialized_objects(*elements);
572   }
573 }
574 
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)575 void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
576   if (!isolate->heap()->serialized_objects().IsArrayList()) {
577     isolate->heap()->SetSerializedObjects(
578         i::ReadOnlyRoots(isolate).empty_fixed_array());
579   } else {
580     i::Handle<i::ArrayList> list(
581         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
582     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
583     isolate->heap()->SetSerializedObjects(*elements);
584   }
585 }
586 }  // anonymous namespace
587 
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)588 StartupData SnapshotCreator::CreateBlob(
589     SnapshotCreator::FunctionCodeHandling function_code_handling) {
590   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
591   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
592   Utils::ApiCheck(!data->created_, "v8::SnapshotCreator::CreateBlob",
593                   "CreateBlob() cannot be called more than once on the same "
594                   "SnapshotCreator.");
595   Utils::ApiCheck(
596       !data->default_context_.IsEmpty(), "v8::SnapshotCreator::CreateBlob",
597       "CreateBlob() cannot be called before the default context is set.");
598 
599   const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
600   const int num_contexts = num_additional_contexts + 1;  // The default context.
601 
602   // Create and store lists of embedder-provided data needed during
603   // serialization.
604   {
605     i::HandleScope scope(isolate);
606     // Convert list of context-independent data to FixedArray.
607     ConvertSerializedObjectsToFixedArray(isolate);
608 
609     // Convert lists of context-dependent data to FixedArray.
610     ConvertSerializedObjectsToFixedArray(
611         data->default_context_.Get(data->isolate_));
612     for (int i = 0; i < num_additional_contexts; i++) {
613       ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
614     }
615 
616     // We need to store the global proxy size upfront in case we need the
617     // bootstrapper to create a global proxy before we deserialize the context.
618     i::Handle<i::FixedArray> global_proxy_sizes =
619         isolate->factory()->NewFixedArray(num_additional_contexts,
620                                           i::AllocationType::kOld);
621     for (int i = 0; i < num_additional_contexts; i++) {
622       i::Handle<i::Context> context =
623           v8::Utils::OpenHandle(*data->contexts_.Get(i));
624       global_proxy_sizes->set(i,
625                               i::Smi::FromInt(context->global_proxy().Size()));
626     }
627     isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
628   }
629 
630   // We might rehash strings and re-sort descriptors. Clear the lookup cache.
631   isolate->descriptor_lookup_cache()->Clear();
632 
633   // If we don't do this then we end up with a stray root pointing at the
634   // context even after we have disposed of the context.
635   isolate->heap()->CollectAllAvailableGarbage(
636       i::GarbageCollectionReason::kSnapshotCreator);
637   {
638     i::HandleScope scope(isolate);
639     isolate->heap()->CompactWeakArrayLists();
640   }
641 
642   i::Snapshot::ClearReconstructableDataForSerialization(
643       isolate, function_code_handling == FunctionCodeHandling::kClear);
644 
645   i::GlobalSafepointScope global_safepoint(isolate);
646   i::DisallowGarbageCollection no_gc_from_here_on;
647 
648   // Create a vector with all contexts and clear associated Persistent fields.
649   // Note these contexts may be dead after calling Clear(), but will not be
650   // collected until serialization completes and the DisallowGarbageCollection
651   // scope above goes out of scope.
652   std::vector<i::Context> contexts;
653   contexts.reserve(num_contexts);
654   {
655     i::HandleScope scope(isolate);
656     contexts.push_back(
657         *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
658     data->default_context_.Reset();
659     for (int i = 0; i < num_additional_contexts; i++) {
660       i::Handle<i::Context> context =
661           v8::Utils::OpenHandle(*data->contexts_.Get(i));
662       contexts.push_back(*context);
663     }
664     data->contexts_.Clear();
665   }
666 
667   // Check that values referenced by global/eternal handles are accounted for.
668   i::SerializedHandleChecker handle_checker(isolate, &contexts);
669   CHECK(handle_checker.CheckGlobalAndEternalHandles());
670 
671   // Create a vector with all embedder fields serializers.
672   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
673   embedder_fields_serializers.reserve(num_contexts);
674   embedder_fields_serializers.push_back(
675       data->default_embedder_fields_serializer_);
676   for (int i = 0; i < num_additional_contexts; i++) {
677     embedder_fields_serializers.push_back(
678         data->embedder_fields_serializers_[i]);
679   }
680 
681   data->created_ = true;
682   return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
683                              global_safepoint, no_gc_from_here_on);
684 }
685 
CanBeRehashed() const686 bool StartupData::CanBeRehashed() const {
687   DCHECK(i::Snapshot::VerifyChecksum(this));
688   return i::Snapshot::ExtractRehashability(this);
689 }
690 
IsValid() const691 bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
692 
SetDcheckErrorHandler(DcheckErrorCallback that)693 void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
694   v8::base::SetDcheckFunction(that);
695 }
696 
SetFlagsFromString(const char * str)697 void V8::SetFlagsFromString(const char* str) {
698   SetFlagsFromString(str, strlen(str));
699 }
700 
SetFlagsFromString(const char * str,size_t length)701 void V8::SetFlagsFromString(const char* str, size_t length) {
702   i::FlagList::SetFlagsFromString(str, length);
703   i::FlagList::EnforceFlagImplications();
704 }
705 
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)706 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
707   using HelpOptions = i::FlagList::HelpOptions;
708   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
709                                        HelpOptions(HelpOptions::kDontExit));
710 }
711 
712 RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
713 
RegisteredExtension(std::unique_ptr<Extension> extension)714 RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
715     : extension_(std::move(extension)) {}
716 
717 // static
Register(std::unique_ptr<Extension> extension)718 void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
719   RegisteredExtension* new_extension =
720       new RegisteredExtension(std::move(extension));
721   new_extension->next_ = first_extension_;
722   first_extension_ = new_extension;
723 }
724 
725 // static
UnregisterAll()726 void RegisteredExtension::UnregisterAll() {
727   RegisteredExtension* re = first_extension_;
728   while (re != nullptr) {
729     RegisteredExtension* next = re->next();
730     delete re;
731     re = next;
732   }
733   first_extension_ = nullptr;
734 }
735 
736 namespace {
737 class ExtensionResource : public String::ExternalOneByteStringResource {
738  public:
ExtensionResource()739   ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)740   ExtensionResource(const char* data, size_t length)
741       : data_(data), length_(length) {}
data() const742   const char* data() const override { return data_; }
length() const743   size_t length() const override { return length_; }
Dispose()744   void Dispose() override {}
745 
746  private:
747   const char* data_;
748   size_t length_;
749 };
750 }  // anonymous namespace
751 
RegisterExtension(std::unique_ptr<Extension> extension)752 void RegisterExtension(std::unique_ptr<Extension> extension) {
753   RegisteredExtension::Register(std::move(extension));
754 }
755 
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)756 Extension::Extension(const char* name, const char* source, int dep_count,
757                      const char** deps, int source_length)
758     : name_(name),
759       source_length_(source_length >= 0
760                          ? source_length
761                          : (source ? static_cast<int>(strlen(source)) : 0)),
762       dep_count_(dep_count),
763       deps_(deps),
764       auto_enable_(false) {
765   source_ = new ExtensionResource(source, source_length_);
766   CHECK(source != nullptr || source_length_ == 0);
767 }
768 
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)769 void ResourceConstraints::ConfigureDefaultsFromHeapSize(
770     size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
771   CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
772   if (maximum_heap_size_in_bytes == 0) {
773     return;
774   }
775   size_t young_generation, old_generation;
776   i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
777                                        &young_generation, &old_generation);
778   set_max_young_generation_size_in_bytes(
779       std::max(young_generation, i::Heap::MinYoungGenerationSize()));
780   set_max_old_generation_size_in_bytes(
781       std::max(old_generation, i::Heap::MinOldGenerationSize()));
782   if (initial_heap_size_in_bytes > 0) {
783     i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
784                                          &young_generation, &old_generation);
785     // We do not set lower bounds for the initial sizes.
786     set_initial_young_generation_size_in_bytes(young_generation);
787     set_initial_old_generation_size_in_bytes(old_generation);
788   }
789   if (i::kPlatformRequiresCodeRange) {
790     set_code_range_size_in_bytes(
791         std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
792   }
793 }
794 
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)795 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
796                                             uint64_t virtual_memory_limit) {
797   size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
798   size_t young_generation, old_generation;
799   i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
800                                        &old_generation);
801   set_max_young_generation_size_in_bytes(young_generation);
802   set_max_old_generation_size_in_bytes(old_generation);
803 
804   if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
805     set_code_range_size_in_bytes(
806         std::min(i::kMaximalCodeRangeSize,
807                  static_cast<size_t>(virtual_memory_limit / 8)));
808   }
809 }
810 
811 namespace internal {
812 
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,GlobalHandleStoreMode store_mode)813 i::Address* GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
814                                      internal::Address* slot,
815                                      GlobalHandleStoreMode store_mode) {
816   API_RCS_SCOPE(isolate, TracedGlobal, New);
817 #ifdef DEBUG
818   Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
819                   "the address slot must be not null");
820 #endif
821   i::Handle<i::Object> result =
822       isolate->global_handles()->CreateTraced(*obj, slot, store_mode);
823 #ifdef VERIFY_HEAP
824   if (i::FLAG_verify_heap) {
825     i::Object(*obj).ObjectVerify(isolate);
826   }
827 #endif  // VERIFY_HEAP
828   return result.location();
829 }
830 
MoveTracedReference(internal::Address ** from,internal::Address ** to)831 void MoveTracedReference(internal::Address** from, internal::Address** to) {
832   GlobalHandles::MoveTracedReference(from, to);
833 }
834 
CopyTracedReference(const internal::Address * const * from,internal::Address ** to)835 void CopyTracedReference(const internal::Address* const* from,
836                          internal::Address** to) {
837   GlobalHandles::CopyTracedReference(from, to);
838 }
839 
DisposeTracedReference(internal::Address * location)840 void DisposeTracedReference(internal::Address* location) {
841   GlobalHandles::DestroyTracedReference(location);
842 }
843 
844 }  // namespace internal
845 
846 namespace api_internal {
847 
GlobalizeReference(i::Isolate * isolate,i::Address * obj)848 i::Address* GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
849   API_RCS_SCOPE(isolate, Persistent, New);
850   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
851 #ifdef VERIFY_HEAP
852   if (i::FLAG_verify_heap) {
853     i::Object(*obj).ObjectVerify(isolate);
854   }
855 #endif  // VERIFY_HEAP
856   return result.location();
857 }
858 
CopyGlobalReference(i::Address * from)859 i::Address* CopyGlobalReference(i::Address* from) {
860   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
861   return result.location();
862 }
863 
MoveGlobalReference(internal::Address ** from,internal::Address ** to)864 void MoveGlobalReference(internal::Address** from, internal::Address** to) {
865   i::GlobalHandles::MoveGlobal(from, to);
866 }
867 
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)868 void MakeWeak(i::Address* location, void* parameter,
869               WeakCallbackInfo<void>::Callback weak_callback,
870               WeakCallbackType type) {
871   i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
872 }
873 
MakeWeak(i::Address ** location_addr)874 void MakeWeak(i::Address** location_addr) {
875   i::GlobalHandles::MakeWeak(location_addr);
876 }
877 
ClearWeak(i::Address * location)878 void* ClearWeak(i::Address* location) {
879   return i::GlobalHandles::ClearWeakness(location);
880 }
881 
AnnotateStrongRetainer(i::Address * location,const char * label)882 void AnnotateStrongRetainer(i::Address* location, const char* label) {
883   i::GlobalHandles::AnnotateStrongRetainer(location, label);
884 }
885 
DisposeGlobal(i::Address * location)886 void DisposeGlobal(i::Address* location) {
887   i::GlobalHandles::Destroy(location);
888 }
889 
Eternalize(Isolate * v8_isolate,Value * value)890 Value* Eternalize(Isolate* v8_isolate, Value* value) {
891   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
892   i::Object object = *Utils::OpenHandle(value);
893   int index = -1;
894   isolate->eternal_handles()->Create(isolate, object, &index);
895   return reinterpret_cast<Value*>(
896       isolate->eternal_handles()->Get(index).location());
897 }
898 
FromJustIsNothing()899 void FromJustIsNothing() {
900   Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
901 }
902 
ToLocalEmpty()903 void ToLocalEmpty() {
904   Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
905 }
906 
InternalFieldOutOfBounds(int index)907 void InternalFieldOutOfBounds(int index) {
908   Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
909                   "WeakCallbackInfo::GetInternalField",
910                   "Internal field out of bounds.");
911 }
912 
913 }  // namespace api_internal
914 
915 // --- H a n d l e s ---
916 
HandleScope(Isolate * isolate)917 HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
918 
Initialize(Isolate * isolate)919 void HandleScope::Initialize(Isolate* isolate) {
920   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
921   // We do not want to check the correct usage of the Locker class all over the
922   // place, so we do it only here: Without a HandleScope, an embedder can do
923   // almost nothing, so it is enough to check in this central place.
924   // We make an exception if the serializer is enabled, which means that the
925   // Isolate is exclusively used to create a snapshot.
926   Utils::ApiCheck(
927       !internal_isolate->was_locker_ever_used() ||
928           internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
929           internal_isolate->serializer_enabled(),
930       "HandleScope::HandleScope",
931       "Entering the V8 API without proper locking in place");
932   i::HandleScopeData* current = internal_isolate->handle_scope_data();
933   isolate_ = internal_isolate;
934   prev_next_ = current->next;
935   prev_limit_ = current->limit;
936   current->level++;
937 }
938 
~HandleScope()939 HandleScope::~HandleScope() {
940   i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
941 }
942 
operator new(size_t)943 void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)944 void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)945 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)946 void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
947 
NumberOfHandles(Isolate * isolate)948 int HandleScope::NumberOfHandles(Isolate* isolate) {
949   return i::HandleScope::NumberOfHandles(
950       reinterpret_cast<i::Isolate*>(isolate));
951 }
952 
CreateHandle(i::Isolate * isolate,i::Address value)953 i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
954   return i::HandleScope::CreateHandle(isolate, value);
955 }
956 
EscapableHandleScope(Isolate * v8_isolate)957 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
958   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
959   escape_slot_ =
960       CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
961   Initialize(v8_isolate);
962 }
963 
Escape(i::Address * escape_value)964 i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
965   i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
966   Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
967                   "EscapableHandleScope::Escape", "Escape value set twice");
968   if (escape_value == nullptr) {
969     *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
970     return nullptr;
971   }
972   *escape_slot_ = *escape_value;
973   return escape_slot_;
974 }
975 
operator new(size_t)976 void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)977 void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)978 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)979 void EscapableHandleScope::operator delete[](void*, size_t) {
980   base::OS::Abort();
981 }
982 
SealHandleScope(Isolate * isolate)983 SealHandleScope::SealHandleScope(Isolate* isolate)
984     : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
985   i::HandleScopeData* current = isolate_->handle_scope_data();
986   prev_limit_ = current->limit;
987   current->limit = current->next;
988   prev_sealed_level_ = current->sealed_level;
989   current->sealed_level = current->level;
990 }
991 
~SealHandleScope()992 SealHandleScope::~SealHandleScope() {
993   i::HandleScopeData* current = isolate_->handle_scope_data();
994   DCHECK_EQ(current->next, current->limit);
995   current->limit = prev_limit_;
996   DCHECK_EQ(current->level, current->sealed_level);
997   current->sealed_level = prev_sealed_level_;
998 }
999 
operator new(size_t)1000 void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1001 void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1002 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1003 void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1004 
IsModule() const1005 bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
IsFixedArray() const1006 bool Data::IsFixedArray() const {
1007   return Utils::OpenHandle(this)->IsFixedArray();
1008 }
1009 
IsValue() const1010 bool Data::IsValue() const {
1011   i::DisallowGarbageCollection no_gc;
1012   i::Object self = *Utils::OpenHandle(this);
1013   if (self.IsSmi()) return true;
1014   i::HeapObject heap_object = i::HeapObject::cast(self);
1015   DCHECK(!heap_object.IsTheHole());
1016   if (heap_object.IsSymbol()) {
1017     return !i::Symbol::cast(heap_object).is_private();
1018   }
1019   return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1020 }
1021 
IsPrivate() const1022 bool Data::IsPrivate() const {
1023   return Utils::OpenHandle(this)->IsPrivateSymbol();
1024 }
1025 
IsObjectTemplate() const1026 bool Data::IsObjectTemplate() const {
1027   return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1028 }
1029 
IsFunctionTemplate() const1030 bool Data::IsFunctionTemplate() const {
1031   return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1032 }
1033 
IsContext() const1034 bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1035 
Enter()1036 void Context::Enter() {
1037   i::Handle<i::Context> env = Utils::OpenHandle(this);
1038   i::Isolate* isolate = env->GetIsolate();
1039   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1040   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1041   impl->EnterContext(*env);
1042   impl->SaveContext(isolate->context());
1043   isolate->set_context(*env);
1044 }
1045 
Exit()1046 void Context::Exit() {
1047   i::Handle<i::Context> env = Utils::OpenHandle(this);
1048   i::Isolate* isolate = env->GetIsolate();
1049   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1050   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1051   if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1052                        "Cannot exit non-entered context")) {
1053     return;
1054   }
1055   impl->LeaveContext();
1056   isolate->set_context(impl->RestoreContext());
1057 }
1058 
BackupIncumbentScope(Local<Context> backup_incumbent_context)1059 Context::BackupIncumbentScope::BackupIncumbentScope(
1060     Local<Context> backup_incumbent_context)
1061     : backup_incumbent_context_(backup_incumbent_context) {
1062   DCHECK(!backup_incumbent_context_.IsEmpty());
1063 
1064   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1065   i::Isolate* isolate = env->GetIsolate();
1066 
1067   js_stack_comparable_address_ =
1068       i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1069 
1070   prev_ = isolate->top_backup_incumbent_scope();
1071   isolate->set_top_backup_incumbent_scope(this);
1072 }
1073 
~BackupIncumbentScope()1074 Context::BackupIncumbentScope::~BackupIncumbentScope() {
1075   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1076   i::Isolate* isolate = env->GetIsolate();
1077 
1078   i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1079 
1080   isolate->set_top_backup_incumbent_scope(prev_);
1081 }
1082 
1083 STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1084 
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1085 static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1086                                                        int index, bool can_grow,
1087                                                        const char* location) {
1088   i::Handle<i::Context> env = Utils::OpenHandle(context);
1089   i::Isolate* isolate = env->GetIsolate();
1090   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
1091   bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1092                             "Not a native context") &&
1093             Utils::ApiCheck(index >= 0, location, "Negative index");
1094   if (!ok) return i::Handle<i::EmbedderDataArray>();
1095   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1096   i::Handle<i::EmbedderDataArray> data(
1097       i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1098   if (index < data->length()) return data;
1099   if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1100                        location, "Index too large")) {
1101     return i::Handle<i::EmbedderDataArray>();
1102   }
1103   data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1104   env->set_embedder_data(*data);
1105   return data;
1106 }
1107 
GetNumberOfEmbedderDataFields()1108 uint32_t Context::GetNumberOfEmbedderDataFields() {
1109   i::Handle<i::Context> context = Utils::OpenHandle(this);
1110   ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate());
1111   Utils::ApiCheck(context->IsNativeContext(),
1112                   "Context::GetNumberOfEmbedderDataFields",
1113                   "Not a native context");
1114   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1115   return static_cast<uint32_t>(
1116       i::EmbedderDataArray::cast(context->embedder_data()).length());
1117 }
1118 
SlowGetEmbedderData(int index)1119 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1120   const char* location = "v8::Context::GetEmbedderData()";
1121   i::Handle<i::EmbedderDataArray> data =
1122       EmbedderDataFor(this, index, false, location);
1123   if (data.is_null()) return Local<Value>();
1124   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1125   i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1126                               isolate);
1127   return Utils::ToLocal(result);
1128 }
1129 
SetEmbedderData(int index,v8::Local<Value> value)1130 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1131   const char* location = "v8::Context::SetEmbedderData()";
1132   i::Handle<i::EmbedderDataArray> data =
1133       EmbedderDataFor(this, index, true, location);
1134   if (data.is_null()) return;
1135   i::Handle<i::Object> val = Utils::OpenHandle(*value);
1136   i::EmbedderDataSlot::store_tagged(*data, index, *val);
1137   DCHECK_EQ(*Utils::OpenHandle(*value),
1138             *Utils::OpenHandle(*GetEmbedderData(index)));
1139 }
1140 
SlowGetAlignedPointerFromEmbedderData(int index)1141 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1142   const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1143   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1144   i::HandleScope handle_scope(isolate);
1145   i::Handle<i::EmbedderDataArray> data =
1146       EmbedderDataFor(this, index, false, location);
1147   if (data.is_null()) return nullptr;
1148   void* result;
1149   Utils::ApiCheck(
1150       i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1151       location, "Pointer is not aligned");
1152   return result;
1153 }
1154 
SetAlignedPointerInEmbedderData(int index,void * value)1155 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1156   const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1157   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1158   i::Handle<i::EmbedderDataArray> data =
1159       EmbedderDataFor(this, index, true, location);
1160   bool ok =
1161       i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1162   Utils::ApiCheck(ok, location, "Pointer is not aligned");
1163   DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1164 }
1165 
1166 // --- T e m p l a t e ---
1167 
InitializeTemplate(i::TemplateInfo that,int type,bool do_not_cache)1168 static void InitializeTemplate(i::TemplateInfo that, int type,
1169                                bool do_not_cache) {
1170   that.set_number_of_properties(0);
1171   that.set_tag(type);
1172   int serial_number =
1173       do_not_cache ? i::TemplateInfo::kDoNotCache : i::TemplateInfo::kUncached;
1174   that.set_serial_number(serial_number);
1175 }
1176 
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1177 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1178                    v8::PropertyAttribute attribute) {
1179   auto templ = Utils::OpenHandle(this);
1180   i::Isolate* isolate = templ->GetIsolate();
1181   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1182   i::HandleScope scope(isolate);
1183   auto value_obj = Utils::OpenHandle(*value);
1184 
1185   Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(),
1186                   "v8::Template::Set",
1187                   "Invalid value, must be a primitive or a Template");
1188 
1189   // The template cache only performs shallow clones, if we set an
1190   // ObjectTemplate as a property value then we can not cache the receiver
1191   // template.
1192   if (value_obj->IsObjectTemplateInfo()) {
1193     templ->set_serial_number(i::TemplateInfo::kDoNotCache);
1194   }
1195 
1196   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1197                                  value_obj,
1198                                  static_cast<i::PropertyAttributes>(attribute));
1199 }
1200 
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1201 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1202                           v8::PropertyAttribute attribute) {
1203   Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1204       attribute);
1205 }
1206 
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1207 void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1208                                    v8::Local<FunctionTemplate> getter,
1209                                    v8::Local<FunctionTemplate> setter,
1210                                    v8::PropertyAttribute attribute,
1211                                    v8::AccessControl access_control) {
1212   // TODO(verwaest): Remove |access_control|.
1213   DCHECK_EQ(v8::DEFAULT, access_control);
1214   auto templ = Utils::OpenHandle(this);
1215   auto isolate = templ->GetIsolate();
1216   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1217   DCHECK(!name.IsEmpty());
1218   DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1219   i::HandleScope scope(isolate);
1220   i::ApiNatives::AddAccessorProperty(
1221       isolate, templ, Utils::OpenHandle(*name),
1222       Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1223       static_cast<i::PropertyAttributes>(attribute));
1224 }
1225 
1226 // --- F u n c t i o n   T e m p l a t e ---
InitializeFunctionTemplate(i::FunctionTemplateInfo info,bool do_not_cache)1227 static void InitializeFunctionTemplate(i::FunctionTemplateInfo info,
1228                                        bool do_not_cache) {
1229   InitializeTemplate(info, Consts::FUNCTION_TEMPLATE, do_not_cache);
1230   info.set_flag(0);
1231 }
1232 
1233 static Local<ObjectTemplate> ObjectTemplateNew(
1234     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1235     bool do_not_cache);
1236 
PrototypeTemplate()1237 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1238   auto self = Utils::OpenHandle(this);
1239   i::Isolate* i_isolate = self->GetIsolate();
1240   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1241   i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1242   if (result->IsUndefined(i_isolate)) {
1243     // Do not cache prototype objects.
1244     result = Utils::OpenHandle(
1245         *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1246     i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1247   }
1248   return ToApiHandle<ObjectTemplate>(result);
1249 }
1250 
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1251 void FunctionTemplate::SetPrototypeProviderTemplate(
1252     Local<FunctionTemplate> prototype_provider) {
1253   auto self = Utils::OpenHandle(this);
1254   i::Isolate* i_isolate = self->GetIsolate();
1255   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1256   i::Handle<i::FunctionTemplateInfo> result =
1257       Utils::OpenHandle(*prototype_provider);
1258   Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
1259                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1260                   "Protoype must be undefined");
1261   Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
1262                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1263                   "Prototype provider must be empty");
1264   i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1265                                                         result);
1266 }
1267 
EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,const char * func)1268 static void EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,
1269                                const char* func) {
1270   DCHECK_IMPLIES(info->instantiated(), info->published());
1271   Utils::ApiCheck(!info->published(), func,
1272                   "FunctionTemplate already instantiated");
1273 }
1274 
Inherit(v8::Local<FunctionTemplate> value)1275 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1276   auto info = Utils::OpenHandle(this);
1277   EnsureNotPublished(info, "v8::FunctionTemplate::Inherit");
1278   i::Isolate* i_isolate = info->GetIsolate();
1279   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1280   Utils::ApiCheck(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate),
1281                   "v8::FunctionTemplate::Inherit",
1282                   "Protoype provider must be empty");
1283   i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1284                                              Utils::OpenHandle(*value));
1285 }
1286 
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> (),SideEffectType side_effect_type=SideEffectType::kHasSideEffect,const MemorySpan<const CFunction> & c_function_overloads={},uint8_t instance_type=0,uint8_t allowed_receiver_instance_type_range_start=0,uint8_t allowed_receiver_instance_type_range_end=0)1287 static Local<FunctionTemplate> FunctionTemplateNew(
1288     i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1289     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1290     bool do_not_cache,
1291     v8::Local<Private> cached_property_name = v8::Local<Private>(),
1292     SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1293     const MemorySpan<const CFunction>& c_function_overloads = {},
1294     uint8_t instance_type = 0,
1295     uint8_t allowed_receiver_instance_type_range_start = 0,
1296     uint8_t allowed_receiver_instance_type_range_end = 0) {
1297   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1298       i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1299   i::Handle<i::FunctionTemplateInfo> obj =
1300       i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1301   {
1302     // Disallow GC until all fields of obj have acceptable types.
1303     i::DisallowGarbageCollection no_gc;
1304     i::FunctionTemplateInfo raw = *obj;
1305     InitializeFunctionTemplate(raw, do_not_cache);
1306     raw.set_length(length);
1307     raw.set_undetectable(false);
1308     raw.set_needs_access_check(false);
1309     raw.set_accept_any_receiver(true);
1310     if (!signature.IsEmpty()) {
1311       raw.set_signature(*Utils::OpenHandle(*signature));
1312     }
1313     raw.set_cached_property_name(
1314         cached_property_name.IsEmpty()
1315             ? i::ReadOnlyRoots(isolate).the_hole_value()
1316             : *Utils::OpenHandle(*cached_property_name));
1317     if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
1318     raw.SetInstanceType(instance_type);
1319     raw.set_allowed_receiver_instance_type_range_start(
1320         allowed_receiver_instance_type_range_start);
1321     raw.set_allowed_receiver_instance_type_range_end(
1322         allowed_receiver_instance_type_range_end);
1323   }
1324   if (callback != nullptr) {
1325     Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1326                                         c_function_overloads);
1327   }
1328   return Utils::ToLocal(obj);
1329 }
1330 
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const CFunction * c_function,uint16_t instance_type,uint16_t allowed_receiver_instance_type_range_start,uint16_t allowed_receiver_instance_type_range_end)1331 Local<FunctionTemplate> FunctionTemplate::New(
1332     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1333     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1334     SideEffectType side_effect_type, const CFunction* c_function,
1335     uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
1336     uint16_t allowed_receiver_instance_type_range_end) {
1337   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1338   // Changes to the environment cannot be captured in the snapshot. Expect no
1339   // function templates when the isolate is created for serialization.
1340   API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1341 
1342   if (!Utils::ApiCheck(
1343           !c_function || behavior == ConstructorBehavior::kThrow,
1344           "FunctionTemplate::New",
1345           "Fast API calls are not supported for constructor functions.")) {
1346     return Local<FunctionTemplate>();
1347   }
1348 
1349   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1350   return FunctionTemplateNew(
1351       i_isolate, callback, data, signature, length, behavior, false,
1352       Local<Private>(), side_effect_type,
1353       c_function ? MemorySpan<const CFunction>{c_function, 1}
1354                  : MemorySpan<const CFunction>{},
1355       instance_type, allowed_receiver_instance_type_range_start,
1356       allowed_receiver_instance_type_range_end);
1357 }
1358 
NewWithCFunctionOverloads(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1359 Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1360     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1361     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1362     SideEffectType side_effect_type,
1363     const MemorySpan<const CFunction>& c_function_overloads) {
1364   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1365   API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1366 
1367   if (!Utils::ApiCheck(
1368           c_function_overloads.size() == 0 ||
1369               behavior == ConstructorBehavior::kThrow,
1370           "FunctionTemplate::NewWithCFunctionOverloads",
1371           "Fast API calls are not supported for constructor functions.")) {
1372     return Local<FunctionTemplate>();
1373   }
1374 
1375   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1376   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1377                              behavior, false, Local<Private>(),
1378                              side_effect_type, c_function_overloads);
1379 }
1380 
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1381 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1382     Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1383     Local<Value> data, Local<Signature> signature, int length,
1384     SideEffectType side_effect_type) {
1385   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1386   API_RCS_SCOPE(i_isolate, FunctionTemplate, NewWithCache);
1387   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1388   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1389                              ConstructorBehavior::kAllow, false, cache_property,
1390                              side_effect_type);
1391 }
1392 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1393 Local<Signature> Signature::New(Isolate* isolate,
1394                                 Local<FunctionTemplate> receiver) {
1395   return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1396 }
1397 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1398 Local<AccessorSignature> AccessorSignature::New(
1399     Isolate* isolate, Local<FunctionTemplate> receiver) {
1400   return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1401 }
1402 
1403 #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata)        \
1404   do {                                                        \
1405     i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1406     (obj)->setter(*foreign);                                  \
1407   } while (false)
1408 
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1409 void FunctionTemplate::SetCallHandler(
1410     FunctionCallback callback, v8::Local<Value> data,
1411     SideEffectType side_effect_type,
1412     const MemorySpan<const CFunction>& c_function_overloads) {
1413   auto info = Utils::OpenHandle(this);
1414   EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
1415   i::Isolate* isolate = info->GetIsolate();
1416   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1417   i::HandleScope scope(isolate);
1418   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1419       side_effect_type == SideEffectType::kHasNoSideEffect);
1420   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1421   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1422   if (data.IsEmpty()) {
1423     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424   }
1425   obj->set_data(*Utils::OpenHandle(*data));
1426   if (c_function_overloads.size() > 0) {
1427     // Stores the data for a sequence of CFunction overloads into a single
1428     // FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
1429     i::Handle<i::FixedArray> function_overloads =
1430         isolate->factory()->NewFixedArray(static_cast<int>(
1431             c_function_overloads.size() *
1432             i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
1433     int function_count = static_cast<int>(c_function_overloads.size());
1434     for (int i = 0; i < function_count; i++) {
1435       const CFunction& c_function = c_function_overloads.data()[i];
1436       i::Handle<i::Object> address =
1437           FromCData(isolate, c_function.GetAddress());
1438       function_overloads->set(
1439           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
1440       i::Handle<i::Object> signature =
1441           FromCData(isolate, c_function.GetTypeInfo());
1442       function_overloads->set(
1443           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
1444           *signature);
1445     }
1446     i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
1447                                                    function_overloads);
1448   }
1449   info->set_call_code(*obj, kReleaseStore);
1450 }
1451 
1452 namespace {
1453 
1454 template <typename Getter, typename Setter>
MakeAccessorInfo(i::Isolate * isolate,v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1455 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1456     i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1457     v8::Local<Value> data, v8::AccessControl settings,
1458     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1459     bool replace_on_access) {
1460   i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1461   SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1462   DCHECK_IMPLIES(replace_on_access,
1463                  is_special_data_property && setter == nullptr);
1464   if (is_special_data_property && setter == nullptr) {
1465     setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1466   }
1467   SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1468   i::Address redirected = obj->redirected_getter();
1469   if (redirected != i::kNullAddress) {
1470     SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1471   }
1472 
1473   i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1474   if (!accessor_name->IsUniqueName()) {
1475     accessor_name = isolate->factory()->InternalizeString(
1476         i::Handle<i::String>::cast(accessor_name));
1477   }
1478   i::DisallowGarbageCollection no_gc;
1479   i::AccessorInfo raw_obj = *obj;
1480   if (data.IsEmpty()) {
1481     raw_obj.set_data(i::ReadOnlyRoots(isolate).undefined_value());
1482   } else {
1483     raw_obj.set_data(*Utils::OpenHandle(*data));
1484   }
1485   raw_obj.set_name(*accessor_name);
1486   raw_obj.set_is_special_data_property(is_special_data_property);
1487   raw_obj.set_replace_on_access(replace_on_access);
1488   if (settings & ALL_CAN_READ) raw_obj.set_all_can_read(true);
1489   if (settings & ALL_CAN_WRITE) raw_obj.set_all_can_write(true);
1490   raw_obj.set_initial_property_attributes(i::NONE);
1491   if (!signature.IsEmpty()) {
1492     raw_obj.set_expected_receiver_type(*Utils::OpenHandle(*signature));
1493   }
1494   return obj;
1495 }
1496 
1497 }  // namespace
1498 
InstanceTemplate()1499 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1500   i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1501   if (!Utils::ApiCheck(!handle.is_null(),
1502                        "v8::FunctionTemplate::InstanceTemplate()",
1503                        "Reading from empty handle")) {
1504     return Local<ObjectTemplate>();
1505   }
1506   i::Isolate* isolate = handle->GetIsolate();
1507   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1508   if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1509     Local<ObjectTemplate> templ =
1510         ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1511     i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1512                                                  Utils::OpenHandle(*templ));
1513   }
1514   i::Handle<i::ObjectTemplateInfo> result(
1515       i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1516   return Utils::ToLocal(result);
1517 }
1518 
SetLength(int length)1519 void FunctionTemplate::SetLength(int length) {
1520   auto info = Utils::OpenHandle(this);
1521   EnsureNotPublished(info, "v8::FunctionTemplate::SetLength");
1522   auto isolate = info->GetIsolate();
1523   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1524   info->set_length(length);
1525 }
1526 
SetClassName(Local<String> name)1527 void FunctionTemplate::SetClassName(Local<String> name) {
1528   auto info = Utils::OpenHandle(this);
1529   EnsureNotPublished(info, "v8::FunctionTemplate::SetClassName");
1530   auto isolate = info->GetIsolate();
1531   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1532   info->set_class_name(*Utils::OpenHandle(*name));
1533 }
1534 
SetAcceptAnyReceiver(bool value)1535 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1536   auto info = Utils::OpenHandle(this);
1537   EnsureNotPublished(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1538   auto isolate = info->GetIsolate();
1539   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1540   info->set_accept_any_receiver(value);
1541 }
1542 
ReadOnlyPrototype()1543 void FunctionTemplate::ReadOnlyPrototype() {
1544   auto info = Utils::OpenHandle(this);
1545   EnsureNotPublished(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1546   auto isolate = info->GetIsolate();
1547   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548   info->set_read_only_prototype(true);
1549 }
1550 
RemovePrototype()1551 void FunctionTemplate::RemovePrototype() {
1552   auto info = Utils::OpenHandle(this);
1553   EnsureNotPublished(info, "v8::FunctionTemplate::RemovePrototype");
1554   auto isolate = info->GetIsolate();
1555   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1556   info->set_remove_prototype(true);
1557 }
1558 
1559 // --- O b j e c t T e m p l a t e ---
1560 
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1561 Local<ObjectTemplate> ObjectTemplate::New(
1562     Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1563   return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1564 }
1565 
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1566 static Local<ObjectTemplate> ObjectTemplateNew(
1567     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1568     bool do_not_cache) {
1569   API_RCS_SCOPE(isolate, ObjectTemplate, New);
1570   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1571   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1572       i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1573   i::Handle<i::ObjectTemplateInfo> obj =
1574       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1575   {
1576     // Disallow GC until all fields of obj have acceptable types.
1577     i::DisallowGarbageCollection no_gc;
1578     i::ObjectTemplateInfo raw = *obj;
1579     InitializeTemplate(raw, Consts::OBJECT_TEMPLATE, do_not_cache);
1580     raw.set_data(0);
1581     if (!constructor.IsEmpty()) {
1582       raw.set_constructor(*Utils::OpenHandle(*constructor));
1583     }
1584   }
1585   return Utils::ToLocal(obj);
1586 }
1587 
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1588 Local<ObjectTemplate> ObjectTemplate::New(
1589     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1590   return ObjectTemplateNew(isolate, constructor, false);
1591 }
1592 
1593 // Ensure that the object template has a constructor.  If no
1594 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1595 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1596     i::Isolate* isolate, ObjectTemplate* object_template) {
1597   i::Object obj = Utils::OpenHandle(object_template)->constructor();
1598   if (!obj.IsUndefined(isolate)) {
1599     i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1600     return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1601   }
1602   Local<FunctionTemplate> templ =
1603       FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1604   i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1605   i::FunctionTemplateInfo::SetInstanceTemplate(
1606       isolate, constructor, Utils::OpenHandle(object_template));
1607   Utils::OpenHandle(object_template)->set_constructor(*constructor);
1608   return constructor;
1609 }
1610 
1611 template <typename Getter, typename Setter, typename Data, typename Template>
TemplateSetAccessor(Template * template_obj,v8::Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1612 static void TemplateSetAccessor(
1613     Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1614     Data data, AccessControl settings, PropertyAttribute attribute,
1615     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1616     bool replace_on_access, SideEffectType getter_side_effect_type,
1617     SideEffectType setter_side_effect_type) {
1618   auto info = Utils::OpenHandle(template_obj);
1619   auto isolate = info->GetIsolate();
1620   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1621   i::HandleScope scope(isolate);
1622   i::Handle<i::AccessorInfo> accessor_info =
1623       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1624                        is_special_data_property, replace_on_access);
1625   {
1626     i::DisallowGarbageCollection no_gc;
1627     i::AccessorInfo raw = *accessor_info;
1628     raw.set_initial_property_attributes(
1629         static_cast<i::PropertyAttributes>(attribute));
1630     raw.set_getter_side_effect_type(getter_side_effect_type);
1631     raw.set_setter_side_effect_type(setter_side_effect_type);
1632   }
1633   i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1634 }
1635 
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1636 void Template::SetNativeDataProperty(v8::Local<String> name,
1637                                      AccessorGetterCallback getter,
1638                                      AccessorSetterCallback setter,
1639                                      v8::Local<Value> data,
1640                                      PropertyAttribute attribute,
1641                                      AccessControl settings,
1642                                      SideEffectType getter_side_effect_type,
1643                                      SideEffectType setter_side_effect_type) {
1644   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1645                       Local<AccessorSignature>(), true, false,
1646                       getter_side_effect_type, setter_side_effect_type);
1647 }
1648 
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1649 void Template::SetNativeDataProperty(
1650     v8::Local<String> name, AccessorGetterCallback getter,
1651     AccessorSetterCallback setter, v8::Local<Value> data,
1652     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1653     AccessControl settings, SideEffectType getter_side_effect_type,
1654     SideEffectType setter_side_effect_type) {
1655   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1656                       signature, true, false, getter_side_effect_type,
1657                       setter_side_effect_type);
1658 }
1659 
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1660 void Template::SetNativeDataProperty(v8::Local<Name> name,
1661                                      AccessorNameGetterCallback getter,
1662                                      AccessorNameSetterCallback setter,
1663                                      v8::Local<Value> data,
1664                                      PropertyAttribute attribute,
1665                                      AccessControl settings,
1666                                      SideEffectType getter_side_effect_type,
1667                                      SideEffectType setter_side_effect_type) {
1668   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1669                       Local<AccessorSignature>(), true, false,
1670                       getter_side_effect_type, setter_side_effect_type);
1671 }
1672 
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1673 void Template::SetNativeDataProperty(
1674     v8::Local<Name> name, AccessorNameGetterCallback getter,
1675     AccessorNameSetterCallback setter, v8::Local<Value> data,
1676     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1677     AccessControl settings, SideEffectType getter_side_effect_type,
1678     SideEffectType setter_side_effect_type) {
1679   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1680                       signature, true, false, getter_side_effect_type,
1681                       setter_side_effect_type);
1682 }
1683 
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1684 void Template::SetLazyDataProperty(v8::Local<Name> name,
1685                                    AccessorNameGetterCallback getter,
1686                                    v8::Local<Value> data,
1687                                    PropertyAttribute attribute,
1688                                    SideEffectType getter_side_effect_type,
1689                                    SideEffectType setter_side_effect_type) {
1690   TemplateSetAccessor(this, name, getter,
1691                       static_cast<AccessorNameSetterCallback>(nullptr), data,
1692                       DEFAULT, attribute, Local<AccessorSignature>(), true,
1693                       true, getter_side_effect_type, setter_side_effect_type);
1694 }
1695 
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1696 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1697                                         PropertyAttribute attribute) {
1698   auto templ = Utils::OpenHandle(this);
1699   i::Isolate* isolate = templ->GetIsolate();
1700   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1701   i::HandleScope scope(isolate);
1702   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1703                                  intrinsic,
1704                                  static_cast<i::PropertyAttributes>(attribute));
1705 }
1706 
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1707 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1708                                  AccessorGetterCallback getter,
1709                                  AccessorSetterCallback setter,
1710                                  v8::Local<Value> data, AccessControl settings,
1711                                  PropertyAttribute attribute,
1712                                  SideEffectType getter_side_effect_type,
1713                                  SideEffectType setter_side_effect_type) {
1714   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1715                       Local<AccessorSignature>(),
1716                       i::FLAG_disable_old_api_accessors, false,
1717                       getter_side_effect_type, setter_side_effect_type);
1718 }
1719 
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1720 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1721                                  AccessorNameGetterCallback getter,
1722                                  AccessorNameSetterCallback setter,
1723                                  v8::Local<Value> data, AccessControl settings,
1724                                  PropertyAttribute attribute,
1725                                  SideEffectType getter_side_effect_type,
1726                                  SideEffectType setter_side_effect_type) {
1727   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1728                       Local<AccessorSignature>(),
1729                       i::FLAG_disable_old_api_accessors, false,
1730                       getter_side_effect_type, setter_side_effect_type);
1731 }
1732 
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1733 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1734                                  AccessorGetterCallback getter,
1735                                  AccessorSetterCallback setter,
1736                                  v8::Local<Value> data, AccessControl settings,
1737                                  PropertyAttribute attribute,
1738                                  v8::Local<AccessorSignature> signature,
1739                                  SideEffectType getter_side_effect_type,
1740                                  SideEffectType setter_side_effect_type) {
1741   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1742                       signature, i::FLAG_disable_old_api_accessors, false,
1743                       getter_side_effect_type, setter_side_effect_type);
1744 }
1745 
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1746 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1747                                  AccessorNameGetterCallback getter,
1748                                  AccessorNameSetterCallback setter,
1749                                  v8::Local<Value> data, AccessControl settings,
1750                                  PropertyAttribute attribute,
1751                                  v8::Local<AccessorSignature> signature,
1752                                  SideEffectType getter_side_effect_type,
1753                                  SideEffectType setter_side_effect_type) {
1754   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1755                       signature, i::FLAG_disable_old_api_accessors, false,
1756                       getter_side_effect_type, setter_side_effect_type);
1757 }
1758 
1759 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1760           typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1761 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1762     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1763     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1764     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1765   auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1766       i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1767   obj->set_flags(0);
1768 
1769   if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1770   if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1771   if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1772   if (descriptor != nullptr)
1773     SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1774   if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1775   if (enumerator != nullptr)
1776     SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1777   if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1778   obj->set_can_intercept_symbols(
1779       !(static_cast<int>(flags) &
1780         static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1781   obj->set_all_can_read(static_cast<int>(flags) &
1782                         static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1783   obj->set_non_masking(static_cast<int>(flags) &
1784                        static_cast<int>(PropertyHandlerFlags::kNonMasking));
1785   obj->set_has_no_side_effect(
1786       static_cast<int>(flags) &
1787       static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1788 
1789   if (data.IsEmpty()) {
1790     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1791   }
1792   obj->set_data(*Utils::OpenHandle(*data));
1793   return obj;
1794 }
1795 
1796 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1797           typename Deleter, typename Enumerator, typename Definer>
CreateNamedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1798 static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1799     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1800     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1801     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1802   auto interceptor =
1803       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1804                             enumerator, definer, data, flags);
1805   interceptor->set_is_named(true);
1806   return interceptor;
1807 }
1808 
1809 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1810           typename Deleter, typename Enumerator, typename Definer>
CreateIndexedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1811 static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1812     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1813     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1814     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1815   auto interceptor =
1816       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1817                             enumerator, definer, data, flags);
1818   interceptor->set_is_named(false);
1819   return interceptor;
1820 }
1821 
1822 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1823           typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1824 static void ObjectTemplateSetNamedPropertyHandler(
1825     ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1826     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1827     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1828   i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1829   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1830   i::HandleScope scope(isolate);
1831   auto cons = EnsureConstructor(isolate, templ);
1832   EnsureNotPublished(cons, "ObjectTemplateSetNamedPropertyHandler");
1833   auto obj =
1834       CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1835                                  remover, enumerator, definer, data, flags);
1836   i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1837 }
1838 
SetHandler(const NamedPropertyHandlerConfiguration & config)1839 void ObjectTemplate::SetHandler(
1840     const NamedPropertyHandlerConfiguration& config) {
1841   ObjectTemplateSetNamedPropertyHandler(
1842       this, config.getter, config.setter, config.query, config.descriptor,
1843       config.deleter, config.enumerator, config.definer, config.data,
1844       config.flags);
1845 }
1846 
MarkAsUndetectable()1847 void ObjectTemplate::MarkAsUndetectable() {
1848   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1849   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1850   i::HandleScope scope(isolate);
1851   auto cons = EnsureConstructor(isolate, this);
1852   EnsureNotPublished(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1853   cons->set_undetectable(true);
1854 }
1855 
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1856 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1857                                             Local<Value> data) {
1858   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1859   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1860   i::HandleScope scope(isolate);
1861   auto cons = EnsureConstructor(isolate, this);
1862   EnsureNotPublished(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1863 
1864   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1865       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1866   i::Handle<i::AccessCheckInfo> info =
1867       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1868 
1869   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1870   info->set_named_interceptor(i::Object());
1871   info->set_indexed_interceptor(i::Object());
1872 
1873   if (data.IsEmpty()) {
1874     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1875   }
1876   info->set_data(*Utils::OpenHandle(*data));
1877 
1878   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1879   cons->set_needs_access_check(true);
1880 }
1881 
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1882 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1883     AccessCheckCallback callback,
1884     const NamedPropertyHandlerConfiguration& named_handler,
1885     const IndexedPropertyHandlerConfiguration& indexed_handler,
1886     Local<Value> data) {
1887   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1888   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1889   i::HandleScope scope(isolate);
1890   auto cons = EnsureConstructor(isolate, this);
1891   EnsureNotPublished(cons,
1892                      "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1893 
1894   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1895       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1896   i::Handle<i::AccessCheckInfo> info =
1897       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1898 
1899   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1900   auto named_interceptor = CreateNamedInterceptorInfo(
1901       isolate, named_handler.getter, named_handler.setter, named_handler.query,
1902       named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1903       named_handler.definer, named_handler.data, named_handler.flags);
1904   info->set_named_interceptor(*named_interceptor);
1905   auto indexed_interceptor = CreateIndexedInterceptorInfo(
1906       isolate, indexed_handler.getter, indexed_handler.setter,
1907       indexed_handler.query, indexed_handler.descriptor,
1908       indexed_handler.deleter, indexed_handler.enumerator,
1909       indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1910   info->set_indexed_interceptor(*indexed_interceptor);
1911 
1912   if (data.IsEmpty()) {
1913     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1914   }
1915   info->set_data(*Utils::OpenHandle(*data));
1916 
1917   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1918   cons->set_needs_access_check(true);
1919 }
1920 
SetHandler(const IndexedPropertyHandlerConfiguration & config)1921 void ObjectTemplate::SetHandler(
1922     const IndexedPropertyHandlerConfiguration& config) {
1923   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1924   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1925   i::HandleScope scope(isolate);
1926   auto cons = EnsureConstructor(isolate, this);
1927   EnsureNotPublished(cons, "v8::ObjectTemplate::SetHandler");
1928   auto obj = CreateIndexedInterceptorInfo(
1929       isolate, config.getter, config.setter, config.query, config.descriptor,
1930       config.deleter, config.enumerator, config.definer, config.data,
1931       config.flags);
1932   i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1933 }
1934 
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1935 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1936                                               Local<Value> data) {
1937   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1938   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1939   i::HandleScope scope(isolate);
1940   auto cons = EnsureConstructor(isolate, this);
1941   EnsureNotPublished(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1942   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1943   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1944   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1945   if (data.IsEmpty()) {
1946     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1947   }
1948   obj->set_data(*Utils::OpenHandle(*data));
1949   i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1950 }
1951 
InternalFieldCount() const1952 int ObjectTemplate::InternalFieldCount() const {
1953   return Utils::OpenHandle(this)->embedder_field_count();
1954 }
1955 
SetInternalFieldCount(int value)1956 void ObjectTemplate::SetInternalFieldCount(int value) {
1957   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1958   if (!Utils::ApiCheck(i::Smi::IsValid(value),
1959                        "v8::ObjectTemplate::SetInternalFieldCount()",
1960                        "Invalid embedder field count")) {
1961     return;
1962   }
1963   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1964   if (value > 0) {
1965     // The embedder field count is set by the constructor function's
1966     // construct code, so we ensure that there is a constructor
1967     // function to do the setting.
1968     EnsureConstructor(isolate, this);
1969   }
1970   Utils::OpenHandle(this)->set_embedder_field_count(value);
1971 }
1972 
IsImmutableProto() const1973 bool ObjectTemplate::IsImmutableProto() const {
1974   return Utils::OpenHandle(this)->immutable_proto();
1975 }
1976 
SetImmutableProto()1977 void ObjectTemplate::SetImmutableProto() {
1978   auto self = Utils::OpenHandle(this);
1979   i::Isolate* isolate = self->GetIsolate();
1980   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1981   self->set_immutable_proto(true);
1982 }
1983 
IsCodeLike() const1984 bool ObjectTemplate::IsCodeLike() const {
1985   return Utils::OpenHandle(this)->code_like();
1986 }
1987 
SetCodeLike()1988 void ObjectTemplate::SetCodeLike() {
1989   auto self = Utils::OpenHandle(this);
1990   i::Isolate* isolate = self->GetIsolate();
1991   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1992   self->set_code_like(true);
1993 }
1994 
1995 // --- S c r i p t s ---
1996 
1997 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1998 // JSFunction.
1999 
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)2000 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
2001                                        BufferPolicy buffer_policy_)
2002     : data(data_),
2003       length(length_),
2004       rejected(false),
2005       buffer_policy(buffer_policy_) {}
2006 
~CachedData()2007 ScriptCompiler::CachedData::~CachedData() {
2008   if (buffer_policy == BufferOwned) {
2009     delete[] data;
2010   }
2011 }
2012 
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)2013 ScriptCompiler::StreamedSource::StreamedSource(
2014     std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2015     : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2016 
2017 ScriptCompiler::StreamedSource::~StreamedSource() = default;
2018 
BindToCurrentContext()2019 Local<Script> UnboundScript::BindToCurrentContext() {
2020   auto function_info =
2021       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2022   i::Isolate* isolate = function_info->GetIsolate();
2023   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2024   i::Handle<i::JSFunction> function =
2025       i::Factory::JSFunctionBuilder{isolate, function_info,
2026                                     isolate->native_context()}
2027           .Build();
2028   return ToApiHandle<Script>(function);
2029 }
2030 
GetId() const2031 int UnboundScript::GetId() const {
2032   auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
2033   API_RCS_SCOPE(function_info.GetIsolate(), UnboundScript, GetId);
2034   return i::Script::cast(function_info.script()).id();
2035 }
2036 
GetLineNumber(int code_pos)2037 int UnboundScript::GetLineNumber(int code_pos) {
2038   i::Handle<i::SharedFunctionInfo> obj =
2039       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2040   i::Isolate* isolate = obj->GetIsolate();
2041   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2042   API_RCS_SCOPE(isolate, UnboundScript, GetLineNumber);
2043   if (obj->script().IsScript()) {
2044     i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2045     return i::Script::GetLineNumber(script, code_pos);
2046   } else {
2047     return -1;
2048   }
2049 }
2050 
GetScriptName()2051 Local<Value> UnboundScript::GetScriptName() {
2052   i::Handle<i::SharedFunctionInfo> obj =
2053       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2054   i::Isolate* isolate = obj->GetIsolate();
2055   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2056   API_RCS_SCOPE(isolate, UnboundScript, GetName);
2057   if (obj->script().IsScript()) {
2058     i::Object name = i::Script::cast(obj->script()).name();
2059     return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2060   } else {
2061     return Local<String>();
2062   }
2063 }
2064 
GetSourceURL()2065 Local<Value> UnboundScript::GetSourceURL() {
2066   i::Handle<i::SharedFunctionInfo> obj =
2067       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2068   i::Isolate* isolate = obj->GetIsolate();
2069   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2070   API_RCS_SCOPE(isolate, UnboundScript, GetSourceURL);
2071   if (obj->script().IsScript()) {
2072     i::Object url = i::Script::cast(obj->script()).source_url();
2073     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2074   } else {
2075     return Local<String>();
2076   }
2077 }
2078 
GetSourceMappingURL()2079 Local<Value> UnboundScript::GetSourceMappingURL() {
2080   i::Handle<i::SharedFunctionInfo> obj =
2081       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2082   i::Isolate* isolate = obj->GetIsolate();
2083   API_RCS_SCOPE(isolate, UnboundScript, GetSourceMappingURL);
2084   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2085   if (obj->script().IsScript()) {
2086     i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2087     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2088   } else {
2089     return Local<String>();
2090   }
2091 }
2092 
Run(Local<Context> context)2093 MaybeLocal<Value> Script::Run(Local<Context> context) {
2094   return Run(context, Local<Data>());
2095 }
2096 
Run(Local<Context> context,Local<Data> host_defined_options)2097 MaybeLocal<Value> Script::Run(Local<Context> context,
2098                               Local<Data> host_defined_options) {
2099   auto v8_isolate = context->GetIsolate();
2100   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2101   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2102   ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2103            InternalEscapableScope);
2104   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2105   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2106                                              isolate);
2107   i::AggregatingHistogramTimerScope histogram_timer(
2108       isolate->counters()->compile_lazy());
2109   auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2110 
2111   // TODO(crbug.com/1193459): remove once ablation study is completed
2112   base::ElapsedTimer timer;
2113   base::TimeDelta delta;
2114   if (i::FLAG_script_delay > 0) {
2115     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay);
2116   }
2117   if (i::FLAG_script_delay_once > 0 && !isolate->did_run_script_delay()) {
2118     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay_once);
2119     isolate->set_did_run_script_delay(true);
2120   }
2121   if (i::FLAG_script_delay_fraction > 0.0) {
2122     timer.Start();
2123   } else if (delta.InMicroseconds() > 0) {
2124     timer.Start();
2125     while (timer.Elapsed() < delta) {
2126       // Busy wait.
2127     }
2128   }
2129 
2130   if (V8_UNLIKELY(i::FLAG_experimental_web_snapshots)) {
2131     i::Handle<i::HeapObject> maybe_script =
2132         handle(fun->shared().script(), isolate);
2133     if (maybe_script->IsScript() &&
2134         i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
2135       i::WebSnapshotDeserializer deserializer(
2136           reinterpret_cast<i::Isolate*>(v8_isolate),
2137           i::Handle<i::Script>::cast(maybe_script));
2138       deserializer.Deserialize();
2139       RETURN_ON_FAILED_EXECUTION(Value);
2140       Local<Value> result = v8::Undefined(v8_isolate);
2141       RETURN_ESCAPED(result);
2142     }
2143   }
2144 
2145   i::Handle<i::Object> receiver = isolate->global_proxy();
2146   // TODO(cbruni, chromium:1244145): Remove once migrated to the context.
2147   i::Handle<i::Object> options(
2148       i::Script::cast(fun->shared().script()).host_defined_options(), isolate);
2149   Local<Value> result;
2150   has_pending_exception = !ToLocal<Value>(
2151       i::Execution::CallScript(isolate, fun, receiver, options), &result);
2152 
2153   if (i::FLAG_script_delay_fraction > 0.0) {
2154     delta = v8::base::TimeDelta::FromMillisecondsD(
2155         timer.Elapsed().InMillisecondsF() * i::FLAG_script_delay_fraction);
2156     timer.Restart();
2157     while (timer.Elapsed() < delta) {
2158       // Busy wait.
2159     }
2160   }
2161 
2162   RETURN_ON_FAILED_EXECUTION(Value);
2163   RETURN_ESCAPED(result);
2164 }
2165 
GetResourceName()2166 Local<Value> ScriptOrModule::GetResourceName() {
2167   i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2168   i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2169   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2170   i::Handle<i::Object> val(obj->resource_name(), isolate);
2171   return ToApiHandle<Value>(val);
2172 }
2173 
GetHostDefinedOptions()2174 Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2175   return HostDefinedOptions().As<PrimitiveArray>();
2176 }
2177 
HostDefinedOptions()2178 Local<Data> ScriptOrModule::HostDefinedOptions() {
2179   i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2180   i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2181   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2182   i::Handle<i::Object> val(obj->host_defined_options(), isolate);
2183   return ToApiHandle<Data>(val);
2184 }
2185 
GetUnboundScript()2186 Local<UnboundScript> Script::GetUnboundScript() {
2187   i::DisallowGarbageCollection no_gc;
2188   i::Handle<i::JSFunction> obj = Utils::OpenHandle(this);
2189   i::SharedFunctionInfo sfi = (*obj).shared();
2190   i::Isolate* isolate = sfi.GetIsolate();
2191   return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2192 }
2193 
GetResourceName()2194 Local<Value> Script::GetResourceName() {
2195   i::DisallowGarbageCollection no_gc;
2196   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2197   i::SharedFunctionInfo sfi = (*func).shared();
2198   i::Isolate* isolate = func->GetIsolate();
2199   CHECK(sfi.script().IsScript());
2200   return ToApiHandle<Value>(
2201       i::handle(i::Script::cast(sfi.script()).name(), isolate));
2202 }
2203 
2204 // static
New(Isolate * v8_isolate,int length)2205 Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2206   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2207   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2208   Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2209                   "length must be equal or greater than zero");
2210   i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2211   return ToApiHandle<PrimitiveArray>(array);
2212 }
2213 
Length() const2214 int PrimitiveArray::Length() const {
2215   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2216   return array->length();
2217 }
2218 
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2219 void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2220                          Local<Primitive> item) {
2221   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2222   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2223   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2224   Utils::ApiCheck(index >= 0 && index < array->length(),
2225                   "v8::PrimitiveArray::Set",
2226                   "index must be greater than or equal to 0 and less than the "
2227                   "array length");
2228   i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2229   array->set(index, *i_item);
2230 }
2231 
Get(Isolate * v8_isolate,int index)2232 Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2233   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2234   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2235   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2236   Utils::ApiCheck(index >= 0 && index < array->length(),
2237                   "v8::PrimitiveArray::Get",
2238                   "index must be greater than or equal to 0 and less than the "
2239                   "array length");
2240   i::Handle<i::Object> i_item(array->get(index), isolate);
2241   return ToApiHandle<Primitive>(i_item);
2242 }
2243 
CheckCast(v8::Data * that)2244 void v8::PrimitiveArray::CheckCast(v8::Data* that) {
2245   i::Handle<i::Object> obj = Utils::OpenHandle(that);
2246   Utils::ApiCheck(
2247       obj->IsFixedArray(), "v8::PrimitiveArray::Cast",
2248       "Value is not a PrimitiveArray. This is a temporary issue, v8::Data and "
2249       "v8::PrimitiveArray will not be compatible in the future.");
2250 }
2251 
Length() const2252 int FixedArray::Length() const {
2253   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2254   return self->length();
2255 }
2256 
Get(Local<Context> context,int i) const2257 Local<Data> FixedArray::Get(Local<Context> context, int i) const {
2258   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2259   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2260   CHECK_LT(i, self->length());
2261   i::Handle<i::Object> entry(self->get(i), isolate);
2262   return ToApiHandle<Data>(entry);
2263 }
2264 
GetSpecifier() const2265 Local<String> ModuleRequest::GetSpecifier() const {
2266   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2267   i::Isolate* isolate = self->GetIsolate();
2268   return ToApiHandle<String>(i::handle(self->specifier(), isolate));
2269 }
2270 
GetSourceOffset() const2271 int ModuleRequest::GetSourceOffset() const {
2272   return Utils::OpenHandle(this)->position();
2273 }
2274 
GetImportAssertions() const2275 Local<FixedArray> ModuleRequest::GetImportAssertions() const {
2276   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2277   i::Isolate* isolate = self->GetIsolate();
2278   return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate));
2279 }
2280 
GetStatus() const2281 Module::Status Module::GetStatus() const {
2282   i::Handle<i::Module> self = Utils::OpenHandle(this);
2283   switch (self->status()) {
2284     case i::Module::kUnlinked:
2285     case i::Module::kPreLinking:
2286       return kUninstantiated;
2287     case i::Module::kLinking:
2288       return kInstantiating;
2289     case i::Module::kLinked:
2290       return kInstantiated;
2291     case i::Module::kEvaluating:
2292     case i::Module::kEvaluatingAsync:
2293       return kEvaluating;
2294     case i::Module::kEvaluated:
2295       return kEvaluated;
2296     case i::Module::kErrored:
2297       return kErrored;
2298   }
2299   UNREACHABLE();
2300 }
2301 
GetException() const2302 Local<Value> Module::GetException() const {
2303   Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2304                   "Module status must be kErrored");
2305   i::Handle<i::Module> self = Utils::OpenHandle(this);
2306   i::Isolate* isolate = self->GetIsolate();
2307   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2308   return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2309 }
2310 
GetModuleRequests() const2311 Local<FixedArray> Module::GetModuleRequests() const {
2312   i::Handle<i::Module> self = Utils::OpenHandle(this);
2313   if (self->IsSyntheticModule()) {
2314     // Synthetic modules are leaf nodes in the module graph. They have no
2315     // ModuleRequests.
2316     return ToApiHandle<FixedArray>(
2317         self->GetReadOnlyRoots().empty_fixed_array_handle());
2318   } else {
2319     i::Isolate* isolate = self->GetIsolate();
2320     i::Handle<i::FixedArray> module_requests(
2321         i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2322         isolate);
2323     return ToApiHandle<FixedArray>(module_requests);
2324   }
2325 }
2326 
SourceOffsetToLocation(int offset) const2327 Location Module::SourceOffsetToLocation(int offset) const {
2328   i::Handle<i::Module> self = Utils::OpenHandle(this);
2329   i::Isolate* isolate = self->GetIsolate();
2330   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2331   i::HandleScope scope(isolate);
2332   Utils::ApiCheck(
2333       self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation",
2334       "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule");
2335   i::Handle<i::Script> script(
2336       i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2337   i::Script::PositionInfo info;
2338   i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
2339   return v8::Location(info.line, info.column);
2340 }
2341 
GetModuleNamespace()2342 Local<Value> Module::GetModuleNamespace() {
2343   Utils::ApiCheck(
2344       GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2345       "v8::Module::GetModuleNamespace must be used on an instantiated module");
2346   i::Handle<i::Module> self = Utils::OpenHandle(this);
2347   auto isolate = self->GetIsolate();
2348   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2349   i::Handle<i::JSModuleNamespace> module_namespace =
2350       i::Module::GetModuleNamespace(isolate, self);
2351   return ToApiHandle<Value>(module_namespace);
2352 }
2353 
GetUnboundModuleScript()2354 Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2355   i::Handle<i::Module> self = Utils::OpenHandle(this);
2356   Utils::ApiCheck(
2357       self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript",
2358       "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule");
2359   auto isolate = self->GetIsolate();
2360   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2361   return ToApiHandle<UnboundModuleScript>(i::handle(
2362       i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2363       isolate));
2364 }
2365 
ScriptId() const2366 int Module::ScriptId() const {
2367   i::Module self = *Utils::OpenHandle(this);
2368   Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
2369                   "v8::Module::ScriptId must be used on an SourceTextModule");
2370   ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2371   return i::SourceTextModule::cast(self).GetScript().id();
2372 }
2373 
IsGraphAsync() const2374 bool Module::IsGraphAsync() const {
2375   Utils::ApiCheck(
2376       GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2377       "v8::Module::IsGraphAsync must be used on an instantiated module");
2378   i::Module self = *Utils::OpenHandle(this);
2379   auto isolate = self.GetIsolate();
2380   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2381   return self.IsGraphAsync(isolate);
2382 }
2383 
IsSourceTextModule() const2384 bool Module::IsSourceTextModule() const {
2385   return Utils::OpenHandle(this)->IsSourceTextModule();
2386 }
2387 
IsSyntheticModule() const2388 bool Module::IsSyntheticModule() const {
2389   return Utils::OpenHandle(this)->IsSyntheticModule();
2390 }
2391 
GetIdentityHash() const2392 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2393 
InstantiateModule(Local<Context> context,Module::ResolveModuleCallback callback)2394 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2395                                       Module::ResolveModuleCallback callback) {
2396   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2397   ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2398            i::HandleScope);
2399   has_pending_exception = !i::Module::Instantiate(
2400       isolate, Utils::OpenHandle(this), context, callback, nullptr);
2401   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2402   return Just(true);
2403 }
2404 
Evaluate(Local<Context> context)2405 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2406   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2407   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2408   ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2409            InternalEscapableScope);
2410   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2411   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2412                                              isolate);
2413   i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2414 
2415   i::Handle<i::Module> self = Utils::OpenHandle(this);
2416   Utils::ApiCheck(self->status() >= i::Module::kLinked, "Module::Evaluate",
2417                   "Expected instantiated module");
2418 
2419   Local<Value> result;
2420   has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2421   RETURN_ON_FAILED_EXECUTION(Value);
2422   RETURN_ESCAPED(result);
2423 }
2424 
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2425 Local<Module> Module::CreateSyntheticModule(
2426     Isolate* isolate, Local<String> module_name,
2427     const std::vector<Local<v8::String>>& export_names,
2428     v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2429   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2430   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
2431   i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2432   i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2433       static_cast<int>(export_names.size()));
2434   for (int i = 0; i < i_export_names->length(); ++i) {
2435     i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2436         Utils::OpenHandle(*export_names[i]));
2437     i_export_names->set(i, *str);
2438   }
2439   return v8::Utils::ToLocal(
2440       i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2441           i_module_name, i_export_names, evaluation_steps)));
2442 }
2443 
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2444 Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2445                                              Local<String> export_name,
2446                                              Local<v8::Value> export_value) {
2447   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2448   i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2449   i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2450   i::Handle<i::Module> self = Utils::OpenHandle(this);
2451   Utils::ApiCheck(self->IsSyntheticModule(),
2452                   "v8::Module::SyntheticModuleSetExport",
2453                   "v8::Module::SyntheticModuleSetExport must only be called on "
2454                   "a SyntheticModule");
2455   ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2456                      SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2457   has_pending_exception =
2458       i::SyntheticModule::SetExport(i_isolate,
2459                                     i::Handle<i::SyntheticModule>::cast(self),
2460                                     i_export_name, i_export_value)
2461           .IsNothing();
2462   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2463   return Just(true);
2464 }
2465 
2466 namespace {
2467 
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,int resource_line_offset,int resource_column_offset,Local<Value> source_map_url,Local<Data> host_defined_options,ScriptOriginOptions origin_options)2468 i::ScriptDetails GetScriptDetails(
2469     i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset,
2470     int resource_column_offset, Local<Value> source_map_url,
2471     Local<Data> host_defined_options, ScriptOriginOptions origin_options) {
2472   i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
2473                                   origin_options);
2474   script_details.line_offset = resource_line_offset;
2475   script_details.column_offset = resource_column_offset;
2476   script_details.host_defined_options =
2477       host_defined_options.IsEmpty()
2478           ? isolate->factory()->empty_fixed_array()
2479           : Utils::OpenHandle(*(host_defined_options));
2480   if (!source_map_url.IsEmpty()) {
2481     script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2482   }
2483   return script_details;
2484 }
2485 
2486 }  // namespace
2487 
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2488 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2489     Isolate* v8_isolate, Source* source, CompileOptions options,
2490     NoCacheReason no_cache_reason) {
2491   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2492   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2493   ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2494                      CompileUnbound, MaybeLocal<UnboundScript>(),
2495                      InternalEscapableScope);
2496 
2497   i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2498 
2499   i::Handle<i::SharedFunctionInfo> result;
2500   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2501   i::ScriptDetails script_details = GetScriptDetails(
2502       isolate, source->resource_name, source->resource_line_offset,
2503       source->resource_column_offset, source->source_map_url,
2504       source->host_defined_options, source->resource_options);
2505 
2506   i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info;
2507   if (options == kConsumeCodeCache) {
2508     if (source->consume_cache_task) {
2509       // Take ownership of the internal deserialization task and clear it off
2510       // the consume task on the source.
2511       DCHECK_NOT_NULL(source->consume_cache_task->impl_);
2512       std::unique_ptr<i::BackgroundDeserializeTask> deserialize_task =
2513           std::move(source->consume_cache_task->impl_);
2514       maybe_function_info =
2515           i::Compiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
2516               isolate, str, script_details, deserialize_task.get(), options,
2517               no_cache_reason, i::NOT_NATIVES_CODE);
2518       source->cached_data->rejected = deserialize_task->rejected();
2519     } else {
2520       DCHECK(source->cached_data);
2521       // AlignedCachedData takes care of pointer-aligning the data.
2522       auto cached_data = std::make_unique<i::AlignedCachedData>(
2523           source->cached_data->data, source->cached_data->length);
2524       maybe_function_info =
2525           i::Compiler::GetSharedFunctionInfoForScriptWithCachedData(
2526               isolate, str, script_details, cached_data.get(), options,
2527               no_cache_reason, i::NOT_NATIVES_CODE);
2528       source->cached_data->rejected = cached_data->rejected();
2529     }
2530   } else {
2531     // Compile without any cache.
2532     maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript(
2533         isolate, str, script_details, options, no_cache_reason,
2534         i::NOT_NATIVES_CODE);
2535   }
2536 
2537   has_pending_exception = !maybe_function_info.ToHandle(&result);
2538   RETURN_ON_FAILED_EXECUTION(UnboundScript);
2539   RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2540 }
2541 
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2542 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2543     Isolate* v8_isolate, Source* source, CompileOptions options,
2544     NoCacheReason no_cache_reason) {
2545   Utils::ApiCheck(
2546       !source->GetResourceOptions().IsModule(),
2547       "v8::ScriptCompiler::CompileUnboundScript",
2548       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2549   return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2550 }
2551 
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2552 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2553                                            Source* source,
2554                                            CompileOptions options,
2555                                            NoCacheReason no_cache_reason) {
2556   Utils::ApiCheck(
2557       !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2558       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2559   auto isolate = context->GetIsolate();
2560   MaybeLocal<UnboundScript> maybe =
2561       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2562   Local<UnboundScript> result;
2563   if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2564   v8::Context::Scope scope(context);
2565   return result->BindToCurrentContext();
2566 }
2567 
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2568 MaybeLocal<Module> ScriptCompiler::CompileModule(
2569     Isolate* isolate, Source* source, CompileOptions options,
2570     NoCacheReason no_cache_reason) {
2571   Utils::ApiCheck(options == kNoCompileOptions || options == kConsumeCodeCache,
2572                   "v8::ScriptCompiler::CompileModule",
2573                   "Invalid CompileOptions");
2574   Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2575                   "v8::ScriptCompiler::CompileModule",
2576                   "Invalid ScriptOrigin: is_module must be true");
2577   MaybeLocal<UnboundScript> maybe =
2578       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2579   Local<UnboundScript> unbound;
2580   if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2581   i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2582   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2583   return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2584 }
2585 
2586 // static
CompileFunction(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason)2587 V8_WARN_UNUSED_RESULT MaybeLocal<Function> ScriptCompiler::CompileFunction(
2588     Local<Context> context, Source* source, size_t arguments_count,
2589     Local<String> arguments[], size_t context_extension_count,
2590     Local<Object> context_extensions[], CompileOptions options,
2591     NoCacheReason no_cache_reason) {
2592   return CompileFunctionInternal(context, source, arguments_count, arguments,
2593                                  context_extension_count, context_extensions,
2594                                  options, no_cache_reason, nullptr);
2595 }
2596 
2597 // static
CompileFunctionInContext(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2598 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2599     Local<Context> context, Source* source, size_t arguments_count,
2600     Local<String> arguments[], size_t context_extension_count,
2601     Local<Object> context_extensions[], CompileOptions options,
2602     NoCacheReason no_cache_reason,
2603     Local<ScriptOrModule>* script_or_module_out) {
2604   return CompileFunctionInternal(
2605       context, source, arguments_count, arguments, context_extension_count,
2606       context_extensions, options, no_cache_reason, script_or_module_out);
2607 }
2608 
CompileFunctionInternal(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2609 MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
2610     Local<Context> v8_context, Source* source, size_t arguments_count,
2611     Local<String> arguments[], size_t context_extension_count,
2612     Local<Object> context_extensions[], CompileOptions options,
2613     NoCacheReason no_cache_reason,
2614     Local<ScriptOrModule>* script_or_module_out) {
2615   Local<Function> result;
2616 
2617   {
2618     PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunction,
2619                           Function);
2620     TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2621 
2622     DCHECK(options == CompileOptions::kConsumeCodeCache ||
2623            options == CompileOptions::kEagerCompile ||
2624            options == CompileOptions::kNoCompileOptions);
2625 
2626     i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2627 
2628     DCHECK(context->IsNativeContext());
2629 
2630     i::Handle<i::FixedArray> arguments_list =
2631         isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2632     for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2633       i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2634       if (!i::String::IsIdentifier(isolate, argument)) return Local<Function>();
2635       arguments_list->set(i, *argument);
2636     }
2637 
2638     for (size_t i = 0; i < context_extension_count; ++i) {
2639       i::Handle<i::JSReceiver> extension =
2640           Utils::OpenHandle(*context_extensions[i]);
2641       if (!extension->IsJSObject()) return Local<Function>();
2642       context = isolate->factory()->NewWithContext(
2643           context,
2644           i::ScopeInfo::CreateForWithScope(
2645               isolate,
2646               context->IsNativeContext()
2647                   ? i::Handle<i::ScopeInfo>::null()
2648                   : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2649           extension);
2650     }
2651 
2652     i::ScriptDetails script_details = GetScriptDetails(
2653         isolate, source->resource_name, source->resource_line_offset,
2654         source->resource_column_offset, source->source_map_url,
2655         source->host_defined_options, source->resource_options);
2656 
2657     std::unique_ptr<i::AlignedCachedData> cached_data;
2658     if (options == kConsumeCodeCache) {
2659       DCHECK(source->cached_data);
2660       // ScriptData takes care of pointer-aligning the data.
2661       cached_data.reset(new i::AlignedCachedData(source->cached_data->data,
2662                                                  source->cached_data->length));
2663     }
2664 
2665     i::Handle<i::JSFunction> scoped_result;
2666     has_pending_exception =
2667         !i::Compiler::GetWrappedFunction(
2668              Utils::OpenHandle(*source->source_string), arguments_list, context,
2669              script_details, cached_data.get(), options, no_cache_reason)
2670              .ToHandle(&scoped_result);
2671     if (options == kConsumeCodeCache) {
2672       source->cached_data->rejected = cached_data->rejected();
2673     }
2674     RETURN_ON_FAILED_EXECUTION(Function);
2675     result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2676   }
2677   // TODO(cbruni): remove script_or_module_out paramater
2678   if (script_or_module_out != nullptr) {
2679     i::Handle<i::JSFunction> function =
2680         i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2681     i::Isolate* isolate = function->GetIsolate();
2682     i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2683     i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2684     // TODO(cbruni, v8:12302): Avoid creating tempory ScriptOrModule objects.
2685     auto script_or_module = i::Handle<i::ScriptOrModule>::cast(
2686         isolate->factory()->NewStruct(i::SCRIPT_OR_MODULE_TYPE));
2687     script_or_module->set_resource_name(script->name());
2688     script_or_module->set_host_defined_options(script->host_defined_options());
2689 #ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
2690     i::Handle<i::ArrayList> list =
2691         i::handle(script->script_or_modules(), isolate);
2692     list = i::ArrayList::Add(isolate, list, script_or_module);
2693     script->set_script_or_modules(*list);
2694 #endif  // V8_SCRIPTORMODULE_LEGACY_LIFETIME
2695     *script_or_module_out = v8::Utils::ToLocal(script_or_module);
2696   }
2697   return result;
2698 }
2699 
Run()2700 void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2701 
StartStreaming(Isolate * v8_isolate,StreamedSource * source,v8::ScriptType type)2702 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2703     Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) {
2704   if (!i::FLAG_script_streaming) return nullptr;
2705   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2706   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2707   i::ScriptStreamingData* data = source->impl();
2708   std::unique_ptr<i::BackgroundCompileTask> task =
2709       std::make_unique<i::BackgroundCompileTask>(data, isolate, type);
2710   data->task = std::move(task);
2711   return new ScriptCompiler::ScriptStreamingTask(data);
2712 }
2713 
ConsumeCodeCacheTask(std::unique_ptr<i::BackgroundDeserializeTask> impl)2714 ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2715     std::unique_ptr<i::BackgroundDeserializeTask> impl)
2716     : impl_(std::move(impl)) {}
2717 
2718 ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2719 
Run()2720 void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2721 
StartConsumingCodeCache(Isolate * v8_isolate,std::unique_ptr<CachedData> cached_data)2722 ScriptCompiler::ConsumeCodeCacheTask* ScriptCompiler::StartConsumingCodeCache(
2723     Isolate* v8_isolate, std::unique_ptr<CachedData> cached_data) {
2724   if (!i::FLAG_concurrent_cache_deserialization) return nullptr;
2725   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2726   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2727   return new ScriptCompiler::ConsumeCodeCacheTask(
2728       std::make_unique<i::BackgroundDeserializeTask>(isolate,
2729                                                      std::move(cached_data)));
2730 }
2731 
2732 namespace {
CompileStreamedSource(i::Isolate * isolate,ScriptCompiler::StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2733 i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
2734     i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source,
2735     Local<String> full_source_string, const ScriptOrigin& origin) {
2736   i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2737   i::ScriptDetails script_details =
2738       GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
2739                        origin.ColumnOffset(), origin.SourceMapUrl(),
2740                        origin.GetHostDefinedOptions(), origin.Options());
2741   i::ScriptStreamingData* data = v8_source->impl();
2742   return i::Compiler::GetSharedFunctionInfoForStreamedScript(
2743       isolate, str, script_details, data);
2744 }
2745 
2746 }  // namespace
2747 
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2748 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2749                                            StreamedSource* v8_source,
2750                                            Local<String> full_source_string,
2751                                            const ScriptOrigin& origin) {
2752   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2753   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2754   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2755                "V8.CompileStreamedScript");
2756   i::Handle<i::SharedFunctionInfo> sfi;
2757   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2758       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2759   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2760   if (has_pending_exception) isolate->ReportPendingMessages();
2761   RETURN_ON_FAILED_EXECUTION(Script);
2762   Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi);
2763   if (generic.IsEmpty()) return Local<Script>();
2764   Local<Script> bound = generic->BindToCurrentContext();
2765   if (bound.IsEmpty()) return Local<Script>();
2766   RETURN_ESCAPED(bound);
2767 }
2768 
CompileModule(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2769 MaybeLocal<Module> ScriptCompiler::CompileModule(
2770     Local<Context> context, StreamedSource* v8_source,
2771     Local<String> full_source_string, const ScriptOrigin& origin) {
2772   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module);
2773   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2774   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2775                "V8.CompileStreamedModule");
2776   i::Handle<i::SharedFunctionInfo> sfi;
2777   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2778       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2779   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2780   if (has_pending_exception) isolate->ReportPendingMessages();
2781   RETURN_ON_FAILED_EXECUTION(Module);
2782   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2783   RETURN_ESCAPED(
2784       ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi)));
2785 }
2786 
CachedDataVersionTag()2787 uint32_t ScriptCompiler::CachedDataVersionTag() {
2788   return static_cast<uint32_t>(base::hash_combine(
2789       internal::Version::Hash(), internal::FlagList::Hash(),
2790       static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2791 }
2792 
CreateCodeCache(Local<UnboundScript> unbound_script)2793 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2794     Local<UnboundScript> unbound_script) {
2795   i::Handle<i::SharedFunctionInfo> shared =
2796       i::Handle<i::SharedFunctionInfo>::cast(
2797           Utils::OpenHandle(*unbound_script));
2798   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2799   DCHECK(shared->is_toplevel());
2800   return i::CodeSerializer::Serialize(shared);
2801 }
2802 
2803 // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2804 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2805     Local<UnboundModuleScript> unbound_module_script) {
2806   i::Handle<i::SharedFunctionInfo> shared =
2807       i::Handle<i::SharedFunctionInfo>::cast(
2808           Utils::OpenHandle(*unbound_module_script));
2809   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2810   DCHECK(shared->is_toplevel());
2811   return i::CodeSerializer::Serialize(shared);
2812 }
2813 
CreateCodeCacheForFunction(Local<Function> function)2814 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2815     Local<Function> function) {
2816   auto js_function =
2817       i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2818   i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2819                                           js_function->GetIsolate());
2820   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2821   Utils::ApiCheck(shared->is_wrapped(),
2822                   "v8::ScriptCompiler::CreateCodeCacheForFunction",
2823                   "Expected SharedFunctionInfo with wrapped source code.");
2824   return i::CodeSerializer::Serialize(shared);
2825 }
2826 
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2827 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2828                                    ScriptOrigin* origin) {
2829   if (origin) {
2830     ScriptCompiler::Source script_source(source, *origin);
2831     return ScriptCompiler::Compile(context, &script_source);
2832   }
2833   ScriptCompiler::Source script_source(source);
2834   return ScriptCompiler::Compile(context, &script_source);
2835 }
2836 
2837 // --- E x c e p t i o n s ---
2838 
TryCatch(v8::Isolate * isolate)2839 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2840     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2841       next_(isolate_->try_catch_handler()),
2842       is_verbose_(false),
2843       can_continue_(true),
2844       capture_message_(true),
2845       rethrow_(false),
2846       has_terminated_(false) {
2847   ResetInternal();
2848   // Special handling for simulators which have a separate JS stack.
2849   js_stack_comparable_address_ = static_cast<internal::Address>(
2850       i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2851   isolate_->RegisterTryCatchHandler(this);
2852 }
2853 
~TryCatch()2854 v8::TryCatch::~TryCatch() {
2855   if (rethrow_) {
2856     v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2857     v8::HandleScope scope(isolate);
2858     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2859     if (HasCaught() && capture_message_) {
2860       // If an exception was caught and rethrow_ is indicated, the saved
2861       // message, script, and location need to be restored to Isolate TLS
2862       // for reuse.  capture_message_ needs to be disabled so that Throw()
2863       // does not create a new message.
2864       isolate_->thread_local_top()->rethrowing_message_ = true;
2865       isolate_->RestorePendingMessageFromTryCatch(this);
2866     }
2867     isolate_->UnregisterTryCatchHandler(this);
2868     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2869     reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2870     DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2871   } else {
2872     if (HasCaught() && isolate_->has_scheduled_exception()) {
2873       // If an exception was caught but is still scheduled because no API call
2874       // promoted it, then it is canceled to prevent it from being propagated.
2875       // Note that this will not cancel termination exceptions.
2876       isolate_->CancelScheduledExceptionFromTryCatch(this);
2877     }
2878     isolate_->UnregisterTryCatchHandler(this);
2879     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2880   }
2881 }
2882 
operator new(size_t)2883 void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2884 void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2885 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2886 void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2887 
HasCaught() const2888 bool v8::TryCatch::HasCaught() const {
2889   return !i::Object(reinterpret_cast<i::Address>(exception_))
2890               .IsTheHole(isolate_);
2891 }
2892 
CanContinue() const2893 bool v8::TryCatch::CanContinue() const { return can_continue_; }
2894 
HasTerminated() const2895 bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2896 
ReThrow()2897 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2898   if (!HasCaught()) return v8::Local<v8::Value>();
2899   rethrow_ = true;
2900   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2901 }
2902 
Exception() const2903 v8::Local<Value> v8::TryCatch::Exception() const {
2904   if (HasCaught()) {
2905     // Check for out of memory exception.
2906     i::Object exception(reinterpret_cast<i::Address>(exception_));
2907     return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2908   } else {
2909     return v8::Local<Value>();
2910   }
2911 }
2912 
StackTrace(Local<Context> context,Local<Value> exception)2913 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2914                                            Local<Value> exception) {
2915   i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2916   if (!i_exception->IsJSObject()) return v8::Local<Value>();
2917   PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2918   auto obj = i::Handle<i::JSObject>::cast(i_exception);
2919   i::Handle<i::String> name = isolate->factory()->stack_string();
2920   Maybe<bool> maybe = i::JSReceiver::HasProperty(isolate, obj, name);
2921   has_pending_exception = maybe.IsNothing();
2922   RETURN_ON_FAILED_EXECUTION(Value);
2923   if (!maybe.FromJust()) return v8::Local<Value>();
2924   Local<Value> result;
2925   has_pending_exception =
2926       !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2927   RETURN_ON_FAILED_EXECUTION(Value);
2928   RETURN_ESCAPED(result);
2929 }
2930 
StackTrace(Local<Context> context) const2931 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2932   if (!HasCaught()) return v8::Local<Value>();
2933   return StackTrace(context, Exception());
2934 }
2935 
Message() const2936 v8::Local<v8::Message> v8::TryCatch::Message() const {
2937   i::Object message(reinterpret_cast<i::Address>(message_obj_));
2938   DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2939   if (HasCaught() && !message.IsTheHole(isolate_)) {
2940     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2941   } else {
2942     return v8::Local<v8::Message>();
2943   }
2944 }
2945 
Reset()2946 void v8::TryCatch::Reset() {
2947   if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2948     // If an exception was caught but is still scheduled because no API call
2949     // promoted it, then it is canceled to prevent it from being propagated.
2950     // Note that this will not cancel termination exceptions.
2951     isolate_->CancelScheduledExceptionFromTryCatch(this);
2952   }
2953   ResetInternal();
2954 }
2955 
ResetInternal()2956 void v8::TryCatch::ResetInternal() {
2957   i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2958   exception_ = reinterpret_cast<void*>(the_hole.ptr());
2959   message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2960 }
2961 
SetVerbose(bool value)2962 void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2963 
IsVerbose() const2964 bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2965 
SetCaptureMessage(bool value)2966 void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2967 
2968 // --- M e s s a g e ---
2969 
Get() const2970 Local<String> Message::Get() const {
2971   auto self = Utils::OpenHandle(this);
2972   i::Isolate* isolate = self->GetIsolate();
2973   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2975   i::Handle<i::String> raw_result =
2976       i::MessageHandler::GetMessage(isolate, self);
2977   Local<String> result = Utils::ToLocal(raw_result);
2978   return scope.Escape(result);
2979 }
2980 
GetIsolate() const2981 v8::Isolate* Message::GetIsolate() const {
2982   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983   return reinterpret_cast<Isolate*>(isolate);
2984 }
2985 
GetScriptOrigin() const2986 ScriptOrigin Message::GetScriptOrigin() const {
2987   auto self = Utils::OpenHandle(this);
2988   i::Isolate* isolate = self->GetIsolate();
2989   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2990   i::Handle<i::Script> script(self->script(), isolate);
2991   return GetScriptOriginForScript(isolate, script);
2992 }
2993 
VerifyHostDefinedOptions() const2994 void ScriptOrigin::VerifyHostDefinedOptions() const {
2995   // TODO(cbruni, chromium:1244145): Remove checks once we allow arbitrary
2996   // host-defined options.
2997   USE(isolate_);
2998   if (host_defined_options_.IsEmpty()) return;
2999   Utils::ApiCheck(host_defined_options_->IsFixedArray(), "ScriptOrigin()",
3000                   "Host-defined options has to be a PrimitiveArray");
3001   i::Handle<i::FixedArray> options =
3002       Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
3003   for (int i = 0; i < options->length(); i++) {
3004     Utils::ApiCheck(options->get(i).IsPrimitive(), "ScriptOrigin()",
3005                     "PrimitiveArray can only contain primtive values");
3006   }
3007 }
3008 
GetScriptResourceName() const3009 v8::Local<Value> Message::GetScriptResourceName() const {
3010   ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
3011   return GetScriptOrigin().ResourceName();
3012 }
3013 
GetStackTrace() const3014 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
3015   auto self = Utils::OpenHandle(this);
3016   i::Isolate* isolate = self->GetIsolate();
3017   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3018   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3019   i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
3020   if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
3021   auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
3022   return scope.Escape(Utils::StackTraceToLocal(stackTrace));
3023 }
3024 
GetLineNumber(Local<Context> context) const3025 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
3026   auto self = Utils::OpenHandle(this);
3027   i::Isolate* isolate = self->GetIsolate();
3028   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3029   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3030   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3031   return Just(self->GetLineNumber());
3032 }
3033 
GetStartPosition() const3034 int Message::GetStartPosition() const {
3035   auto self = Utils::OpenHandle(this);
3036   i::Isolate* isolate = self->GetIsolate();
3037   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3038   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3039   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3040   return self->GetStartPosition();
3041 }
3042 
GetEndPosition() const3043 int Message::GetEndPosition() const {
3044   auto self = Utils::OpenHandle(this);
3045   i::Isolate* isolate = self->GetIsolate();
3046   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3047   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3048   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3049   return self->GetEndPosition();
3050 }
3051 
ErrorLevel() const3052 int Message::ErrorLevel() const {
3053   auto self = Utils::OpenHandle(this);
3054   ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3055   return self->error_level();
3056 }
3057 
GetStartColumn() const3058 int Message::GetStartColumn() const {
3059   auto self = Utils::OpenHandle(this);
3060   i::Isolate* isolate = self->GetIsolate();
3061   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3062   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3063   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3064   return self->GetColumnNumber();
3065 }
3066 
GetWasmFunctionIndex() const3067 int Message::GetWasmFunctionIndex() const {
3068 #if V8_ENABLE_WEBASSEMBLY
3069   auto self = Utils::OpenHandle(this);
3070   i::Isolate* isolate = self->GetIsolate();
3071   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3072   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3073   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3074   int start_position = self->GetColumnNumber();
3075   if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
3076 
3077   i::Handle<i::Script> script(self->script(), isolate);
3078 
3079   if (script->type() != i::Script::TYPE_WASM) {
3080     return Message::kNoWasmFunctionIndexInfo;
3081   }
3082 
3083   auto debug_script = ToApiHandle<debug::Script>(script);
3084   return Local<debug::WasmScript>::Cast(debug_script)
3085       ->GetContainingFunction(start_position);
3086 #else
3087   return Message::kNoWasmFunctionIndexInfo;
3088 #endif  // V8_ENABLE_WEBASSEMBLY
3089 }
3090 
GetStartColumn(Local<Context> context) const3091 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3092   return Just(GetStartColumn());
3093 }
3094 
GetEndColumn() const3095 int Message::GetEndColumn() const {
3096   auto self = Utils::OpenHandle(this);
3097   i::Isolate* isolate = self->GetIsolate();
3098   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3099   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3100   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3101   const int column_number = self->GetColumnNumber();
3102   if (column_number == -1) return -1;
3103   const int start = self->GetStartPosition();
3104   const int end = self->GetEndPosition();
3105   return column_number + (end - start);
3106 }
3107 
GetEndColumn(Local<Context> context) const3108 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3109   return Just(GetEndColumn());
3110 }
3111 
IsSharedCrossOrigin() const3112 bool Message::IsSharedCrossOrigin() const {
3113   auto self = Utils::OpenHandle(this);
3114   i::Isolate* isolate = self->GetIsolate();
3115   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3116   return self->script().origin_options().IsSharedCrossOrigin();
3117 }
3118 
IsOpaque() const3119 bool Message::IsOpaque() const {
3120   auto self = Utils::OpenHandle(this);
3121   i::Isolate* isolate = self->GetIsolate();
3122   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3123   return self->script().origin_options().IsOpaque();
3124 }
3125 
GetSource(Local<Context> context) const3126 MaybeLocal<String> Message::GetSource(Local<Context> context) const {
3127   auto self = Utils::OpenHandle(this);
3128   i::Isolate* isolate = self->GetIsolate();
3129   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3130   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3131   i::Handle<i::String> source(self->GetSource(), isolate);
3132   RETURN_ESCAPED(Utils::ToLocal(source));
3133 }
3134 
GetSourceLine(Local<Context> context) const3135 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3136   auto self = Utils::OpenHandle(this);
3137   i::Isolate* isolate = self->GetIsolate();
3138   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3139   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3140   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3141   RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3142 }
3143 
PrintCurrentStackTrace(Isolate * isolate,std::ostream & out)3144 void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) {
3145   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3146   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3147   i_isolate->PrintCurrentStackTrace(out);
3148 }
3149 
3150 // --- S t a c k T r a c e ---
3151 
GetFrame(Isolate * v8_isolate,uint32_t index) const3152 Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3153                                        uint32_t index) const {
3154   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3155   i::Handle<i::StackFrameInfo> info(
3156       i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate);
3157   return Utils::StackFrameToLocal(info);
3158 }
3159 
GetFrameCount() const3160 int StackTrace::GetFrameCount() const {
3161   return Utils::OpenHandle(this)->length();
3162 }
3163 
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3164 Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3165                                                 int frame_limit,
3166                                                 StackTraceOptions options) {
3167   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3168   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3169   i::Handle<i::FixedArray> stackTrace =
3170       i_isolate->CaptureDetailedStackTrace(frame_limit, options);
3171   return Utils::StackTraceToLocal(stackTrace);
3172 }
3173 
CurrentScriptNameOrSourceURL(Isolate * v8_isolate)3174 Local<String> StackTrace::CurrentScriptNameOrSourceURL(Isolate* v8_isolate) {
3175   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3176   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3177   i::Handle<i::String> name_or_source_url =
3178       isolate->CurrentScriptNameOrSourceURL();
3179   return Utils::ToLocal(name_or_source_url);
3180 }
3181 
3182 // --- S t a c k F r a m e ---
3183 
GetLocation() const3184 Location StackFrame::GetLocation() const {
3185   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3186   i::Isolate* isolate = self->GetIsolate();
3187   i::Handle<i::Script> script(self->script(), isolate);
3188   i::Script::PositionInfo info;
3189   CHECK(i::Script::GetPositionInfo(script,
3190                                    i::StackFrameInfo::GetSourcePosition(self),
3191                                    &info, i::Script::WITH_OFFSET));
3192   if (script->HasSourceURLComment()) {
3193     info.line -= script->line_offset();
3194     if (info.line == 0) {
3195       info.column -= script->column_offset();
3196     }
3197   }
3198   return {info.line, info.column};
3199 }
3200 
GetScriptId() const3201 int StackFrame::GetScriptId() const {
3202   return Utils::OpenHandle(this)->script().id();
3203 }
3204 
GetScriptName() const3205 Local<String> StackFrame::GetScriptName() const {
3206   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3207   i::Isolate* isolate = self->GetIsolate();
3208   i::Handle<i::Object> name(self->script().name(), isolate);
3209   if (!name->IsString()) return {};
3210   return Utils::ToLocal(i::Handle<i::String>::cast(name));
3211 }
3212 
GetScriptNameOrSourceURL() const3213 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3214   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3215   i::Isolate* isolate = self->GetIsolate();
3216   i::Handle<i::Object> name_or_source_url(self->script().GetNameOrSourceURL(),
3217                                           isolate);
3218   if (!name_or_source_url->IsString()) return {};
3219   return Utils::ToLocal(i::Handle<i::String>::cast(name_or_source_url));
3220 }
3221 
GetScriptSource() const3222 Local<String> StackFrame::GetScriptSource() const {
3223   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3224   i::Isolate* isolate = self->GetIsolate();
3225   if (!self->script().HasValidSource()) return {};
3226   i::Handle<i::PrimitiveHeapObject> source(self->script().source(), isolate);
3227   if (!source->IsString()) return {};
3228   return Utils::ToLocal(i::Handle<i::String>::cast(source));
3229 }
3230 
GetScriptSourceMappingURL() const3231 Local<String> StackFrame::GetScriptSourceMappingURL() const {
3232   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3233   i::Isolate* isolate = self->GetIsolate();
3234   i::Handle<i::Object> source_mapping_url(self->script().source_mapping_url(),
3235                                           isolate);
3236   if (!source_mapping_url->IsString()) return {};
3237   return Utils::ToLocal(i::Handle<i::String>::cast(source_mapping_url));
3238 }
3239 
GetFunctionName() const3240 Local<String> StackFrame::GetFunctionName() const {
3241   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3242   i::Isolate* isolate = self->GetIsolate();
3243   i::Handle<i::String> name(self->function_name(), isolate);
3244   if (name->length() == 0) return {};
3245   return Utils::ToLocal(name);
3246 }
3247 
IsEval() const3248 bool StackFrame::IsEval() const {
3249   i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3250   return self->script().compilation_type() == i::Script::COMPILATION_TYPE_EVAL;
3251 }
3252 
IsConstructor() const3253 bool StackFrame::IsConstructor() const {
3254   return Utils::OpenHandle(this)->is_constructor();
3255 }
3256 
IsWasm() const3257 bool StackFrame::IsWasm() const { return !IsUserJavaScript(); }
3258 
IsUserJavaScript() const3259 bool StackFrame::IsUserJavaScript() const {
3260   return Utils::OpenHandle(this)->script().IsUserJavaScript();
3261 }
3262 
3263 // --- J S O N ---
3264 
Parse(Local<Context> context,Local<String> json_string)3265 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3266                               Local<String> json_string) {
3267   PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3268   i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3269   i::Handle<i::String> source = i::String::Flatten(isolate, string);
3270   i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3271   auto maybe = source->IsOneByteRepresentation()
3272                    ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3273                    : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3274   Local<Value> result;
3275   has_pending_exception = !ToLocal<Value>(maybe, &result);
3276   RETURN_ON_FAILED_EXECUTION(Value);
3277   RETURN_ESCAPED(result);
3278 }
3279 
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3280 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3281                                    Local<Value> json_object,
3282                                    Local<String> gap) {
3283   PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3284   i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3285   i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3286   i::Handle<i::String> gap_string = gap.IsEmpty()
3287                                         ? isolate->factory()->empty_string()
3288                                         : Utils::OpenHandle(*gap);
3289   i::Handle<i::Object> maybe;
3290   has_pending_exception =
3291       !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3292   RETURN_ON_FAILED_EXECUTION(String);
3293   Local<String> result;
3294   has_pending_exception =
3295       !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3296   RETURN_ON_FAILED_EXECUTION(String);
3297   RETURN_ESCAPED(result);
3298 }
3299 
3300 // --- V a l u e   S e r i a l i z a t i o n ---
3301 
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3302 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3303                                                        Local<Object> object) {
3304   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3305   isolate->ScheduleThrow(*isolate->factory()->NewError(
3306       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3307       Utils::OpenHandle(*object)));
3308   return Nothing<bool>();
3309 }
3310 
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3311 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3312     Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3313   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3314   isolate->ScheduleThrow(*isolate->factory()->NewError(
3315       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3316       Utils::OpenHandle(*shared_array_buffer)));
3317   return Nothing<uint32_t>();
3318 }
3319 
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3320 Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3321     Isolate* v8_isolate, Local<WasmModuleObject> module) {
3322   return Nothing<uint32_t>();
3323 }
3324 
SupportsSharedValues() const3325 bool ValueSerializer::Delegate::SupportsSharedValues() const { return false; }
3326 
GetSharedValueId(Isolate * v8_isolate,Local<Value> shared_value)3327 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedValueId(
3328     Isolate* v8_isolate, Local<Value> shared_value) {
3329   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3330   isolate->ScheduleThrow(*isolate->factory()->NewError(
3331       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3332       Utils::OpenHandle(*shared_value)));
3333   return Nothing<uint32_t>();
3334 }
3335 
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3336 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3337                                                         size_t size,
3338                                                         size_t* actual_size) {
3339   *actual_size = size;
3340   return base::Realloc(old_buffer, size);
3341 }
3342 
FreeBufferMemory(void * buffer)3343 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3344   return base::Free(buffer);
3345 }
3346 
3347 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3348   explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3349       : isolate(i), serializer(i, delegate) {}
3350   i::Isolate* isolate;
3351   i::ValueSerializer serializer;
3352 };
3353 
ValueSerializer(Isolate * isolate)3354 ValueSerializer::ValueSerializer(Isolate* isolate)
3355     : ValueSerializer(isolate, nullptr) {}
3356 
ValueSerializer(Isolate * isolate,Delegate * delegate)3357 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3358     : private_(
3359           new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3360 
~ValueSerializer()3361 ValueSerializer::~ValueSerializer() { delete private_; }
3362 
WriteHeader()3363 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3364 
SetTreatArrayBufferViewsAsHostObjects(bool mode)3365 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3366   private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3367 }
3368 
WriteValue(Local<Context> context,Local<Value> value)3369 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3370                                         Local<Value> value) {
3371   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3372   ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3373            i::HandleScope);
3374   i::Handle<i::Object> object = Utils::OpenHandle(*value);
3375   Maybe<bool> result = private_->serializer.WriteObject(object);
3376   has_pending_exception = result.IsNothing();
3377   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3378   return result;
3379 }
3380 
Release()3381 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3382   return private_->serializer.Release();
3383 }
3384 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3385 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3386                                           Local<ArrayBuffer> array_buffer) {
3387   private_->serializer.TransferArrayBuffer(transfer_id,
3388                                            Utils::OpenHandle(*array_buffer));
3389 }
3390 
WriteUint32(uint32_t value)3391 void ValueSerializer::WriteUint32(uint32_t value) {
3392   private_->serializer.WriteUint32(value);
3393 }
3394 
WriteUint64(uint64_t value)3395 void ValueSerializer::WriteUint64(uint64_t value) {
3396   private_->serializer.WriteUint64(value);
3397 }
3398 
WriteDouble(double value)3399 void ValueSerializer::WriteDouble(double value) {
3400   private_->serializer.WriteDouble(value);
3401 }
3402 
WriteRawBytes(const void * source,size_t length)3403 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3404   private_->serializer.WriteRawBytes(source, length);
3405 }
3406 
ReadHostObject(Isolate * v8_isolate)3407 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3408     Isolate* v8_isolate) {
3409   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3410   isolate->ScheduleThrow(*isolate->factory()->NewError(
3411       isolate->error_function(),
3412       i::MessageTemplate::kDataCloneDeserializationError));
3413   return MaybeLocal<Object>();
3414 }
3415 
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3416 MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3417     Isolate* v8_isolate, uint32_t id) {
3418   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3419   isolate->ScheduleThrow(*isolate->factory()->NewError(
3420       isolate->error_function(),
3421       i::MessageTemplate::kDataCloneDeserializationError));
3422   return MaybeLocal<WasmModuleObject>();
3423 }
3424 
SupportsSharedValues() const3425 bool ValueDeserializer::Delegate::SupportsSharedValues() const { return false; }
3426 
GetSharedValueFromId(Isolate * v8_isolate,uint32_t shared_value_id)3427 MaybeLocal<Value> ValueDeserializer::Delegate::GetSharedValueFromId(
3428     Isolate* v8_isolate, uint32_t shared_value_id) {
3429   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3430   isolate->ScheduleThrow(*isolate->factory()->NewError(
3431       isolate->error_function(),
3432       i::MessageTemplate::kDataCloneDeserializationError));
3433   return MaybeLocal<Value>();
3434 }
3435 
3436 MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3437 ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3438                                                         uint32_t id) {
3439   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3440   isolate->ScheduleThrow(*isolate->factory()->NewError(
3441       isolate->error_function(),
3442       i::MessageTemplate::kDataCloneDeserializationError));
3443   return MaybeLocal<SharedArrayBuffer>();
3444 }
3445 
3446 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3447   PrivateData(i::Isolate* i, base::Vector<const uint8_t> data,
3448               Delegate* delegate)
3449       : isolate(i), deserializer(i, data, delegate) {}
3450   i::Isolate* isolate;
3451   i::ValueDeserializer deserializer;
3452   bool supports_legacy_wire_format = false;
3453 };
3454 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3455 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3456                                      size_t size)
3457     : ValueDeserializer(isolate, data, size, nullptr) {}
3458 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3459 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3460                                      size_t size, Delegate* delegate) {
3461   private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3462                              base::Vector<const uint8_t>(data, size), delegate);
3463 }
3464 
~ValueDeserializer()3465 ValueDeserializer::~ValueDeserializer() { delete private_; }
3466 
ReadHeader(Local<Context> context)3467 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3468   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3469   ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3470                      Nothing<bool>(), i::HandleScope);
3471 
3472   bool read_header = false;
3473   has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3474   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3475   DCHECK(read_header);
3476 
3477   static const uint32_t kMinimumNonLegacyVersion = 13;
3478   if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3479       !private_->supports_legacy_wire_format) {
3480     isolate->Throw(*isolate->factory()->NewError(
3481         i::MessageTemplate::kDataCloneDeserializationVersionError));
3482     has_pending_exception = true;
3483     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3484   }
3485 
3486   return Just(true);
3487 }
3488 
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3489 void ValueDeserializer::SetSupportsLegacyWireFormat(
3490     bool supports_legacy_wire_format) {
3491   private_->supports_legacy_wire_format = supports_legacy_wire_format;
3492 }
3493 
GetWireFormatVersion() const3494 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3495   return private_->deserializer.GetWireFormatVersion();
3496 }
3497 
ReadValue(Local<Context> context)3498 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3499   PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3500   i::MaybeHandle<i::Object> result;
3501   if (GetWireFormatVersion() > 0) {
3502     result = private_->deserializer.ReadObjectWrapper();
3503   } else {
3504     result =
3505         private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3506   }
3507   Local<Value> value;
3508   has_pending_exception = !ToLocal(result, &value);
3509   RETURN_ON_FAILED_EXECUTION(Value);
3510   RETURN_ESCAPED(value);
3511 }
3512 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3513 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3514                                             Local<ArrayBuffer> array_buffer) {
3515   private_->deserializer.TransferArrayBuffer(transfer_id,
3516                                              Utils::OpenHandle(*array_buffer));
3517 }
3518 
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3519 void ValueDeserializer::TransferSharedArrayBuffer(
3520     uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3521   private_->deserializer.TransferArrayBuffer(
3522       transfer_id, Utils::OpenHandle(*shared_array_buffer));
3523 }
3524 
ReadUint32(uint32_t * value)3525 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3526   return private_->deserializer.ReadUint32(value);
3527 }
3528 
ReadUint64(uint64_t * value)3529 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3530   return private_->deserializer.ReadUint64(value);
3531 }
3532 
ReadDouble(double * value)3533 bool ValueDeserializer::ReadDouble(double* value) {
3534   return private_->deserializer.ReadDouble(value);
3535 }
3536 
ReadRawBytes(size_t length,const void ** data)3537 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3538   return private_->deserializer.ReadRawBytes(length, data);
3539 }
3540 
3541 // --- D a t a ---
3542 
FullIsUndefined() const3543 bool Value::FullIsUndefined() const {
3544   i::Handle<i::Object> object = Utils::OpenHandle(this);
3545   bool result = object->IsUndefined();
3546   DCHECK_EQ(result, QuickIsUndefined());
3547   return result;
3548 }
3549 
FullIsNull() const3550 bool Value::FullIsNull() const {
3551   i::Handle<i::Object> object = Utils::OpenHandle(this);
3552   bool result = object->IsNull();
3553   DCHECK_EQ(result, QuickIsNull());
3554   return result;
3555 }
3556 
IsTrue() const3557 bool Value::IsTrue() const {
3558   i::Object object = *Utils::OpenHandle(this);
3559   if (object.IsSmi()) return false;
3560   return object.IsTrue();
3561 }
3562 
IsFalse() const3563 bool Value::IsFalse() const {
3564   i::Object object = *Utils::OpenHandle(this);
3565   if (object.IsSmi()) return false;
3566   return object.IsFalse();
3567 }
3568 
IsFunction() const3569 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3570 
IsName() const3571 bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3572 
FullIsString() const3573 bool Value::FullIsString() const {
3574   bool result = Utils::OpenHandle(this)->IsString();
3575   DCHECK_EQ(result, QuickIsString());
3576   return result;
3577 }
3578 
IsSymbol() const3579 bool Value::IsSymbol() const {
3580   return Utils::OpenHandle(this)->IsPublicSymbol();
3581 }
3582 
IsArray() const3583 bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3584 
IsArrayBuffer() const3585 bool Value::IsArrayBuffer() const {
3586   i::Object obj = *Utils::OpenHandle(this);
3587   if (!obj.IsJSArrayBuffer()) return false;
3588   return !i::JSArrayBuffer::cast(obj).is_shared();
3589 }
3590 
IsArrayBufferView() const3591 bool Value::IsArrayBufferView() const {
3592   return Utils::OpenHandle(this)->IsJSArrayBufferView();
3593 }
3594 
IsTypedArray() const3595 bool Value::IsTypedArray() const {
3596   return Utils::OpenHandle(this)->IsJSTypedArray();
3597 }
3598 
3599 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype)                   \
3600   bool Value::Is##Type##Array() const {                                     \
3601     i::Handle<i::Object> obj = Utils::OpenHandle(this);                     \
3602     return obj->IsJSTypedArray() &&                                         \
3603            i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3604   }
3605 
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3606 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3607 
3608 #undef VALUE_IS_TYPED_ARRAY
3609 
3610 bool Value::IsDataView() const {
3611   return Utils::OpenHandle(this)->IsJSDataView();
3612 }
3613 
IsSharedArrayBuffer() const3614 bool Value::IsSharedArrayBuffer() const {
3615   i::Object obj = *Utils::OpenHandle(this);
3616   if (!obj.IsJSArrayBuffer()) return false;
3617   return i::JSArrayBuffer::cast(obj).is_shared();
3618 }
3619 
IsObject() const3620 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3621 
IsNumber() const3622 bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3623 
IsBigInt() const3624 bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3625 
IsProxy() const3626 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3627 
3628 #define VALUE_IS_SPECIFIC_TYPE(Type, Check)             \
3629   bool Value::Is##Type() const {                        \
3630     i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3631     return obj->Is##Check();                            \
3632   }
3633 
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3634 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3635 VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3636 VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3637 VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3638 VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3639 VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3640 VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3641 VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3642 VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3643 #if V8_ENABLE_WEBASSEMBLY
3644 VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3645 VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3646 #else
3647 bool Value::IsWasmMemoryObject() const { return false; }
3648 bool Value::IsWasmModuleObject() const { return false; }
3649 #endif  // V8_ENABLE_WEBASSEMBLY
3650 VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3651 VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3652 
3653 #undef VALUE_IS_SPECIFIC_TYPE
3654 
3655 bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3656 
IsExternal() const3657 bool Value::IsExternal() const {
3658   i::Object obj = *Utils::OpenHandle(this);
3659   return obj.IsJSExternalObject();
3660 }
3661 
IsInt32() const3662 bool Value::IsInt32() const {
3663   i::Object obj = *Utils::OpenHandle(this);
3664   if (obj.IsSmi()) return true;
3665   if (obj.IsNumber()) {
3666     return i::IsInt32Double(obj.Number());
3667   }
3668   return false;
3669 }
3670 
IsUint32() const3671 bool Value::IsUint32() const {
3672   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3673   if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3674   if (obj->IsNumber()) {
3675     double value = obj->Number();
3676     return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3677            value == i::FastUI2D(i::FastD2UI(value));
3678   }
3679   return false;
3680 }
3681 
IsNativeError() const3682 bool Value::IsNativeError() const {
3683   return Utils::OpenHandle(this)->IsJSError();
3684 }
3685 
IsRegExp() const3686 bool Value::IsRegExp() const {
3687   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3688   return obj->IsJSRegExp();
3689 }
3690 
IsAsyncFunction() const3691 bool Value::IsAsyncFunction() const {
3692   i::Object obj = *Utils::OpenHandle(this);
3693   if (!obj.IsJSFunction()) return false;
3694   i::JSFunction func = i::JSFunction::cast(obj);
3695   return i::IsAsyncFunction(func.shared().kind());
3696 }
3697 
IsGeneratorFunction() const3698 bool Value::IsGeneratorFunction() const {
3699   i::Object obj = *Utils::OpenHandle(this);
3700   if (!obj.IsJSFunction()) return false;
3701   i::JSFunction func = i::JSFunction::cast(obj);
3702   ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
3703   return i::IsGeneratorFunction(func.shared().kind());
3704 }
3705 
IsGeneratorObject() const3706 bool Value::IsGeneratorObject() const {
3707   return Utils::OpenHandle(this)->IsJSGeneratorObject();
3708 }
3709 
IsMapIterator() const3710 bool Value::IsMapIterator() const {
3711   return Utils::OpenHandle(this)->IsJSMapIterator();
3712 }
3713 
IsSetIterator() const3714 bool Value::IsSetIterator() const {
3715   return Utils::OpenHandle(this)->IsJSSetIterator();
3716 }
3717 
IsPromise() const3718 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3719 
IsModuleNamespaceObject() const3720 bool Value::IsModuleNamespaceObject() const {
3721   return Utils::OpenHandle(this)->IsJSModuleNamespace();
3722 }
3723 
ToString(Local<Context> context) const3724 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3725   auto obj = Utils::OpenHandle(this);
3726   if (obj->IsString()) return ToApiHandle<String>(obj);
3727   PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3728   Local<String> result;
3729   has_pending_exception =
3730       !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3731   RETURN_ON_FAILED_EXECUTION(String);
3732   RETURN_ESCAPED(result);
3733 }
3734 
ToDetailString(Local<Context> context) const3735 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3736   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3737   if (obj->IsString()) return ToApiHandle<String>(obj);
3738   PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3739   Local<String> result =
3740       Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3741   RETURN_ON_FAILED_EXECUTION(String);
3742   RETURN_ESCAPED(result);
3743 }
3744 
ToObject(Local<Context> context) const3745 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3746   auto obj = Utils::OpenHandle(this);
3747   if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3748   PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3749   Local<Object> result;
3750   has_pending_exception =
3751       !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3752   RETURN_ON_FAILED_EXECUTION(Object);
3753   RETURN_ESCAPED(result);
3754 }
3755 
ToBigInt(Local<Context> context) const3756 MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3757   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3758   if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3759   PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3760   Local<BigInt> result;
3761   has_pending_exception =
3762       !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3763   RETURN_ON_FAILED_EXECUTION(BigInt);
3764   RETURN_ESCAPED(result);
3765 }
3766 
BooleanValue(Isolate * v8_isolate) const3767 bool Value::BooleanValue(Isolate* v8_isolate) const {
3768   return Utils::OpenHandle(this)->BooleanValue(
3769       reinterpret_cast<i::Isolate*>(v8_isolate));
3770 }
3771 
ToBoolean(Isolate * v8_isolate) const3772 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3773   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3774   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3775   return ToApiHandle<Boolean>(
3776       isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3777 }
3778 
ToNumber(Local<Context> context) const3779 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3780   auto obj = Utils::OpenHandle(this);
3781   if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3782   PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3783   Local<Number> result;
3784   has_pending_exception =
3785       !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3786   RETURN_ON_FAILED_EXECUTION(Number);
3787   RETURN_ESCAPED(result);
3788 }
3789 
ToInteger(Local<Context> context) const3790 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3791   auto obj = Utils::OpenHandle(this);
3792   if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3793   PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3794   Local<Integer> result;
3795   has_pending_exception =
3796       !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3797   RETURN_ON_FAILED_EXECUTION(Integer);
3798   RETURN_ESCAPED(result);
3799 }
3800 
ToInt32(Local<Context> context) const3801 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3802   auto obj = Utils::OpenHandle(this);
3803   if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3804   Local<Int32> result;
3805   PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3806   has_pending_exception =
3807       !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3808   RETURN_ON_FAILED_EXECUTION(Int32);
3809   RETURN_ESCAPED(result);
3810 }
3811 
ToUint32(Local<Context> context) const3812 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3813   auto obj = Utils::OpenHandle(this);
3814   if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3815   Local<Uint32> result;
3816   PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3817   has_pending_exception =
3818       !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3819   RETURN_ON_FAILED_EXECUTION(Uint32);
3820   RETURN_ESCAPED(result);
3821 }
3822 
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3823 i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3824                                         i::ExternalPointer_t encoded_pointer,
3825                                         ExternalPointerTag tag) {
3826   return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3827 }
3828 
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3829 i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3830   return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3831 }
3832 
ShouldThrowOnError(i::Isolate * isolate)3833 bool i::ShouldThrowOnError(i::Isolate* isolate) {
3834   return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3835          i::ShouldThrow::kThrowOnError;
3836 }
3837 
CanHaveInternalField(int instance_type)3838 bool i::CanHaveInternalField(int instance_type) {
3839   return instance_type == i::Internals::kJSObjectType ||
3840          instance_type == i::Internals::kJSSpecialApiObjectType ||
3841          v8::internal::InstanceTypeChecker::IsJSApiObject(
3842              static_cast<v8::internal::InstanceType>(instance_type));
3843 }
3844 
CheckInitializedImpl(v8::Isolate * external_isolate)3845 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3846   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3847   Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3848                   "v8::internal::Internals::CheckInitialized",
3849                   "Isolate is not initialized or V8 has died");
3850 }
3851 
CheckCast(Data * that)3852 void v8::Value::CheckCast(Data* that) {
3853   Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3854 }
3855 
CheckCast(v8::Value * that)3856 void External::CheckCast(v8::Value* that) {
3857   Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3858                   "Value is not an External");
3859 }
3860 
CheckCast(Value * that)3861 void v8::Object::CheckCast(Value* that) {
3862   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3863   Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3864                   "Value is not an Object");
3865 }
3866 
CheckCast(Value * that)3867 void v8::Function::CheckCast(Value* that) {
3868   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3869   Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3870                   "Value is not a Function");
3871 }
3872 
CheckCast(v8::Data * that)3873 void v8::Boolean::CheckCast(v8::Data* that) {
3874   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3875   Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3876                   "Value is not a Boolean");
3877 }
3878 
CheckCast(v8::Data * that)3879 void v8::Name::CheckCast(v8::Data* that) {
3880   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3881   Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3882 }
3883 
CheckCast(v8::Data * that)3884 void v8::String::CheckCast(v8::Data* that) {
3885   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3886   Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3887 }
3888 
CheckCast(v8::Data * that)3889 void v8::Symbol::CheckCast(v8::Data* that) {
3890   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3891   Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3892 }
3893 
CheckCast(v8::Data * that)3894 void v8::Private::CheckCast(v8::Data* that) {
3895   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3896   Utils::ApiCheck(
3897       obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3898       "v8::Private::Cast", "Value is not a Private");
3899 }
3900 
CheckCast(v8::Data * that)3901 void v8::FixedArray::CheckCast(v8::Data* that) {
3902   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3903   Utils::ApiCheck(obj->IsFixedArray(), "v8::FixedArray::Cast",
3904                   "Value is not a FixedArray");
3905 }
3906 
CheckCast(v8::Data * that)3907 void v8::ModuleRequest::CheckCast(v8::Data* that) {
3908   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3909   Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast",
3910                   "Value is not a ModuleRequest");
3911 }
3912 
CheckCast(v8::Data * that)3913 void v8::Module::CheckCast(v8::Data* that) {
3914   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3915   Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3916 }
3917 
CheckCast(v8::Data * that)3918 void v8::Number::CheckCast(v8::Data* that) {
3919   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3920   Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3921                   "Value is not a Number");
3922 }
3923 
CheckCast(v8::Data * that)3924 void v8::Integer::CheckCast(v8::Data* that) {
3925   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3926   Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3927                   "Value is not an Integer");
3928 }
3929 
CheckCast(v8::Data * that)3930 void v8::Int32::CheckCast(v8::Data* that) {
3931   Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast",
3932                   "Value is not a 32-bit signed integer");
3933 }
3934 
CheckCast(v8::Data * that)3935 void v8::Uint32::CheckCast(v8::Data* that) {
3936   Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast",
3937                   "Value is not a 32-bit unsigned integer");
3938 }
3939 
CheckCast(v8::Data * that)3940 void v8::BigInt::CheckCast(v8::Data* that) {
3941   Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3942                   "Value is not a BigInt");
3943 }
3944 
CheckCast(v8::Data * that)3945 void v8::Context::CheckCast(v8::Data* that) {
3946   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3947   Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast",
3948                   "Value is not a Context");
3949 }
3950 
CheckCast(Value * that)3951 void v8::Array::CheckCast(Value* that) {
3952   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3953   Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3954 }
3955 
CheckCast(Value * that)3956 void v8::Map::CheckCast(Value* that) {
3957   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3958   Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3959 }
3960 
CheckCast(Value * that)3961 void v8::Set::CheckCast(Value* that) {
3962   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3963   Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3964 }
3965 
CheckCast(Value * that)3966 void v8::Promise::CheckCast(Value* that) {
3967   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3968                   "Value is not a Promise");
3969 }
3970 
CheckCast(Value * that)3971 void v8::Promise::Resolver::CheckCast(Value* that) {
3972   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3973                   "Value is not a Promise::Resolver");
3974 }
3975 
CheckCast(Value * that)3976 void v8::Proxy::CheckCast(Value* that) {
3977   Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3978 }
3979 
CheckCast(Value * that)3980 void v8::WasmMemoryObject::CheckCast(Value* that) {
3981   Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3982                   "Value is not a WasmMemoryObject");
3983 }
3984 
CheckCast(Value * that)3985 void v8::WasmModuleObject::CheckCast(Value* that) {
3986   Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3987                   "Value is not a WasmModuleObject");
3988 }
3989 
~BackingStore()3990 v8::BackingStore::~BackingStore() {
3991   auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3992   i_this->~BackingStore();  // manually call internal destructor
3993 }
3994 
Data() const3995 void* v8::BackingStore::Data() const {
3996   return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3997 }
3998 
ByteLength() const3999 size_t v8::BackingStore::ByteLength() const {
4000   return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
4001 }
4002 
IsShared() const4003 bool v8::BackingStore::IsShared() const {
4004   return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
4005 }
4006 
4007 // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)4008 std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
4009     v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
4010     size_t byte_length) {
4011   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
4012   API_RCS_SCOPE(i_isolate, ArrayBuffer, BackingStore_Reallocate);
4013   Utils::ApiCheck(byte_length <= i::JSArrayBuffer::kMaxByteLength,
4014                   "v8::BackingStore::Reallocate", "byte_lenght is too large");
4015   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
4016   i::BackingStore* i_backing_store =
4017       reinterpret_cast<i::BackingStore*>(backing_store.get());
4018   if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
4019     i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
4020   }
4021   return backing_store;
4022 }
4023 
4024 // static
EmptyDeleter(void * data,size_t length,void * deleter_data)4025 void v8::BackingStore::EmptyDeleter(void* data, size_t length,
4026                                     void* deleter_data) {
4027   DCHECK_NULL(deleter_data);
4028 }
4029 
GetBackingStore()4030 std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
4031   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4032   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4033   if (!backing_store) {
4034     backing_store =
4035         i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
4036   }
4037   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4038   return std::static_pointer_cast<v8::BackingStore>(bs_base);
4039 }
4040 
Data() const4041 void* v8::ArrayBuffer::Data() const {
4042   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4043   return self->backing_store();
4044 }
4045 
GetBackingStore()4046 std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
4047   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4048   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4049   if (!backing_store) {
4050     backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
4051   }
4052   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4053   return std::static_pointer_cast<v8::BackingStore>(bs_base);
4054 }
4055 
Data() const4056 void* v8::SharedArrayBuffer::Data() const {
4057   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4058   return self->backing_store();
4059 }
4060 
CheckCast(Value * that)4061 void v8::ArrayBuffer::CheckCast(Value* that) {
4062   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4063   Utils::ApiCheck(
4064       obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
4065       "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
4066 }
4067 
CheckCast(Value * that)4068 void v8::ArrayBufferView::CheckCast(Value* that) {
4069   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4070   Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
4071                   "Value is not an ArrayBufferView");
4072 }
4073 
4074 constexpr size_t v8::TypedArray::kMaxLength;
4075 
CheckCast(Value * that)4076 void v8::TypedArray::CheckCast(Value* that) {
4077   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4078   Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
4079                   "Value is not a TypedArray");
4080 }
4081 
4082 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype)                  \
4083   void v8::Type##Array::CheckCast(Value* that) {                             \
4084     i::Handle<i::Object> obj = Utils::OpenHandle(that);                      \
4085     Utils::ApiCheck(                                                         \
4086         obj->IsJSTypedArray() &&                                             \
4087             i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
4088         "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array");      \
4089   }
4090 
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)4091 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4092 
4093 #undef CHECK_TYPED_ARRAY_CAST
4094 
4095 void v8::DataView::CheckCast(Value* that) {
4096   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4097   Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
4098                   "Value is not a DataView");
4099 }
4100 
CheckCast(Value * that)4101 void v8::SharedArrayBuffer::CheckCast(Value* that) {
4102   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4103   Utils::ApiCheck(
4104       obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
4105       "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
4106 }
4107 
CheckCast(v8::Value * that)4108 void v8::Date::CheckCast(v8::Value* that) {
4109   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4110   Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
4111 }
4112 
CheckCast(v8::Value * that)4113 void v8::StringObject::CheckCast(v8::Value* that) {
4114   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4115   Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
4116                   "Value is not a StringObject");
4117 }
4118 
CheckCast(v8::Value * that)4119 void v8::SymbolObject::CheckCast(v8::Value* that) {
4120   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4121   Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
4122                   "Value is not a SymbolObject");
4123 }
4124 
CheckCast(v8::Value * that)4125 void v8::NumberObject::CheckCast(v8::Value* that) {
4126   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4127   Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
4128                   "Value is not a NumberObject");
4129 }
4130 
CheckCast(v8::Value * that)4131 void v8::BigIntObject::CheckCast(v8::Value* that) {
4132   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4133   Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
4134                   "Value is not a BigIntObject");
4135 }
4136 
CheckCast(v8::Value * that)4137 void v8::BooleanObject::CheckCast(v8::Value* that) {
4138   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4139   Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
4140                   "Value is not a BooleanObject");
4141 }
4142 
CheckCast(v8::Value * that)4143 void v8::RegExp::CheckCast(v8::Value* that) {
4144   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4145   Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
4146                   "Value is not a RegExp");
4147 }
4148 
NumberValue(Local<Context> context) const4149 Maybe<double> Value::NumberValue(Local<Context> context) const {
4150   auto obj = Utils::OpenHandle(this);
4151   if (obj->IsNumber()) return Just(obj->Number());
4152   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4153   ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4154            i::HandleScope);
4155   i::Handle<i::Object> num;
4156   has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
4157   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4158   return Just(num->Number());
4159 }
4160 
IntegerValue(Local<Context> context) const4161 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4162   auto obj = Utils::OpenHandle(this);
4163   if (obj->IsNumber()) {
4164     return Just(NumberToInt64(*obj));
4165   }
4166   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4167   ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4168            i::HandleScope);
4169   i::Handle<i::Object> num;
4170   has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4171   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4172   return Just(NumberToInt64(*num));
4173 }
4174 
Int32Value(Local<Context> context) const4175 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4176   auto obj = Utils::OpenHandle(this);
4177   if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4178   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4179   ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4180            i::HandleScope);
4181   i::Handle<i::Object> num;
4182   has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4183   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4184   return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4185                            : static_cast<int32_t>(num->Number()));
4186 }
4187 
Uint32Value(Local<Context> context) const4188 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4189   auto obj = Utils::OpenHandle(this);
4190   if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4191   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4192   ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4193            i::HandleScope);
4194   i::Handle<i::Object> num;
4195   has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4196   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4197   return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4198                            : static_cast<uint32_t>(num->Number()));
4199 }
4200 
ToArrayIndex(Local<Context> context) const4201 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4202   auto self = Utils::OpenHandle(this);
4203   if (self->IsSmi()) {
4204     if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4205     return Local<Uint32>();
4206   }
4207   PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4208   i::Handle<i::Object> string_obj;
4209   has_pending_exception =
4210       !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4211   RETURN_ON_FAILED_EXECUTION(Uint32);
4212   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4213   uint32_t index;
4214   if (str->AsArrayIndex(&index)) {
4215     i::Handle<i::Object> value;
4216     if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4217       value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4218     } else {
4219       value = isolate->factory()->NewNumber(index);
4220     }
4221     RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4222   }
4223   return Local<Uint32>();
4224 }
4225 
Equals(Local<Context> context,Local<Value> that) const4226 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4227   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4228   ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope);
4229   auto self = Utils::OpenHandle(this);
4230   auto other = Utils::OpenHandle(*that);
4231   Maybe<bool> result = i::Object::Equals(isolate, self, other);
4232   has_pending_exception = result.IsNothing();
4233   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4234   return result;
4235 }
4236 
StrictEquals(Local<Value> that) const4237 bool Value::StrictEquals(Local<Value> that) const {
4238   auto self = Utils::OpenHandle(this);
4239   auto other = Utils::OpenHandle(*that);
4240   return self->StrictEquals(*other);
4241 }
4242 
SameValue(Local<Value> that) const4243 bool Value::SameValue(Local<Value> that) const {
4244   auto self = Utils::OpenHandle(this);
4245   auto other = Utils::OpenHandle(*that);
4246   return self->SameValue(*other);
4247 }
4248 
TypeOf(v8::Isolate * external_isolate)4249 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4250   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4251   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4252   API_RCS_SCOPE(isolate, Value, TypeOf);
4253   return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4254 }
4255 
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4256 Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4257                               v8::Local<v8::Object> object) {
4258   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4259   ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4260            i::HandleScope);
4261   auto left = Utils::OpenHandle(this);
4262   auto right = Utils::OpenHandle(*object);
4263   i::Handle<i::Object> result;
4264   has_pending_exception =
4265       !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4266   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4267   return Just(result->IsTrue(isolate));
4268 }
4269 
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4270 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4271                             v8::Local<Value> key, v8::Local<Value> value) {
4272   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4273   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4274   auto self = Utils::OpenHandle(this);
4275   auto key_obj = Utils::OpenHandle(*key);
4276   auto value_obj = Utils::OpenHandle(*value);
4277   has_pending_exception =
4278       i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4279                                     i::StoreOrigin::kMaybeKeyed,
4280                                     Just(i::ShouldThrow::kDontThrow))
4281           .is_null();
4282   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4283   return Just(true);
4284 }
4285 
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4286 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4287                             v8::Local<Value> value) {
4288   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4289   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4290   auto self = Utils::OpenHandle(this);
4291   auto value_obj = Utils::OpenHandle(*value);
4292   has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4293                                                 i::ShouldThrow::kDontThrow)
4294                               .is_null();
4295   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4296   return Just(true);
4297 }
4298 
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4299 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4300                                            v8::Local<Name> key,
4301                                            v8::Local<Value> value) {
4302   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4303   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4304   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4305   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4306 
4307   i::PropertyKey lookup_key(isolate, key_obj);
4308   i::LookupIterator it(isolate, self, lookup_key, i::LookupIterator::OWN);
4309   if (self->IsJSProxy()) {
4310     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4311              i::HandleScope);
4312     Maybe<bool> result =
4313         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4314     has_pending_exception = result.IsNothing();
4315     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4316     return result;
4317   } else {
4318     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4319                        Nothing<bool>(), i::HandleScope);
4320     Maybe<bool> result =
4321         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4322     has_pending_exception = result.IsNothing();
4323     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4324     return result;
4325   }
4326 }
4327 
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4328 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4329                                            uint32_t index,
4330                                            v8::Local<Value> value) {
4331   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4332   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4333   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4334 
4335   i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4336   if (self->IsJSProxy()) {
4337     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4338              i::HandleScope);
4339     Maybe<bool> result =
4340         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4341     has_pending_exception = result.IsNothing();
4342     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4343     return result;
4344   } else {
4345     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4346                        Nothing<bool>(), i::HandleScope);
4347     Maybe<bool> result =
4348         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4349     has_pending_exception = result.IsNothing();
4350     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4351     return result;
4352   }
4353 }
4354 
4355 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4356   PrivateData() : desc() {}
4357   i::PropertyDescriptor desc;
4358 };
4359 
PropertyDescriptor()4360 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4361 
4362 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4363 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4364     : private_(new PrivateData()) {
4365   private_->desc.set_value(Utils::OpenHandle(*value, true));
4366 }
4367 
4368 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4369 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4370                                            bool writable)
4371     : private_(new PrivateData()) {
4372   private_->desc.set_value(Utils::OpenHandle(*value, true));
4373   private_->desc.set_writable(writable);
4374 }
4375 
4376 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4377 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4378                                            v8::Local<v8::Value> set)
4379     : private_(new PrivateData()) {
4380   DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4381   DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4382   private_->desc.set_get(Utils::OpenHandle(*get, true));
4383   private_->desc.set_set(Utils::OpenHandle(*set, true));
4384 }
4385 
~PropertyDescriptor()4386 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4387 
value() const4388 v8::Local<Value> v8::PropertyDescriptor::value() const {
4389   DCHECK(private_->desc.has_value());
4390   return Utils::ToLocal(private_->desc.value());
4391 }
4392 
get() const4393 v8::Local<Value> v8::PropertyDescriptor::get() const {
4394   DCHECK(private_->desc.has_get());
4395   return Utils::ToLocal(private_->desc.get());
4396 }
4397 
set() const4398 v8::Local<Value> v8::PropertyDescriptor::set() const {
4399   DCHECK(private_->desc.has_set());
4400   return Utils::ToLocal(private_->desc.set());
4401 }
4402 
has_value() const4403 bool v8::PropertyDescriptor::has_value() const {
4404   return private_->desc.has_value();
4405 }
has_get() const4406 bool v8::PropertyDescriptor::has_get() const {
4407   return private_->desc.has_get();
4408 }
has_set() const4409 bool v8::PropertyDescriptor::has_set() const {
4410   return private_->desc.has_set();
4411 }
4412 
writable() const4413 bool v8::PropertyDescriptor::writable() const {
4414   DCHECK(private_->desc.has_writable());
4415   return private_->desc.writable();
4416 }
4417 
has_writable() const4418 bool v8::PropertyDescriptor::has_writable() const {
4419   return private_->desc.has_writable();
4420 }
4421 
set_enumerable(bool enumerable)4422 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4423   private_->desc.set_enumerable(enumerable);
4424 }
4425 
enumerable() const4426 bool v8::PropertyDescriptor::enumerable() const {
4427   DCHECK(private_->desc.has_enumerable());
4428   return private_->desc.enumerable();
4429 }
4430 
has_enumerable() const4431 bool v8::PropertyDescriptor::has_enumerable() const {
4432   return private_->desc.has_enumerable();
4433 }
4434 
set_configurable(bool configurable)4435 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4436   private_->desc.set_configurable(configurable);
4437 }
4438 
configurable() const4439 bool v8::PropertyDescriptor::configurable() const {
4440   DCHECK(private_->desc.has_configurable());
4441   return private_->desc.configurable();
4442 }
4443 
has_configurable() const4444 bool v8::PropertyDescriptor::has_configurable() const {
4445   return private_->desc.has_configurable();
4446 }
4447 
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4448 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4449                                           v8::Local<Name> key,
4450                                           v8::Local<Value> value,
4451                                           v8::PropertyAttribute attributes) {
4452   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4453   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4454   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4455   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4456 
4457   i::PropertyDescriptor desc;
4458   desc.set_writable(!(attributes & v8::ReadOnly));
4459   desc.set_enumerable(!(attributes & v8::DontEnum));
4460   desc.set_configurable(!(attributes & v8::DontDelete));
4461   desc.set_value(value_obj);
4462 
4463   if (self->IsJSProxy()) {
4464     ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4465              i::HandleScope);
4466     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4467         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4468     // Even though we said kDontThrow, there might be accessors that do throw.
4469     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4470     return success;
4471   } else {
4472     // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4473     // a script.
4474     ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4475                        Nothing<bool>(), i::HandleScope);
4476     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4477         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4478     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4479     return success;
4480   }
4481 }
4482 
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4483 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4484                                        v8::Local<Name> key,
4485                                        PropertyDescriptor& descriptor) {
4486   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4487   ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4488            i::HandleScope);
4489   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4490   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4491 
4492   Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4493       isolate, self, key_obj, &descriptor.get_private()->desc,
4494       Just(i::kDontThrow));
4495   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4496   return success;
4497 }
4498 
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4499 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4500                                    Local<Value> value) {
4501   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4502   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4503                      i::HandleScope);
4504   auto self = Utils::OpenHandle(this);
4505   auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4506   auto value_obj = Utils::OpenHandle(*value);
4507   if (self->IsJSProxy()) {
4508     i::PropertyDescriptor desc;
4509     desc.set_writable(true);
4510     desc.set_enumerable(false);
4511     desc.set_configurable(true);
4512     desc.set_value(value_obj);
4513     return i::JSProxy::SetPrivateSymbol(
4514         isolate, i::Handle<i::JSProxy>::cast(self),
4515         i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4516   }
4517   auto js_object = i::Handle<i::JSObject>::cast(self);
4518   i::LookupIterator it(isolate, js_object, key_obj, js_object);
4519   has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4520                               &it, value_obj, i::DONT_ENUM)
4521                               .is_null();
4522   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4523   return Just(true);
4524 }
4525 
Get(Local<v8::Context> context,Local<Value> key)4526 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4527                                   Local<Value> key) {
4528   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4529   auto self = Utils::OpenHandle(this);
4530   auto key_obj = Utils::OpenHandle(*key);
4531   i::Handle<i::Object> result;
4532   has_pending_exception =
4533       !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4534   RETURN_ON_FAILED_EXECUTION(Value);
4535   RETURN_ESCAPED(Utils::ToLocal(result));
4536 }
4537 
Get(Local<Context> context,uint32_t index)4538 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4539   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4540   auto self = Utils::OpenHandle(this);
4541   i::Handle<i::Object> result;
4542   has_pending_exception =
4543       !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4544   RETURN_ON_FAILED_EXECUTION(Value);
4545   RETURN_ESCAPED(Utils::ToLocal(result));
4546 }
4547 
GetPrivate(Local<Context> context,Local<Private> key)4548 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4549                                          Local<Private> key) {
4550   return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4551 }
4552 
GetPropertyAttributes(Local<Context> context,Local<Value> key)4553 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4554     Local<Context> context, Local<Value> key) {
4555   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4556   ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4557            Nothing<PropertyAttribute>(), i::HandleScope);
4558   auto self = Utils::OpenHandle(this);
4559   auto key_obj = Utils::OpenHandle(*key);
4560   if (!key_obj->IsName()) {
4561     has_pending_exception =
4562         !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4563     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4564   }
4565   auto key_name = i::Handle<i::Name>::cast(key_obj);
4566   auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4567   has_pending_exception = result.IsNothing();
4568   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4569   if (result.FromJust() == i::ABSENT) {
4570     return Just(static_cast<PropertyAttribute>(i::NONE));
4571   }
4572   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4573 }
4574 
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4575 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4576                                                        Local<Name> key) {
4577   PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4578   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4579   i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4580 
4581   i::PropertyDescriptor desc;
4582   Maybe<bool> found =
4583       i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4584   has_pending_exception = found.IsNothing();
4585   RETURN_ON_FAILED_EXECUTION(Value);
4586   if (!found.FromJust()) {
4587     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4588   }
4589   RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4590 }
4591 
GetPrototype()4592 Local<Value> v8::Object::GetPrototype() {
4593   auto self = Utils::OpenHandle(this);
4594   auto isolate = self->GetIsolate();
4595   i::PrototypeIterator iter(isolate, self);
4596   return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4597 }
4598 
SetPrototype(Local<Context> context,Local<Value> value)4599 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4600                                      Local<Value> value) {
4601   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4602   auto self = Utils::OpenHandle(this);
4603   auto value_obj = Utils::OpenHandle(*value);
4604   if (self->IsJSProxy()) {
4605     ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4606              i::HandleScope);
4607     // We do not allow exceptions thrown while setting the prototype
4608     // to propagate outside.
4609     TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4610     auto result =
4611         i::JSProxy::SetPrototype(isolate, i::Handle<i::JSProxy>::cast(self),
4612                                  value_obj, false, i::kThrowOnError);
4613     has_pending_exception = result.IsNothing();
4614     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4615   } else {
4616     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4617     auto result =
4618         i::JSObject::SetPrototype(isolate, i::Handle<i::JSObject>::cast(self),
4619                                   value_obj, false, i::kThrowOnError);
4620     if (result.IsNothing()) {
4621       isolate->clear_pending_exception();
4622       return Nothing<bool>();
4623     }
4624   }
4625   return Just(true);
4626 }
4627 
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4628 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4629     v8::Local<FunctionTemplate> tmpl) {
4630   auto self = Utils::OpenHandle(this);
4631   auto isolate = self->GetIsolate();
4632   i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4633   auto tmpl_info = *Utils::OpenHandle(*tmpl);
4634   while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4635     iter.Advance();
4636     if (iter.IsAtEnd()) return Local<Object>();
4637     if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4638   }
4639   // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4640   return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4641 }
4642 
GetPropertyNames(Local<Context> context)4643 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4644   return GetPropertyNames(
4645       context, v8::KeyCollectionMode::kIncludePrototypes,
4646       static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4647       v8::IndexFilter::kIncludeIndices);
4648 }
4649 
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4650 MaybeLocal<Array> v8::Object::GetPropertyNames(
4651     Local<Context> context, KeyCollectionMode mode,
4652     PropertyFilter property_filter, IndexFilter index_filter,
4653     KeyConversionMode key_conversion) {
4654   PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4655   auto self = Utils::OpenHandle(this);
4656   i::Handle<i::FixedArray> value;
4657   i::KeyAccumulator accumulator(
4658       isolate, static_cast<i::KeyCollectionMode>(mode),
4659       static_cast<i::PropertyFilter>(property_filter));
4660   accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4661   has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4662   RETURN_ON_FAILED_EXECUTION(Array);
4663   value =
4664       accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4665   DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4666          self->map().EnumLength() == 0 ||
4667          self->map().instance_descriptors(isolate).enum_cache().keys() !=
4668              *value);
4669   auto result = isolate->factory()->NewJSArrayWithElements(value);
4670   RETURN_ESCAPED(Utils::ToLocal(result));
4671 }
4672 
GetOwnPropertyNames(Local<Context> context)4673 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4674   return GetOwnPropertyNames(
4675       context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4676 }
4677 
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4678 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4679     Local<Context> context, PropertyFilter filter,
4680     KeyConversionMode key_conversion) {
4681   return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4682                           v8::IndexFilter::kIncludeIndices, key_conversion);
4683 }
4684 
ObjectProtoToString(Local<Context> context)4685 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4686   PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4687   auto self = Utils::OpenHandle(this);
4688   Local<Value> result;
4689   has_pending_exception = !ToLocal<Value>(
4690       i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4691                                 nullptr),
4692       &result);
4693   RETURN_ON_FAILED_EXECUTION(String);
4694   RETURN_ESCAPED(Local<String>::Cast(result));
4695 }
4696 
GetConstructorName()4697 Local<String> v8::Object::GetConstructorName() {
4698   auto self = Utils::OpenHandle(this);
4699   // TODO(v8:12547): Support shared objects.
4700   DCHECK(!self->InSharedHeap());
4701   i::Handle<i::String> name =
4702       i::JSReceiver::GetConstructorName(self->GetIsolate(), self);
4703   return Utils::ToLocal(name);
4704 }
4705 
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4706 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4707                                           IntegrityLevel level) {
4708   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4709   ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4710            i::HandleScope);
4711   auto self = Utils::OpenHandle(this);
4712   i::JSReceiver::IntegrityLevel i_level =
4713       level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4714   Maybe<bool> result =
4715       i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4716   has_pending_exception = result.IsNothing();
4717   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4718   return result;
4719 }
4720 
Delete(Local<Context> context,Local<Value> key)4721 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4722   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4723   auto self = Utils::OpenHandle(this);
4724   auto key_obj = Utils::OpenHandle(*key);
4725   if (self->IsJSProxy()) {
4726     ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4727     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4728         isolate, self, key_obj, i::LanguageMode::kSloppy);
4729     has_pending_exception = result.IsNothing();
4730     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4731     return result;
4732   } else {
4733     // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4734     // a script.
4735     ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4736                        i::HandleScope);
4737     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4738         isolate, self, key_obj, i::LanguageMode::kSloppy);
4739     has_pending_exception = result.IsNothing();
4740     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4741     return result;
4742   }
4743 }
4744 
DeletePrivate(Local<Context> context,Local<Private> key)4745 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4746                                       Local<Private> key) {
4747   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4748   // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4749   // any author script.
4750   ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4751                      i::HandleScope);
4752   auto self = Utils::OpenHandle(this);
4753   auto key_obj = Utils::OpenHandle(*key);
4754   Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4755       isolate, self, key_obj, i::LanguageMode::kSloppy);
4756   has_pending_exception = result.IsNothing();
4757   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4758   return result;
4759 }
4760 
Has(Local<Context> context,Local<Value> key)4761 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4762   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4763   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4764   auto self = Utils::OpenHandle(this);
4765   auto key_obj = Utils::OpenHandle(*key);
4766   Maybe<bool> maybe = Nothing<bool>();
4767   // Check if the given key is an array index.
4768   uint32_t index = 0;
4769   if (key_obj->ToArrayIndex(&index)) {
4770     maybe = i::JSReceiver::HasElement(isolate, self, index);
4771   } else {
4772     // Convert the key to a name - possibly by calling back into JavaScript.
4773     i::Handle<i::Name> name;
4774     if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4775       maybe = i::JSReceiver::HasProperty(isolate, self, name);
4776     }
4777   }
4778   has_pending_exception = maybe.IsNothing();
4779   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4780   return maybe;
4781 }
4782 
HasPrivate(Local<Context> context,Local<Private> key)4783 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4784   return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4785 }
4786 
Delete(Local<Context> context,uint32_t index)4787 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4788   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4789   ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4790   auto self = Utils::OpenHandle(this);
4791   Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4792   has_pending_exception = result.IsNothing();
4793   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4794   return result;
4795 }
4796 
Has(Local<Context> context,uint32_t index)4797 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4798   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4799   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4800   auto self = Utils::OpenHandle(this);
4801   auto maybe = i::JSReceiver::HasElement(isolate, self, index);
4802   has_pending_exception = maybe.IsNothing();
4803   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4804   return maybe;
4805 }
4806 
4807 template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4808 static Maybe<bool> ObjectSetAccessor(
4809     Local<Context> context, Object* self, Local<Name> name, Getter getter,
4810     Setter setter, Data data, AccessControl settings,
4811     PropertyAttribute attributes, bool is_special_data_property,
4812     bool replace_on_access, SideEffectType getter_side_effect_type,
4813     SideEffectType setter_side_effect_type) {
4814   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4815   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4816                      i::HandleScope);
4817   if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4818   i::Handle<i::JSObject> obj =
4819       i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4820   v8::Local<AccessorSignature> signature;
4821   i::Handle<i::AccessorInfo> info =
4822       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4823                        is_special_data_property, replace_on_access);
4824   info->set_getter_side_effect_type(getter_side_effect_type);
4825   info->set_setter_side_effect_type(setter_side_effect_type);
4826   if (info.is_null()) return Nothing<bool>();
4827   bool fast = obj->HasFastProperties();
4828   i::Handle<i::Object> result;
4829 
4830   i::Handle<i::Name> accessor_name(info->name(), isolate);
4831   i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4832   has_pending_exception =
4833       !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4834            .ToHandle(&result);
4835   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4836   if (result->IsUndefined(isolate)) return Just(false);
4837   if (fast) {
4838     i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4839   }
4840   return Just(true);
4841 }
4842 
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4843 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4844                                 AccessorNameGetterCallback getter,
4845                                 AccessorNameSetterCallback setter,
4846                                 MaybeLocal<Value> data, AccessControl settings,
4847                                 PropertyAttribute attribute,
4848                                 SideEffectType getter_side_effect_type,
4849                                 SideEffectType setter_side_effect_type) {
4850   return ObjectSetAccessor(context, this, name, getter, setter,
4851                            data.FromMaybe(Local<Value>()), settings, attribute,
4852                            i::FLAG_disable_old_api_accessors, false,
4853                            getter_side_effect_type, setter_side_effect_type);
4854 }
4855 
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4856 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4857                                  Local<Function> setter,
4858                                  PropertyAttribute attribute,
4859                                  AccessControl settings) {
4860   // TODO(verwaest): Remove |settings|.
4861   DCHECK_EQ(v8::DEFAULT, settings);
4862   auto self = Utils::OpenHandle(this);
4863   i::Isolate* isolate = self->GetIsolate();
4864   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4865   i::HandleScope scope(isolate);
4866   if (!self->IsJSObject()) return;
4867   i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4868   i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4869   if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4870   i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4871                               v8::Utils::OpenHandle(*name), getter_i, setter_i,
4872                               static_cast<i::PropertyAttributes>(attribute));
4873 }
4874 
SetNativeDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4875 Maybe<bool> Object::SetNativeDataProperty(
4876     v8::Local<v8::Context> context, v8::Local<Name> name,
4877     AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4878     v8::Local<Value> data, PropertyAttribute attributes,
4879     SideEffectType getter_side_effect_type,
4880     SideEffectType setter_side_effect_type) {
4881   return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4882                            attributes, true, false, getter_side_effect_type,
4883                            setter_side_effect_type);
4884 }
4885 
SetLazyDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4886 Maybe<bool> Object::SetLazyDataProperty(
4887     v8::Local<v8::Context> context, v8::Local<Name> name,
4888     AccessorNameGetterCallback getter, v8::Local<Value> data,
4889     PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4890     SideEffectType setter_side_effect_type) {
4891   return ObjectSetAccessor(context, this, name, getter,
4892                            static_cast<AccessorNameSetterCallback>(nullptr),
4893                            data, DEFAULT, attributes, true, true,
4894                            getter_side_effect_type, setter_side_effect_type);
4895 }
4896 
HasOwnProperty(Local<Context> context,Local<Name> key)4897 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4898                                        Local<Name> key) {
4899   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4900   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4901            i::HandleScope);
4902   auto self = Utils::OpenHandle(this);
4903   auto key_val = Utils::OpenHandle(*key);
4904   auto result = i::JSReceiver::HasOwnProperty(isolate, self, key_val);
4905   has_pending_exception = result.IsNothing();
4906   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4907   return result;
4908 }
4909 
HasOwnProperty(Local<Context> context,uint32_t index)4910 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4911   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4912   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4913            i::HandleScope);
4914   auto self = Utils::OpenHandle(this);
4915   auto result = i::JSReceiver::HasOwnProperty(isolate, self, index);
4916   has_pending_exception = result.IsNothing();
4917   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4918   return result;
4919 }
4920 
HasRealNamedProperty(Local<Context> context,Local<Name> key)4921 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4922                                              Local<Name> key) {
4923   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4924   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4925                      Nothing<bool>(), i::HandleScope);
4926   auto self = Utils::OpenHandle(this);
4927   if (!self->IsJSObject()) return Just(false);
4928   auto key_val = Utils::OpenHandle(*key);
4929   auto result = i::JSObject::HasRealNamedProperty(
4930       isolate, i::Handle<i::JSObject>::cast(self), key_val);
4931   has_pending_exception = result.IsNothing();
4932   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4933   return result;
4934 }
4935 
HasRealIndexedProperty(Local<Context> context,uint32_t index)4936 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4937                                                uint32_t index) {
4938   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4939   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4940                      Nothing<bool>(), i::HandleScope);
4941   auto self = Utils::OpenHandle(this);
4942   if (!self->IsJSObject()) return Just(false);
4943   auto result = i::JSObject::HasRealElementProperty(
4944       isolate, i::Handle<i::JSObject>::cast(self), index);
4945   has_pending_exception = result.IsNothing();
4946   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4947   return result;
4948 }
4949 
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4950 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4951                                                      Local<Name> key) {
4952   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4953   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
4954                      Nothing<bool>(), i::HandleScope);
4955   auto self = Utils::OpenHandle(this);
4956   if (!self->IsJSObject()) return Just(false);
4957   auto key_val = Utils::OpenHandle(*key);
4958   auto result = i::JSObject::HasRealNamedCallbackProperty(
4959       isolate, i::Handle<i::JSObject>::cast(self), key_val);
4960   has_pending_exception = result.IsNothing();
4961   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4962   return result;
4963 }
4964 
HasNamedLookupInterceptor() const4965 bool v8::Object::HasNamedLookupInterceptor() const {
4966   auto self = *Utils::OpenHandle(this);
4967   if (self.IsJSObject()) return false;
4968   return i::JSObject::cast(self).HasNamedInterceptor();
4969 }
4970 
HasIndexedLookupInterceptor() const4971 bool v8::Object::HasIndexedLookupInterceptor() const {
4972   auto self = *Utils::OpenHandle(this);
4973   if (self.IsJSObject()) return false;
4974   return i::JSObject::cast(self).HasIndexedInterceptor();
4975 }
4976 
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4977 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4978     Local<Context> context, Local<Name> key) {
4979   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4980                         Value);
4981   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4982   if (!self->IsJSObject()) return MaybeLocal<Value>();
4983   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4984   i::PrototypeIterator iter(isolate, self);
4985   if (iter.IsAtEnd()) return MaybeLocal<Value>();
4986   i::Handle<i::JSReceiver> proto =
4987       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4988   i::PropertyKey lookup_key(isolate, key_obj);
4989   i::LookupIterator it(isolate, self, lookup_key, proto,
4990                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4991   Local<Value> result;
4992   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4993   RETURN_ON_FAILED_EXECUTION(Value);
4994   if (!it.IsFound()) return MaybeLocal<Value>();
4995   RETURN_ESCAPED(result);
4996 }
4997 
4998 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4999 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
5000     Local<Context> context, Local<Name> key) {
5001   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5002   ENTER_V8(isolate, context, Object,
5003            GetRealNamedPropertyAttributesInPrototypeChain,
5004            Nothing<PropertyAttribute>(), i::HandleScope);
5005   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5006   if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
5007   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5008   i::PrototypeIterator iter(isolate, self);
5009   if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
5010   i::Handle<i::JSReceiver> proto =
5011       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5012   i::PropertyKey lookup_key(isolate, key_obj);
5013   i::LookupIterator it(isolate, self, lookup_key, proto,
5014                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5015   Maybe<i::PropertyAttributes> result =
5016       i::JSReceiver::GetPropertyAttributes(&it);
5017   has_pending_exception = result.IsNothing();
5018   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5019   if (!it.IsFound()) return Nothing<PropertyAttribute>();
5020   if (result.FromJust() == i::ABSENT) return Just(None);
5021   return Just(static_cast<PropertyAttribute>(result.FromJust()));
5022 }
5023 
GetRealNamedProperty(Local<Context> context,Local<Name> key)5024 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
5025                                                    Local<Name> key) {
5026   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
5027   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5028   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5029   i::PropertyKey lookup_key(isolate, key_obj);
5030   i::LookupIterator it(isolate, self, lookup_key, self,
5031                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5032   Local<Value> result;
5033   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5034   RETURN_ON_FAILED_EXECUTION(Value);
5035   if (!it.IsFound()) return MaybeLocal<Value>();
5036   RETURN_ESCAPED(result);
5037 }
5038 
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)5039 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5040     Local<Context> context, Local<Name> key) {
5041   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5042   ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
5043            Nothing<PropertyAttribute>(), i::HandleScope);
5044   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5045   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5046   i::PropertyKey lookup_key(isolate, key_obj);
5047   i::LookupIterator it(isolate, self, lookup_key, self,
5048                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5049   auto result = i::JSReceiver::GetPropertyAttributes(&it);
5050   has_pending_exception = result.IsNothing();
5051   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5052   if (!it.IsFound()) return Nothing<PropertyAttribute>();
5053   if (result.FromJust() == i::ABSENT) {
5054     return Just(static_cast<PropertyAttribute>(i::NONE));
5055   }
5056   return Just<PropertyAttribute>(
5057       static_cast<PropertyAttribute>(result.FromJust()));
5058 }
5059 
Clone()5060 Local<v8::Object> v8::Object::Clone() {
5061   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5062   auto isolate = self->GetIsolate();
5063   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5064   i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
5065   return Utils::ToLocal(result);
5066 }
5067 
5068 namespace {
CreationContextImpl(i::Handle<i::JSReceiver> self)5069 Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) {
5070   i::Handle<i::Context> context;
5071   if (self->GetCreationContext().ToHandle(&context)) {
5072     return Utils::ToLocal(context);
5073   }
5074 
5075   return Local<v8::Context>();
5076 }
5077 }  // namespace
5078 
CreationContext()5079 Local<v8::Context> v8::Object::CreationContext() {
5080   auto self = Utils::OpenHandle(this);
5081   return CreationContextImpl(self);
5082 }
5083 
CreationContext(const PersistentBase<Object> & object)5084 Local<v8::Context> v8::Object::CreationContext(
5085     const PersistentBase<Object>& object) {
5086   auto self = Utils::OpenHandle(object.val_);
5087   return CreationContextImpl(self);
5088 }
5089 
GetCreationContext()5090 MaybeLocal<v8::Context> v8::Object::GetCreationContext() {
5091   auto self = Utils::OpenHandle(this);
5092   i::Handle<i::Context> context;
5093   if (self->GetCreationContext().ToHandle(&context)) {
5094     return Utils::ToLocal(context);
5095   }
5096   return MaybeLocal<v8::Context>();
5097 }
5098 
GetCreationContextChecked()5099 Local<v8::Context> v8::Object::GetCreationContextChecked() {
5100   Local<Context> context;
5101   Utils::ApiCheck(GetCreationContext().ToLocal(&context),
5102                   "v8::Object::GetCreationContextChecked",
5103                   "No creation context available");
5104   return context;
5105 }
5106 
GetIdentityHash()5107 int v8::Object::GetIdentityHash() {
5108   i::DisallowGarbageCollection no_gc;
5109   auto self = Utils::OpenHandle(this);
5110   auto isolate = self->GetIsolate();
5111   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
5112   i::HandleScope scope(isolate);
5113   return self->GetOrCreateIdentityHash(isolate).value();
5114 }
5115 
IsCallable() const5116 bool v8::Object::IsCallable() const {
5117   auto self = Utils::OpenHandle(this);
5118   return self->IsCallable();
5119 }
5120 
IsConstructor() const5121 bool v8::Object::IsConstructor() const {
5122   auto self = Utils::OpenHandle(this);
5123   return self->IsConstructor();
5124 }
5125 
IsApiWrapper() const5126 bool v8::Object::IsApiWrapper() const {
5127   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5128   // Objects with embedder fields can wrap API objects.
5129   return self->MayHaveEmbedderFields();
5130 }
5131 
IsUndetectable() const5132 bool v8::Object::IsUndetectable() const {
5133   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5134   return self->IsUndetectable();
5135 }
5136 
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5137 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5138                                          Local<Value> recv, int argc,
5139                                          Local<Value> argv[]) {
5140   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5141   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5142   ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5143            InternalEscapableScope);
5144   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5145   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5146                                              isolate);
5147   auto self = Utils::OpenHandle(this);
5148   auto recv_obj = Utils::OpenHandle(*recv);
5149   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5150   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5151   Local<Value> result;
5152   has_pending_exception = !ToLocal<Value>(
5153       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5154   RETURN_ON_FAILED_EXECUTION(Value);
5155   RETURN_ESCAPED(result);
5156 }
5157 
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5158 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5159                                             Local<Value> argv[]) {
5160   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5161   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5162   ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5163            InternalEscapableScope);
5164   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5165   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5166                                              isolate);
5167   auto self = Utils::OpenHandle(this);
5168   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5169   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5170   Local<Value> result;
5171   has_pending_exception = !ToLocal<Value>(
5172       i::Execution::New(isolate, self, self, argc, args), &result);
5173   RETURN_ON_FAILED_EXECUTION(Value);
5174   RETURN_ESCAPED(result);
5175 }
5176 
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)5177 MaybeLocal<Function> Function::New(Local<Context> context,
5178                                    FunctionCallback callback, Local<Value> data,
5179                                    int length, ConstructorBehavior behavior,
5180                                    SideEffectType side_effect_type) {
5181   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5182   API_RCS_SCOPE(isolate, Function, New);
5183   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5184   auto templ =
5185       FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
5186                           behavior, true, Local<Private>(), side_effect_type);
5187   return templ->GetFunction(context);
5188 }
5189 
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5190 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5191                                          v8::Local<v8::Value> argv[]) const {
5192   return NewInstanceWithSideEffectType(context, argc, argv,
5193                                        SideEffectType::kHasSideEffect);
5194 }
5195 
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const5196 MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
5197     Local<Context> context, int argc, v8::Local<v8::Value> argv[],
5198     SideEffectType side_effect_type) const {
5199   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5200   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5201   ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5202            InternalEscapableScope);
5203   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5204   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5205                                              isolate);
5206   auto self = Utils::OpenHandle(this);
5207   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5208   bool should_set_has_no_side_effect =
5209       side_effect_type == SideEffectType::kHasNoSideEffect &&
5210       isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
5211   if (should_set_has_no_side_effect) {
5212     CHECK(self->IsJSFunction() &&
5213           i::JSFunction::cast(*self).shared().IsApiFunction());
5214     i::Object obj =
5215         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5216             kAcquireLoad);
5217     if (obj.IsCallHandlerInfo()) {
5218       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5219       if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
5220         handler_info.SetNextCallHasNoSideEffect();
5221       }
5222     }
5223   }
5224   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5225   Local<Object> result;
5226   has_pending_exception = !ToLocal<Object>(
5227       i::Execution::New(isolate, self, self, argc, args), &result);
5228   if (should_set_has_no_side_effect) {
5229     i::Object obj =
5230         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5231             kAcquireLoad);
5232     if (obj.IsCallHandlerInfo()) {
5233       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5234       if (has_pending_exception) {
5235         // Restore the map if an exception prevented restoration.
5236         handler_info.NextCallHasNoSideEffect();
5237       } else {
5238         DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
5239                handler_info.IsSideEffectFreeCallHandlerInfo());
5240       }
5241     }
5242   }
5243   RETURN_ON_FAILED_EXECUTION(Object);
5244   RETURN_ESCAPED(result);
5245 }
5246 
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5247 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5248                                      v8::Local<v8::Value> recv, int argc,
5249                                      v8::Local<v8::Value> argv[]) {
5250   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5251   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5252   ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5253            InternalEscapableScope);
5254   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5255   i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5256                                              isolate);
5257   auto self = Utils::OpenHandle(this);
5258   Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
5259                   "Function to be called is a null pointer");
5260   i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5261   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5262   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5263   Local<Value> result;
5264   has_pending_exception = !ToLocal<Value>(
5265       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5266   RETURN_ON_FAILED_EXECUTION(Value);
5267   RETURN_ESCAPED(result);
5268 }
5269 
SetName(v8::Local<v8::String> name)5270 void Function::SetName(v8::Local<v8::String> name) {
5271   auto self = Utils::OpenHandle(this);
5272   if (!self->IsJSFunction()) return;
5273   auto func = i::Handle<i::JSFunction>::cast(self);
5274   ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
5275   func->shared().SetName(*Utils::OpenHandle(*name));
5276 }
5277 
GetName() const5278 Local<Value> Function::GetName() const {
5279   auto self = Utils::OpenHandle(this);
5280   i::Isolate* isolate = self->GetIsolate();
5281   if (self->IsJSBoundFunction()) {
5282     auto func = i::Handle<i::JSBoundFunction>::cast(self);
5283     i::Handle<i::Object> name;
5284     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5285                                      i::JSBoundFunction::GetName(isolate, func),
5286                                      Local<Value>());
5287     return Utils::ToLocal(name);
5288   }
5289   if (self->IsJSFunction()) {
5290     auto func = i::Handle<i::JSFunction>::cast(self);
5291     return Utils::ToLocal(handle(func->shared().Name(), isolate));
5292   }
5293   return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5294 }
5295 
GetInferredName() const5296 Local<Value> Function::GetInferredName() const {
5297   auto self = Utils::OpenHandle(this);
5298   if (!self->IsJSFunction()) {
5299     return ToApiHandle<Primitive>(
5300         self->GetIsolate()->factory()->undefined_value());
5301   }
5302   auto func = i::Handle<i::JSFunction>::cast(self);
5303   return Utils::ToLocal(
5304       i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5305 }
5306 
GetDebugName() const5307 Local<Value> Function::GetDebugName() const {
5308   auto self = Utils::OpenHandle(this);
5309   if (!self->IsJSFunction()) {
5310     return ToApiHandle<Primitive>(
5311         self->GetIsolate()->factory()->undefined_value());
5312   }
5313   auto func = i::Handle<i::JSFunction>::cast(self);
5314   i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5315   return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5316 }
5317 
GetScriptOrigin() const5318 ScriptOrigin Function::GetScriptOrigin() const {
5319   auto self = Utils::OpenHandle(this);
5320   auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate());
5321   if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>());
5322   auto func = i::Handle<i::JSFunction>::cast(self);
5323   if (func->shared().script().IsScript()) {
5324     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5325                                 func->GetIsolate());
5326     return GetScriptOriginForScript(func->GetIsolate(), script);
5327   }
5328   return v8::ScriptOrigin(isolate, Local<Value>());
5329 }
5330 
5331 const int Function::kLineOffsetNotFound = -1;
5332 
GetScriptLineNumber() const5333 int Function::GetScriptLineNumber() const {
5334   auto self = Utils::OpenHandle(this);
5335   if (!self->IsJSFunction()) {
5336     return kLineOffsetNotFound;
5337   }
5338   auto func = i::Handle<i::JSFunction>::cast(self);
5339   if (func->shared().script().IsScript()) {
5340     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5341                                 func->GetIsolate());
5342     return i::Script::GetLineNumber(script, func->shared().StartPosition());
5343   }
5344   return kLineOffsetNotFound;
5345 }
5346 
GetScriptColumnNumber() const5347 int Function::GetScriptColumnNumber() const {
5348   auto self = Utils::OpenHandle(this);
5349   if (!self->IsJSFunction()) {
5350     return kLineOffsetNotFound;
5351   }
5352   auto func = i::Handle<i::JSFunction>::cast(self);
5353   if (func->shared().script().IsScript()) {
5354     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5355                                 func->GetIsolate());
5356     return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5357   }
5358   return kLineOffsetNotFound;
5359 }
5360 
GetUnboundScript() const5361 MaybeLocal<UnboundScript> Function::GetUnboundScript() const {
5362   i::Handle<i::Object> self = Utils::OpenHandle(this);
5363   if (!self->IsJSFunction()) return MaybeLocal<UnboundScript>();
5364   i::SharedFunctionInfo sfi = i::JSFunction::cast(*self).shared();
5365   i::Isolate* isolate = sfi.GetIsolate();
5366   return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
5367 }
5368 
ScriptId() const5369 int Function::ScriptId() const {
5370   i::JSReceiver self = *Utils::OpenHandle(this);
5371   if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
5372   auto func = i::JSFunction::cast(self);
5373   if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
5374   return i::Script::cast(func.shared().script()).id();
5375 }
5376 
GetBoundFunction() const5377 Local<v8::Value> Function::GetBoundFunction() const {
5378   auto self = Utils::OpenHandle(this);
5379   if (self->IsJSBoundFunction()) {
5380     auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5381     auto bound_target_function = i::handle(
5382         bound_function->bound_target_function(), bound_function->GetIsolate());
5383     return Utils::CallableToLocal(bound_target_function);
5384   }
5385   return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5386 }
5387 
FunctionProtoToString(Local<Context> context)5388 MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5389   PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5390   auto self = Utils::OpenHandle(this);
5391   Local<Value> result;
5392   has_pending_exception = !ToLocal<Value>(
5393       i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5394                                 nullptr),
5395       &result);
5396   RETURN_ON_FAILED_EXECUTION(String);
5397   RETURN_ESCAPED(Local<String>::Cast(result));
5398 }
5399 
GetIdentityHash()5400 int Name::GetIdentityHash() {
5401   auto self = Utils::OpenHandle(this);
5402   return static_cast<int>(self->EnsureHash());
5403 }
5404 
Length() const5405 int String::Length() const {
5406   i::Handle<i::String> str = Utils::OpenHandle(this);
5407   return str->length();
5408 }
5409 
IsOneByte() const5410 bool String::IsOneByte() const {
5411   i::Handle<i::String> str = Utils::OpenHandle(this);
5412   return str->IsOneByteRepresentation();
5413 }
5414 
5415 // Helpers for ContainsOnlyOneByteHelper
5416 template <size_t size>
5417 struct OneByteMask;
5418 template <>
5419 struct OneByteMask<4> {
5420   static const uint32_t value = 0xFF00FF00;
5421 };
5422 template <>
5423 struct OneByteMask<8> {
5424   static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5425 };
5426 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5427 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5428 static inline bool Unaligned(const uint16_t* chars) {
5429   return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5430 }
5431 
Align(const uint16_t * chars)5432 static inline const uint16_t* Align(const uint16_t* chars) {
5433   return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5434                                      ~kAlignmentMask);
5435 }
5436 
5437 class ContainsOnlyOneByteHelper {
5438  public:
ContainsOnlyOneByteHelper()5439   ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5440   ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5441   ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5442       delete;
Check(i::String string)5443   bool Check(i::String string) {
5444     i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5445     if (cons_string.is_null()) return is_one_byte_;
5446     return CheckCons(cons_string);
5447   }
VisitOneByteString(const uint8_t * chars,int length)5448   void VisitOneByteString(const uint8_t* chars, int length) {
5449     // Nothing to do.
5450   }
VisitTwoByteString(const uint16_t * chars,int length)5451   void VisitTwoByteString(const uint16_t* chars, int length) {
5452     // Accumulated bits.
5453     uintptr_t acc = 0;
5454     // Align to uintptr_t.
5455     const uint16_t* end = chars + length;
5456     while (Unaligned(chars) && chars != end) {
5457       acc |= *chars++;
5458     }
5459     // Read word aligned in blocks,
5460     // checking the return value at the end of each block.
5461     const uint16_t* aligned_end = Align(end);
5462     const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5463     const int inner_loops = 16;
5464     while (chars + inner_loops * increment < aligned_end) {
5465       for (int i = 0; i < inner_loops; i++) {
5466         acc |= *reinterpret_cast<const uintptr_t*>(chars);
5467         chars += increment;
5468       }
5469       // Check for early return.
5470       if ((acc & kOneByteMask) != 0) {
5471         is_one_byte_ = false;
5472         return;
5473       }
5474     }
5475     // Read the rest.
5476     while (chars != end) {
5477       acc |= *chars++;
5478     }
5479     // Check result.
5480     if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5481   }
5482 
5483  private:
CheckCons(i::ConsString cons_string)5484   bool CheckCons(i::ConsString cons_string) {
5485     while (true) {
5486       // Check left side if flat.
5487       i::String left = cons_string.first();
5488       i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5489       if (!is_one_byte_) return false;
5490       // Check right side if flat.
5491       i::String right = cons_string.second();
5492       i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5493       if (!is_one_byte_) return false;
5494       // Standard recurse/iterate trick.
5495       if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5496         if (left.length() < right.length()) {
5497           CheckCons(left_as_cons);
5498           cons_string = right_as_cons;
5499         } else {
5500           CheckCons(right_as_cons);
5501           cons_string = left_as_cons;
5502         }
5503         // Check fast return.
5504         if (!is_one_byte_) return false;
5505         continue;
5506       }
5507       // Descend left in place.
5508       if (!left_as_cons.is_null()) {
5509         cons_string = left_as_cons;
5510         continue;
5511       }
5512       // Descend right in place.
5513       if (!right_as_cons.is_null()) {
5514         cons_string = right_as_cons;
5515         continue;
5516       }
5517       // Terminate.
5518       break;
5519     }
5520     return is_one_byte_;
5521   }
5522   bool is_one_byte_;
5523 };
5524 
ContainsOnlyOneByte() const5525 bool String::ContainsOnlyOneByte() const {
5526   i::Handle<i::String> str = Utils::OpenHandle(this);
5527   if (str->IsOneByteRepresentation()) return true;
5528   ContainsOnlyOneByteHelper helper;
5529   return helper.Check(*str);
5530 }
5531 
Utf8Length(Isolate * isolate) const5532 int String::Utf8Length(Isolate* isolate) const {
5533   i::Handle<i::String> str = Utils::OpenHandle(this);
5534   str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5535   int length = str->length();
5536   if (length == 0) return 0;
5537   i::DisallowGarbageCollection no_gc;
5538   i::String::FlatContent flat = str->GetFlatContent(no_gc);
5539   DCHECK(flat.IsFlat());
5540   int utf8_length = 0;
5541   if (flat.IsOneByte()) {
5542     for (uint8_t c : flat.ToOneByteVector()) {
5543       utf8_length += c >> 7;
5544     }
5545     utf8_length += length;
5546   } else {
5547     int last_character = unibrow::Utf16::kNoPreviousCharacter;
5548     for (uint16_t c : flat.ToUC16Vector()) {
5549       utf8_length += unibrow::Utf8::Length(c, last_character);
5550       last_character = c;
5551     }
5552   }
5553   return utf8_length;
5554 }
5555 
5556 namespace {
5557 // Writes the flat content of a string to a buffer. This is done in two phases.
5558 // The first phase calculates a pessimistic estimate (writable_length) on how
5559 // many code units can be safely written without exceeding the buffer capacity
5560 // and without leaving at a lone surrogate. The estimated number of code units
5561 // is then written out in one go, and the reported byte usage is used to
5562 // correct the estimate. This is repeated until the estimate becomes <= 0 or
5563 // all code units have been written out. The second phase writes out code
5564 // units until the buffer capacity is reached, would be exceeded by the next
5565 // unit, or all code units have been written out.
5566 template <typename Char>
WriteUtf8Impl(base::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5567 static int WriteUtf8Impl(base::Vector<const Char> string, char* write_start,
5568                          int write_capacity, int options,
5569                          int* utf16_chars_read_out) {
5570   bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5571   bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5572   char* current_write = write_start;
5573   const Char* read_start = string.begin();
5574   int read_index = 0;
5575   int read_length = string.length();
5576   int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5577   // Do a fast loop where there is no exit capacity check.
5578   // Need enough space to write everything but one character.
5579   STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5580   static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5581   while (read_index < read_length) {
5582     int up_to = read_length;
5583     if (write_capacity != -1) {
5584       int remaining_capacity =
5585           write_capacity - static_cast<int>(current_write - write_start);
5586       int writable_length =
5587           (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5588       // Need to drop into slow loop.
5589       if (writable_length <= 0) break;
5590       up_to = std::min(up_to, read_index + writable_length);
5591     }
5592     // Write the characters to the stream.
5593     if (sizeof(Char) == 1) {
5594       // Simply memcpy if we only have ASCII characters.
5595       uint8_t char_mask = 0;
5596       for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5597       if ((char_mask & 0x80) == 0) {
5598         int copy_length = up_to - read_index;
5599         memcpy(current_write, read_start + read_index, copy_length);
5600         current_write += copy_length;
5601         read_index = up_to;
5602       } else {
5603         for (; read_index < up_to; read_index++) {
5604           current_write += unibrow::Utf8::EncodeOneByte(
5605               current_write, static_cast<uint8_t>(read_start[read_index]));
5606           DCHECK(write_capacity == -1 ||
5607                  (current_write - write_start) <= write_capacity);
5608         }
5609       }
5610     } else {
5611       for (; read_index < up_to; read_index++) {
5612         uint16_t character = read_start[read_index];
5613         current_write += unibrow::Utf8::Encode(current_write, character,
5614                                                prev_char, replace_invalid_utf8);
5615         prev_char = character;
5616         DCHECK(write_capacity == -1 ||
5617                (current_write - write_start) <= write_capacity);
5618       }
5619     }
5620   }
5621   if (read_index < read_length) {
5622     DCHECK_NE(-1, write_capacity);
5623     // Aborted due to limited capacity. Check capacity on each iteration.
5624     int remaining_capacity =
5625         write_capacity - static_cast<int>(current_write - write_start);
5626     DCHECK_GE(remaining_capacity, 0);
5627     for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5628       uint32_t character = read_start[read_index];
5629       int written = 0;
5630       // We can't use a local buffer here because Encode needs to modify
5631       // previous characters in the stream.  We know, however, that
5632       // exactly one character will be advanced.
5633       if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5634         written = unibrow::Utf8::Encode(current_write, character, prev_char,
5635                                         replace_invalid_utf8);
5636         DCHECK_EQ(written, 1);
5637       } else {
5638         // Use a scratch buffer to check the required characters.
5639         char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5640         // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5641         static const int kSurrogatePairEncodedSize =
5642             static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5643         // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5644         // middle of a surrogate pair. Abort before encoding the pair instead.
5645         if (replace_invalid_utf8 &&
5646             remaining_capacity < kSurrogatePairEncodedSize &&
5647             unibrow::Utf16::IsLeadSurrogate(character) &&
5648             read_index + 1 < read_length &&
5649             unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5650           write_null = false;
5651           break;
5652         }
5653         // Can't encode using prev_char as gcc has array bounds issues.
5654         written = unibrow::Utf8::Encode(temp_buffer, character,
5655                                         unibrow::Utf16::kNoPreviousCharacter,
5656                                         replace_invalid_utf8);
5657         if (written > remaining_capacity) {
5658           // Won't fit. Abort and do not null-terminate the result.
5659           write_null = false;
5660           break;
5661         }
5662         // Copy over the character from temp_buffer.
5663         for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5664       }
5665 
5666       current_write += written;
5667       remaining_capacity -= written;
5668       prev_char = character;
5669     }
5670   }
5671 
5672   // Write out number of utf16 characters written to the stream.
5673   if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5674 
5675   // Only null-terminate if there's space.
5676   if (write_null && (write_capacity == -1 ||
5677                      (current_write - write_start) < write_capacity)) {
5678     *current_write++ = '\0';
5679   }
5680   return static_cast<int>(current_write - write_start);
5681 }
5682 }  // anonymous namespace
5683 
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5684 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5685                       int* nchars_ref, int options) const {
5686   i::Handle<i::String> str = Utils::OpenHandle(this);
5687   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5688   API_RCS_SCOPE(isolate, String, WriteUtf8);
5689   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5690   str = i::String::Flatten(isolate, str);
5691   i::DisallowGarbageCollection no_gc;
5692   i::String::FlatContent content = str->GetFlatContent(no_gc);
5693   if (content.IsOneByte()) {
5694     return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5695                                   options, nchars_ref);
5696   } else {
5697     return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5698                                    options, nchars_ref);
5699   }
5700 }
5701 
5702 template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5703 static inline int WriteHelper(i::Isolate* isolate, const String* string,
5704                               CharType* buffer, int start, int length,
5705                               int options) {
5706   API_RCS_SCOPE(isolate, String, Write);
5707   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5708   DCHECK(start >= 0 && length >= -1);
5709   i::Handle<i::String> str = Utils::OpenHandle(string);
5710   str = i::String::Flatten(isolate, str);
5711   int end = start + length;
5712   if ((length == -1) || (length > str->length() - start)) end = str->length();
5713   if (end < 0) return 0;
5714   int write_length = end - start;
5715   if (start < end) i::String::WriteToFlat(*str, buffer, start, write_length);
5716   if (!(options & String::NO_NULL_TERMINATION) &&
5717       (length == -1 || write_length < length)) {
5718     buffer[write_length] = '\0';
5719   }
5720   return write_length;
5721 }
5722 
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5723 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5724                          int length, int options) const {
5725   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5726                      start, length, options);
5727 }
5728 
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5729 int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5730                   int options) const {
5731   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5732                      start, length, options);
5733 }
5734 
IsExternal() const5735 bool v8::String::IsExternal() const {
5736   i::Handle<i::String> str = Utils::OpenHandle(this);
5737   return i::StringShape(*str).IsExternal();
5738 }
5739 
IsExternalTwoByte() const5740 bool v8::String::IsExternalTwoByte() const {
5741   i::Handle<i::String> str = Utils::OpenHandle(this);
5742   return i::StringShape(*str).IsExternalTwoByte();
5743 }
5744 
IsExternalOneByte() const5745 bool v8::String::IsExternalOneByte() const {
5746   i::Handle<i::String> str = Utils::OpenHandle(this);
5747   return i::StringShape(*str).IsExternalOneByte();
5748 }
5749 
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5750 void v8::String::VerifyExternalStringResource(
5751     v8::String::ExternalStringResource* value) const {
5752   i::DisallowGarbageCollection no_gc;
5753   i::String str = *Utils::OpenHandle(this);
5754   const v8::String::ExternalStringResource* expected;
5755 
5756   if (str.IsThinString()) {
5757     str = i::ThinString::cast(str).actual();
5758   }
5759 
5760   if (i::StringShape(str).IsExternalTwoByte()) {
5761     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5762     expected = reinterpret_cast<const ExternalStringResource*>(resource);
5763   } else {
5764     expected = nullptr;
5765   }
5766   CHECK_EQ(expected, value);
5767 }
5768 
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5769 void v8::String::VerifyExternalStringResourceBase(
5770     v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5771   i::DisallowGarbageCollection no_gc;
5772   i::String str = *Utils::OpenHandle(this);
5773   const v8::String::ExternalStringResourceBase* expected;
5774   Encoding expectedEncoding;
5775 
5776   if (str.IsThinString()) {
5777     str = i::ThinString::cast(str).actual();
5778   }
5779 
5780   if (i::StringShape(str).IsExternalOneByte()) {
5781     const void* resource = i::ExternalOneByteString::cast(str).resource();
5782     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5783     expectedEncoding = ONE_BYTE_ENCODING;
5784   } else if (i::StringShape(str).IsExternalTwoByte()) {
5785     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5786     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5787     expectedEncoding = TWO_BYTE_ENCODING;
5788   } else {
5789     expected = nullptr;
5790     expectedEncoding =
5791         str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5792   }
5793   CHECK_EQ(expected, value);
5794   CHECK_EQ(expectedEncoding, encoding);
5795 }
5796 
GetExternalStringResourceSlow() const5797 String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5798   i::DisallowGarbageCollection no_gc;
5799   using I = internal::Internals;
5800   i::String str = *Utils::OpenHandle(this);
5801 
5802   if (str.IsThinString()) {
5803     str = i::ThinString::cast(str).actual();
5804   }
5805 
5806   if (i::StringShape(str).IsExternalTwoByte()) {
5807     internal::Isolate* isolate = I::GetIsolateForSandbox(str.ptr());
5808     internal::Address value = I::ReadExternalPointerField(
5809         isolate, str.ptr(), I::kStringResourceOffset,
5810         internal::kExternalStringResourceTag);
5811     return reinterpret_cast<String::ExternalStringResource*>(value);
5812   }
5813   return nullptr;
5814 }
5815 
UpdateDataCache()5816 void String::ExternalStringResource::UpdateDataCache() {
5817   DCHECK(IsCacheable());
5818   cached_data_ = data();
5819 }
5820 
CheckCachedDataInvariants() const5821 void String::ExternalStringResource::CheckCachedDataInvariants() const {
5822   DCHECK(IsCacheable() && cached_data_ != nullptr);
5823 }
5824 
UpdateDataCache()5825 void String::ExternalOneByteStringResource::UpdateDataCache() {
5826   DCHECK(IsCacheable());
5827   cached_data_ = data();
5828 }
5829 
CheckCachedDataInvariants() const5830 void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5831   DCHECK(IsCacheable() && cached_data_ != nullptr);
5832 }
5833 
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5834 String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5835     String::Encoding* encoding_out) const {
5836   i::DisallowGarbageCollection no_gc;
5837   using I = internal::Internals;
5838   ExternalStringResourceBase* resource = nullptr;
5839   i::String str = *Utils::OpenHandle(this);
5840 
5841   if (str.IsThinString()) {
5842     str = i::ThinString::cast(str).actual();
5843   }
5844 
5845   internal::Address string = str.ptr();
5846   int type =
5847       I::GetInstanceType(string) & I::kStringRepresentationAndEncodingMask;
5848   *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5849   if (i::StringShape(str).IsExternalOneByte() ||
5850       i::StringShape(str).IsExternalTwoByte()) {
5851     internal::Isolate* isolate = I::GetIsolateForSandbox(string);
5852     internal::Address value =
5853         I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5854                                     internal::kExternalStringResourceTag);
5855     resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5856   }
5857   return resource;
5858 }
5859 
5860 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5861 v8::String::GetExternalOneByteStringResource() const {
5862   i::DisallowGarbageCollection no_gc;
5863   i::String str = *Utils::OpenHandle(this);
5864   if (i::StringShape(str).IsExternalOneByte()) {
5865     return i::ExternalOneByteString::cast(str).resource();
5866   } else if (str.IsThinString()) {
5867     str = i::ThinString::cast(str).actual();
5868     if (i::StringShape(str).IsExternalOneByte()) {
5869       return i::ExternalOneByteString::cast(str).resource();
5870     }
5871   }
5872   return nullptr;
5873 }
5874 
Description(Isolate * isolate) const5875 Local<Value> Symbol::Description(Isolate* isolate) const {
5876   i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5877   i::Handle<i::Object> description(sym->description(),
5878                                    reinterpret_cast<i::Isolate*>(isolate));
5879   return Utils::ToLocal(description);
5880 }
5881 
Name() const5882 Local<Value> Private::Name() const {
5883   const Symbol* sym = reinterpret_cast<const Symbol*>(this);
5884   i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym);
5885   // v8::Private symbols are created by API and are therefore writable, so we
5886   // can always recover an Isolate.
5887   i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym);
5888   return sym->Description(reinterpret_cast<Isolate*>(isolate));
5889 }
5890 
Value() const5891 double Number::Value() const {
5892   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5893   return obj->Number();
5894 }
5895 
Value() const5896 bool Boolean::Value() const {
5897   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5898   return obj->IsTrue();
5899 }
5900 
Value() const5901 int64_t Integer::Value() const {
5902   i::Object obj = *Utils::OpenHandle(this);
5903   if (obj.IsSmi()) {
5904     return i::Smi::ToInt(obj);
5905   } else {
5906     return static_cast<int64_t>(obj.Number());
5907   }
5908 }
5909 
Value() const5910 int32_t Int32::Value() const {
5911   i::Object obj = *Utils::OpenHandle(this);
5912   if (obj.IsSmi()) {
5913     return i::Smi::ToInt(obj);
5914   } else {
5915     return static_cast<int32_t>(obj.Number());
5916   }
5917 }
5918 
Value() const5919 uint32_t Uint32::Value() const {
5920   i::Object obj = *Utils::OpenHandle(this);
5921   if (obj.IsSmi()) {
5922     return i::Smi::ToInt(obj);
5923   } else {
5924     return static_cast<uint32_t>(obj.Number());
5925   }
5926 }
5927 
InternalFieldCount() const5928 int v8::Object::InternalFieldCount() const {
5929   i::JSReceiver self = *Utils::OpenHandle(this);
5930   if (!self.IsJSObject()) return 0;
5931   return i::JSObject::cast(self).GetEmbedderFieldCount();
5932 }
5933 
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5934 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5935                             const char* location) {
5936   return Utils::ApiCheck(
5937       obj->IsJSObject() &&
5938           (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5939       location, "Internal field out of bounds");
5940 }
5941 
SlowGetInternalField(int index)5942 Local<Value> v8::Object::SlowGetInternalField(int index) {
5943   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5944   const char* location = "v8::Object::GetInternalField()";
5945   if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5946   i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
5947                              obj->GetIsolate());
5948   return Utils::ToLocal(value);
5949 }
5950 
SetInternalField(int index,v8::Local<Value> value)5951 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5952   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5953   const char* location = "v8::Object::SetInternalField()";
5954   if (!InternalFieldOK(obj, index, location)) return;
5955   i::Handle<i::Object> val = Utils::OpenHandle(*value);
5956   i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
5957 }
5958 
SlowGetAlignedPointerFromInternalField(int index)5959 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5960   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5961   const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5962   if (!InternalFieldOK(obj, index, location)) return nullptr;
5963   void* result;
5964   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5965                       .ToAlignedPointer(obj->GetIsolate(), &result),
5966                   location, "Unaligned pointer");
5967   return result;
5968 }
5969 
SetAlignedPointerInInternalField(int index,void * value)5970 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5971   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5972   const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5973   if (!InternalFieldOK(obj, index, location)) return;
5974 
5975   i::DisallowGarbageCollection no_gc;
5976 
5977   // There's no need to invalidate slots as embedder fields are always
5978   // tagged.
5979   obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
5980                                            i::InvalidateRecordedSlots::kNo);
5981 
5982   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5983                       .store_aligned_pointer(obj->GetIsolate(), value),
5984                   location, "Unaligned pointer");
5985   DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5986   internal::WriteBarrier::MarkingFromInternalFields(i::JSObject::cast(*obj));
5987 
5988 #ifdef VERIFY_HEAP
5989   obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
5990 #endif  // VERIFY_HEAP
5991 }
5992 
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])5993 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
5994                                                    void* values[]) {
5995   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5996 
5997   i::DisallowGarbageCollection no_gc;
5998   // There's no need to invalidate slots as embedder fields are always
5999   // tagged.
6000   obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
6001                                            i::InvalidateRecordedSlots::kNo);
6002 
6003   const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6004   i::JSObject js_obj = i::JSObject::cast(*obj);
6005   int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
6006   for (int i = 0; i < argc; i++) {
6007     int index = indices[i];
6008     if (!Utils::ApiCheck(index < nof_embedder_fields, location,
6009                          "Internal field out of bounds")) {
6010       return;
6011     }
6012     void* value = values[i];
6013     Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
6014                         .store_aligned_pointer(obj->GetIsolate(), value),
6015                     location, "Unaligned pointer");
6016     DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6017   }
6018   internal::WriteBarrier::MarkingFromInternalFields(js_obj);
6019 
6020 #ifdef VERIFY_HEAP
6021   obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6022 #endif  // VERIFY_HEAP
6023 }
6024 
6025 // --- E n v i r o n m e n t ---
6026 
InitializePlatform(Platform * platform)6027 void v8::V8::InitializePlatform(Platform* platform) {
6028   i::V8::InitializePlatform(platform);
6029 }
6030 
6031 #ifdef V8_SANDBOX
InitializeSandbox()6032 bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); }
6033 #endif
6034 
DisposePlatform()6035 void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); }
6036 
Initialize(const int build_config)6037 bool v8::V8::Initialize(const int build_config) {
6038   const bool kEmbedderPointerCompression =
6039       (build_config & kPointerCompression) != 0;
6040   if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
6041     FATAL(
6042         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6043         "pointer compression is %s while on V8 side it's %s.",
6044         kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
6045         COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6046   }
6047 
6048   const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
6049   if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
6050     FATAL(
6051         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6052         "Smi value size is %d while on V8 side it's %d.",
6053         kEmbedderSmiValueSize, internal::kSmiValueSize);
6054   }
6055 
6056   const bool kEmbedderSandboxedExternalPointers =
6057       (build_config & kSandboxedExternalPointers) != 0;
6058   if (kEmbedderSandboxedExternalPointers !=
6059       V8_SANDBOXED_EXTERNAL_POINTERS_BOOL) {
6060     FATAL(
6061         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6062         "sandboxed external pointers is %s while on V8 side it's %s.",
6063         kEmbedderSandboxedExternalPointers ? "ENABLED" : "DISABLED",
6064         V8_SANDBOXED_EXTERNAL_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6065   }
6066 
6067   const bool kEmbedderSandbox = (build_config & kSandbox) != 0;
6068   if (kEmbedderSandbox != V8_SANDBOX_BOOL) {
6069     FATAL(
6070         "Embedder-vs-V8 build configuration mismatch. On embedder side "
6071         "sandbox is %s while on V8 side it's %s.",
6072         kEmbedderSandbox ? "ENABLED" : "DISABLED",
6073         V8_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
6074   }
6075 
6076   i::V8::Initialize();
6077   return true;
6078 }
6079 
6080 #if V8_OS_LINUX || V8_OS_DARWIN
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)6081 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
6082                                    void* context) {
6083 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6084   return i::trap_handler::TryHandleSignal(sig_code, info, context);
6085 #else
6086   return false;
6087 #endif
6088 }
6089 #endif
6090 
6091 #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)6092 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
6093 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6094   return i::trap_handler::TryHandleWasmTrap(exception);
6095 #else
6096   return false;
6097 #endif
6098 }
6099 #endif
6100 
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)6101 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6102 #if V8_ENABLE_WEBASSEMBLY
6103   return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
6104 #else
6105   return false;
6106 #endif
6107 }
6108 
6109 #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6110 void V8::SetUnhandledExceptionCallback(
6111     UnhandledExceptionCallback unhandled_exception_callback) {
6112 #if defined(V8_OS_WIN64)
6113   v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
6114       unhandled_exception_callback);
6115 #else
6116   // Not implemented, port needed.
6117 #endif  // V8_OS_WIN64
6118 }
6119 #endif  // V8_OS_WIN
6120 
SetFatalMemoryErrorCallback(v8::OOMErrorCallback oom_error_callback)6121 void v8::V8::SetFatalMemoryErrorCallback(
6122     v8::OOMErrorCallback oom_error_callback) {
6123   g_oom_error_callback = oom_error_callback;
6124 }
6125 
SetEntropySource(EntropySource entropy_source)6126 void v8::V8::SetEntropySource(EntropySource entropy_source) {
6127   base::RandomNumberGenerator::SetEntropySource(entropy_source);
6128 }
6129 
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6130 void v8::V8::SetReturnAddressLocationResolver(
6131     ReturnAddressLocationResolver return_address_resolver) {
6132   i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6133 }
6134 
Dispose()6135 bool v8::V8::Dispose() {
6136   i::V8::Dispose();
6137   return true;
6138 }
6139 
SharedMemoryStatistics()6140 SharedMemoryStatistics::SharedMemoryStatistics()
6141     : read_only_space_size_(0),
6142       read_only_space_used_size_(0),
6143       read_only_space_physical_size_(0) {}
6144 
HeapStatistics()6145 HeapStatistics::HeapStatistics()
6146     : total_heap_size_(0),
6147       total_heap_size_executable_(0),
6148       total_physical_size_(0),
6149       total_available_size_(0),
6150       used_heap_size_(0),
6151       heap_size_limit_(0),
6152       malloced_memory_(0),
6153       external_memory_(0),
6154       peak_malloced_memory_(0),
6155       does_zap_garbage_(false),
6156       number_of_native_contexts_(0),
6157       number_of_detached_contexts_(0) {}
6158 
HeapSpaceStatistics()6159 HeapSpaceStatistics::HeapSpaceStatistics()
6160     : space_name_(nullptr),
6161       space_size_(0),
6162       space_used_size_(0),
6163       space_available_size_(0),
6164       physical_space_size_(0) {}
6165 
HeapObjectStatistics()6166 HeapObjectStatistics::HeapObjectStatistics()
6167     : object_type_(nullptr),
6168       object_sub_type_(nullptr),
6169       object_count_(0),
6170       object_size_(0) {}
6171 
HeapCodeStatistics()6172 HeapCodeStatistics::HeapCodeStatistics()
6173     : code_and_metadata_size_(0),
6174       bytecode_and_metadata_size_(0),
6175       external_script_source_size_(0),
6176       cpu_profiler_metadata_size_(0) {}
6177 
InitializeICU(const char * icu_data_file)6178 bool v8::V8::InitializeICU(const char* icu_data_file) {
6179   return i::InitializeICU(icu_data_file);
6180 }
6181 
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6182 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6183                                           const char* icu_data_file) {
6184   return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6185 }
6186 
InitializeExternalStartupData(const char * directory_path)6187 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6188   i::InitializeExternalStartupData(directory_path);
6189 }
6190 
6191 // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)6192 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6193   i::InitializeExternalStartupDataFromFile(snapshot_blob);
6194 }
6195 
GetVersion()6196 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6197 
6198 #ifdef V8_SANDBOX
GetSandboxAddressSpace()6199 VirtualAddressSpace* v8::V8::GetSandboxAddressSpace() {
6200   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6201                   "v8::V8::GetSandboxAddressSpace",
6202                   "The sandbox must be initialized first.");
6203   return i::GetProcessWideSandbox()->address_space();
6204 }
6205 
GetVirtualMemoryCagePageAllocator()6206 PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() {
6207   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6208                   "v8::V8::GetVirtualMemoryCagePageAllocator",
6209                   "The sandbox must be initialized first.");
6210   return i::GetProcessWideSandbox()->page_allocator();
6211 }
6212 
GetSandboxSizeInBytes()6213 size_t v8::V8::GetSandboxSizeInBytes() {
6214   if (!i::GetProcessWideSandbox()->is_initialized()) {
6215     return 0;
6216   } else {
6217     return i::GetProcessWideSandbox()->size();
6218   }
6219 }
6220 
IsSandboxConfiguredSecurely()6221 bool v8::V8::IsSandboxConfiguredSecurely() {
6222   Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6223                   "v8::V8::IsSandoxConfiguredSecurely",
6224                   "The sandbox must be initialized first.");
6225   // TODO(saelo) For now, we only treat a partially reserved sandbox as
6226   // insecure. Once we use sandboxed pointers, which assume that the sandbox
6227   // has a fixed size, we'll also treat sandboxes with a smaller size as
6228   // insecure because these pointers can then access memory outside of them.
6229   return !i::GetProcessWideSandbox()->is_partially_reserved();
6230 }
6231 #endif
6232 
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6233 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6234   i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6235 }
6236 
6237 template <typename ObjectType>
6238 struct InvokeBootstrapper;
6239 
6240 template <>
6241 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6242   i::Handle<i::Context> Invoke(
6243       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6244       v8::Local<v8::ObjectTemplate> global_proxy_template,
6245       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6246       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6247       v8::MicrotaskQueue* microtask_queue) {
6248     return isolate->bootstrapper()->CreateEnvironment(
6249         maybe_global_proxy, global_proxy_template, extensions,
6250         context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6251   }
6252 };
6253 
6254 template <>
6255 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6256   i::Handle<i::JSGlobalProxy> Invoke(
6257       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6258       v8::Local<v8::ObjectTemplate> global_proxy_template,
6259       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6260       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6261       v8::MicrotaskQueue* microtask_queue) {
6262     USE(extensions);
6263     USE(context_snapshot_index);
6264     return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6265                                                      global_proxy_template);
6266   }
6267 };
6268 
6269 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)6270 static i::Handle<ObjectType> CreateEnvironment(
6271     i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6272     v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6273     v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6274     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6275     v8::MicrotaskQueue* microtask_queue) {
6276   i::Handle<ObjectType> result;
6277 
6278   {
6279     ENTER_V8_FOR_NEW_CONTEXT(isolate);
6280     v8::Local<ObjectTemplate> proxy_template;
6281     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6282     i::Handle<i::FunctionTemplateInfo> global_constructor;
6283     i::Handle<i::HeapObject> named_interceptor(
6284         isolate->factory()->undefined_value());
6285     i::Handle<i::HeapObject> indexed_interceptor(
6286         isolate->factory()->undefined_value());
6287 
6288     if (!maybe_global_template.IsEmpty()) {
6289       v8::Local<v8::ObjectTemplate> global_template =
6290           maybe_global_template.ToLocalChecked();
6291       // Make sure that the global_template has a constructor.
6292       global_constructor = EnsureConstructor(isolate, *global_template);
6293 
6294       // Create a fresh template for the global proxy object.
6295       proxy_template =
6296           ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
6297       proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6298 
6299       // Set the global template to be the prototype template of
6300       // global proxy template.
6301       i::FunctionTemplateInfo::SetPrototypeTemplate(
6302           isolate, proxy_constructor, Utils::OpenHandle(*global_template));
6303 
6304       proxy_template->SetInternalFieldCount(
6305           global_template->InternalFieldCount());
6306 
6307       // Migrate security handlers from global_template to
6308       // proxy_template.  Temporarily removing access check
6309       // information from the global template.
6310       if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
6311         i::FunctionTemplateInfo::SetAccessCheckInfo(
6312             isolate, proxy_constructor,
6313             i::handle(global_constructor->GetAccessCheckInfo(), isolate));
6314         proxy_constructor->set_needs_access_check(
6315             global_constructor->needs_access_check());
6316         global_constructor->set_needs_access_check(false);
6317         i::FunctionTemplateInfo::SetAccessCheckInfo(
6318             isolate, global_constructor,
6319             i::ReadOnlyRoots(isolate).undefined_value_handle());
6320       }
6321 
6322       // Same for other interceptors. If the global constructor has
6323       // interceptors, we need to replace them temporarily with noop
6324       // interceptors, so the map is correctly marked as having interceptors,
6325       // but we don't invoke any.
6326       if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
6327         named_interceptor =
6328             handle(global_constructor->GetNamedPropertyHandler(), isolate);
6329         i::FunctionTemplateInfo::SetNamedPropertyHandler(
6330             isolate, global_constructor,
6331             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6332       }
6333       if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
6334               isolate)) {
6335         indexed_interceptor =
6336             handle(global_constructor->GetIndexedPropertyHandler(), isolate);
6337         i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6338             isolate, global_constructor,
6339             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6340       }
6341     }
6342 
6343     i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6344     if (!maybe_global_proxy.IsEmpty()) {
6345       maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6346           Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6347     }
6348     // Create the environment.
6349     InvokeBootstrapper<ObjectType> invoke;
6350     result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6351                            context_snapshot_index, embedder_fields_deserializer,
6352                            microtask_queue);
6353 
6354     // Restore the access check info and interceptors on the global template.
6355     if (!maybe_global_template.IsEmpty()) {
6356       DCHECK(!global_constructor.is_null());
6357       DCHECK(!proxy_constructor.is_null());
6358       i::FunctionTemplateInfo::SetAccessCheckInfo(
6359           isolate, global_constructor,
6360           i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6361       global_constructor->set_needs_access_check(
6362           proxy_constructor->needs_access_check());
6363       i::FunctionTemplateInfo::SetNamedPropertyHandler(
6364           isolate, global_constructor, named_interceptor);
6365       i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6366           isolate, global_constructor, indexed_interceptor);
6367     }
6368   }
6369   // Leave V8.
6370 
6371   return result;
6372 }
6373 
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)6374 Local<Context> NewContext(
6375     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6376     v8::MaybeLocal<ObjectTemplate> global_template,
6377     v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6378     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6379     v8::MicrotaskQueue* microtask_queue) {
6380   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6381   // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6382   // fail.
6383   // Sanity-check that the isolate is initialized and usable.
6384   CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT());
6385 
6386   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6387   API_RCS_SCOPE(isolate, Context, New);
6388   i::HandleScope scope(isolate);
6389   ExtensionConfiguration no_extensions;
6390   if (extensions == nullptr) extensions = &no_extensions;
6391   i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6392       isolate, extensions, global_template, global_object,
6393       context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6394   if (env.is_null()) {
6395     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6396     return Local<Context>();
6397   }
6398   return Utils::ToLocal(scope.CloseAndEscape(env));
6399 }
6400 
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)6401 Local<Context> v8::Context::New(
6402     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6403     v8::MaybeLocal<ObjectTemplate> global_template,
6404     v8::MaybeLocal<Value> global_object,
6405     DeserializeInternalFieldsCallback internal_fields_deserializer,
6406     v8::MicrotaskQueue* microtask_queue) {
6407   return NewContext(external_isolate, extensions, global_template,
6408                     global_object, 0, internal_fields_deserializer,
6409                     microtask_queue);
6410 }
6411 
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)6412 MaybeLocal<Context> v8::Context::FromSnapshot(
6413     v8::Isolate* external_isolate, size_t context_snapshot_index,
6414     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6415     v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6416     v8::MicrotaskQueue* microtask_queue) {
6417   size_t index_including_default_context = context_snapshot_index + 1;
6418   if (!i::Snapshot::HasContextSnapshot(
6419           reinterpret_cast<i::Isolate*>(external_isolate),
6420           index_including_default_context)) {
6421     return MaybeLocal<Context>();
6422   }
6423   return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6424                     global_object, index_including_default_context,
6425                     embedder_fields_deserializer, microtask_queue);
6426 }
6427 
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6428 MaybeLocal<Object> v8::Context::NewRemoteContext(
6429     v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6430     v8::MaybeLocal<v8::Value> global_object) {
6431   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6432   API_RCS_SCOPE(isolate, Context, NewRemoteContext);
6433   i::HandleScope scope(isolate);
6434   i::Handle<i::FunctionTemplateInfo> global_constructor =
6435       EnsureConstructor(isolate, *global_template);
6436   Utils::ApiCheck(global_constructor->needs_access_check(),
6437                   "v8::Context::NewRemoteContext",
6438                   "Global template needs to have access checks enabled.");
6439   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6440       i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6441       isolate);
6442   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6443                   "v8::Context::NewRemoteContext",
6444                   "Global template needs to have access check handlers.");
6445   i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6446       isolate, nullptr, global_template, global_object, 0,
6447       DeserializeInternalFieldsCallback(), nullptr);
6448   if (global_proxy.is_null()) {
6449     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6450     return MaybeLocal<Object>();
6451   }
6452   return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6453 }
6454 
SetSecurityToken(Local<Value> token)6455 void v8::Context::SetSecurityToken(Local<Value> token) {
6456   i::Handle<i::Context> env = Utils::OpenHandle(this);
6457   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6458   env->set_security_token(*token_handle);
6459 }
6460 
UseDefaultSecurityToken()6461 void v8::Context::UseDefaultSecurityToken() {
6462   i::Handle<i::Context> env = Utils::OpenHandle(this);
6463   env->set_security_token(env->global_object());
6464 }
6465 
GetSecurityToken()6466 Local<Value> v8::Context::GetSecurityToken() {
6467   i::Handle<i::Context> env = Utils::OpenHandle(this);
6468   i::Isolate* isolate = env->GetIsolate();
6469   i::Object security_token = env->security_token();
6470   i::Handle<i::Object> token_handle(security_token, isolate);
6471   return Utils::ToLocal(token_handle);
6472 }
6473 
GetIsolate()6474 v8::Isolate* Context::GetIsolate() {
6475   i::Handle<i::Context> env = Utils::OpenHandle(this);
6476   return reinterpret_cast<Isolate*>(env->GetIsolate());
6477 }
6478 
GetMicrotaskQueue()6479 v8::MicrotaskQueue* Context::GetMicrotaskQueue() {
6480   i::Handle<i::Context> env = Utils::OpenHandle(this);
6481   Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue",
6482                   "Must be calld on a native context");
6483   return i::Handle<i::NativeContext>::cast(env)->microtask_queue();
6484 }
6485 
Global()6486 v8::Local<v8::Object> Context::Global() {
6487   i::Handle<i::Context> context = Utils::OpenHandle(this);
6488   i::Isolate* isolate = context->GetIsolate();
6489   i::Handle<i::Object> global(context->global_proxy(), isolate);
6490   // TODO(chromium:324812): This should always return the global proxy
6491   // but can't presently as calls to GetProtoype will return the wrong result.
6492   if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6493           context->global_object())) {
6494     global = i::Handle<i::Object>(context->global_object(), isolate);
6495   }
6496   return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6497 }
6498 
DetachGlobal()6499 void Context::DetachGlobal() {
6500   i::Handle<i::Context> context = Utils::OpenHandle(this);
6501   i::Isolate* isolate = context->GetIsolate();
6502   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6503   isolate->DetachGlobal(context);
6504 }
6505 
GetExtrasBindingObject()6506 Local<v8::Object> Context::GetExtrasBindingObject() {
6507   i::Handle<i::Context> context = Utils::OpenHandle(this);
6508   i::Isolate* isolate = context->GetIsolate();
6509   i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6510   return Utils::ToLocal(binding);
6511 }
6512 
AllowCodeGenerationFromStrings(bool allow)6513 void Context::AllowCodeGenerationFromStrings(bool allow) {
6514   i::Handle<i::Context> context = Utils::OpenHandle(this);
6515   i::Isolate* isolate = context->GetIsolate();
6516   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6517   context->set_allow_code_gen_from_strings(
6518       allow ? i::ReadOnlyRoots(isolate).true_value()
6519             : i::ReadOnlyRoots(isolate).false_value());
6520 }
6521 
IsCodeGenerationFromStringsAllowed() const6522 bool Context::IsCodeGenerationFromStringsAllowed() const {
6523   i::Context context = *Utils::OpenHandle(this);
6524   return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6525 }
6526 
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6527 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6528   i::Handle<i::Context> context = Utils::OpenHandle(this);
6529   i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6530   context->set_error_message_for_code_gen_from_strings(*error_handle);
6531 }
6532 
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6533 void Context::SetAbortScriptExecution(
6534     Context::AbortScriptExecutionCallback callback) {
6535   i::Handle<i::Context> context = Utils::OpenHandle(this);
6536   i::Isolate* isolate = context->GetIsolate();
6537   if (callback == nullptr) {
6538     context->set_script_execution_callback(
6539         i::ReadOnlyRoots(isolate).undefined_value());
6540   } else {
6541     SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6542                       callback);
6543   }
6544 }
6545 
GetContinuationPreservedEmbedderData() const6546 Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6547   i::Handle<i::Context> context = Utils::OpenHandle(this);
6548   i::Isolate* isolate = context->GetIsolate();
6549   i::Handle<i::Object> data(
6550       context->native_context().continuation_preserved_embedder_data(),
6551       isolate);
6552   return ToApiHandle<Object>(data);
6553 }
6554 
SetContinuationPreservedEmbedderData(Local<Value> data)6555 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6556   i::Handle<i::Context> context = Utils::OpenHandle(this);
6557   i::Isolate* isolate = context->GetIsolate();
6558   if (data.IsEmpty())
6559     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6560   context->native_context().set_continuation_preserved_embedder_data(
6561       *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6562 }
6563 
SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6564 void v8::Context::SetPromiseHooks(Local<Function> init_hook,
6565                                   Local<Function> before_hook,
6566                                   Local<Function> after_hook,
6567                                   Local<Function> resolve_hook) {
6568 #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6569   i::Handle<i::Context> context = Utils::OpenHandle(this);
6570   i::Isolate* isolate = context->GetIsolate();
6571 
6572   i::Handle<i::Object> init = isolate->factory()->undefined_value();
6573   i::Handle<i::Object> before = isolate->factory()->undefined_value();
6574   i::Handle<i::Object> after = isolate->factory()->undefined_value();
6575   i::Handle<i::Object> resolve = isolate->factory()->undefined_value();
6576 
6577   bool has_hook = false;
6578 
6579   if (!init_hook.IsEmpty()) {
6580     init = Utils::OpenHandle(*init_hook);
6581     has_hook = true;
6582   }
6583   if (!before_hook.IsEmpty()) {
6584     before = Utils::OpenHandle(*before_hook);
6585     has_hook = true;
6586   }
6587   if (!after_hook.IsEmpty()) {
6588     after = Utils::OpenHandle(*after_hook);
6589     has_hook = true;
6590   }
6591   if (!resolve_hook.IsEmpty()) {
6592     resolve = Utils::OpenHandle(*resolve_hook);
6593     has_hook = true;
6594   }
6595 
6596   isolate->SetHasContextPromiseHooks(has_hook);
6597 
6598   context->native_context().set_promise_hook_init_function(*init);
6599   context->native_context().set_promise_hook_before_function(*before);
6600   context->native_context().set_promise_hook_after_function(*after);
6601   context->native_context().set_promise_hook_resolve_function(*resolve);
6602 #else   // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6603   Utils::ApiCheck(false, "v8::Context::SetPromiseHook",
6604                   "V8 was compiled without JavaScript Promise hooks");
6605 #endif  // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6606 }
6607 
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6608 MaybeLocal<Context> metrics::Recorder::GetContext(
6609     Isolate* isolate, metrics::Recorder::ContextId id) {
6610   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6611   return i_isolate->GetContextFromRecorderContextId(id);
6612 }
6613 
GetContextId(Local<Context> context)6614 metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6615     Local<Context> context) {
6616   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6617   i::Isolate* isolate = i_context->GetIsolate();
6618   return isolate->GetOrRegisterRecorderContextId(
6619       handle(i_context->native_context(), isolate));
6620 }
6621 
Get(v8::Isolate * isolate)6622 metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6623   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6624   return *i_isolate->GetCurrentLongTaskStats();
6625 }
6626 
6627 namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6628 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6629                                             i::FixedArray list, size_t index) {
6630   if (index < static_cast<size_t>(list.length())) {
6631     int int_index = static_cast<int>(index);
6632     i::Object object = list.get(int_index);
6633     if (!object.IsTheHole(isolate)) {
6634       list.set_the_hole(isolate, int_index);
6635       // Shrink the list so that the last element is not the hole (unless it's
6636       // the first element, because we don't want to end up with a non-canonical
6637       // empty FixedArray).
6638       int last = list.length() - 1;
6639       while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6640       if (last != -1) list.Shrink(isolate, last + 1);
6641       return i::Handle<i::Object>(object, isolate).location();
6642     }
6643   }
6644   return nullptr;
6645 }
6646 }  // anonymous namespace
6647 
GetDataFromSnapshotOnce(size_t index)6648 i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6649   auto context = Utils::OpenHandle(this);
6650   i::Isolate* i_isolate = context->GetIsolate();
6651   i::FixedArray list = context->serialized_objects();
6652   return GetSerializedDataFromFixedArray(i_isolate, list, index);
6653 }
6654 
NewInstance(Local<Context> context)6655 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6656   PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6657   auto self = Utils::OpenHandle(this);
6658   Local<Object> result;
6659   has_pending_exception = !ToLocal<Object>(
6660       i::ApiNatives::InstantiateObject(isolate, self), &result);
6661   RETURN_ON_FAILED_EXECUTION(Object);
6662   RETURN_ESCAPED(result);
6663 }
6664 
CheckCast(Data * that)6665 void v8::ObjectTemplate::CheckCast(Data* that) {
6666   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6667   Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6668                   "Value is not an ObjectTemplate");
6669 }
6670 
CheckCast(Data * that)6671 void v8::FunctionTemplate::CheckCast(Data* that) {
6672   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6673   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6674                   "Value is not a FunctionTemplate");
6675 }
6676 
CheckCast(Data * that)6677 void v8::Signature::CheckCast(Data* that) {
6678   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6679   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6680                   "Value is not a Signature");
6681 }
6682 
CheckCast(Data * that)6683 void v8::AccessorSignature::CheckCast(Data* that) {
6684   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6685   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6686                   "Value is not an AccessorSignature");
6687 }
6688 
GetFunction(Local<Context> context)6689 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6690   PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6691   auto self = Utils::OpenHandle(this);
6692   Local<Function> result;
6693   has_pending_exception =
6694       !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6695   RETURN_ON_FAILED_EXECUTION(Function);
6696   RETURN_ESCAPED(result);
6697 }
6698 
NewRemoteInstance()6699 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6700   auto self = Utils::OpenHandle(this);
6701   i::Isolate* isolate = self->GetIsolate();
6702   API_RCS_SCOPE(isolate, FunctionTemplate, NewRemoteInstance);
6703   i::HandleScope scope(isolate);
6704   i::Handle<i::FunctionTemplateInfo> constructor =
6705       EnsureConstructor(isolate, *InstanceTemplate());
6706   Utils::ApiCheck(constructor->needs_access_check(),
6707                   "v8::FunctionTemplate::NewRemoteInstance",
6708                   "InstanceTemplate needs to have access checks enabled.");
6709   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6710       i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6711   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6712                   "v8::FunctionTemplate::NewRemoteInstance",
6713                   "InstanceTemplate needs to have access check handlers.");
6714   i::Handle<i::JSObject> object;
6715   if (!i::ApiNatives::InstantiateRemoteObject(
6716            Utils::OpenHandle(*InstanceTemplate()))
6717            .ToHandle(&object)) {
6718     if (isolate->has_pending_exception()) {
6719       isolate->OptionalRescheduleException(true);
6720     }
6721     return MaybeLocal<Object>();
6722   }
6723   return Utils::ToLocal(scope.CloseAndEscape(object));
6724 }
6725 
HasInstance(v8::Local<v8::Value> value)6726 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6727   auto self = Utils::OpenHandle(this);
6728   auto obj = Utils::OpenHandle(*value);
6729   if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6730     return true;
6731   }
6732   if (obj->IsJSGlobalProxy()) {
6733     // If it's a global proxy, then test with the global object. Note that the
6734     // inner global object may not necessarily be a JSGlobalObject.
6735     i::PrototypeIterator iter(self->GetIsolate(),
6736                               i::JSObject::cast(*obj).map());
6737     // The global proxy should always have a prototype, as it is a bug to call
6738     // this on a detached JSGlobalProxy.
6739     DCHECK(!iter.IsAtEnd());
6740     return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6741   }
6742   return false;
6743 }
6744 
IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6745 bool FunctionTemplate::IsLeafTemplateForApiObject(
6746     v8::Local<v8::Value> value) const {
6747   i::DisallowGarbageCollection no_gc;
6748 
6749   i::Object object = *Utils::OpenHandle(*value);
6750 
6751   auto self = Utils::OpenHandle(this);
6752   return self->IsLeafTemplateForApiObject(object);
6753 }
6754 
New(Isolate * isolate,void * value)6755 Local<External> v8::External::New(Isolate* isolate, void* value) {
6756   STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6757   // Nullptr is not allowed here because serialization/deserialization of
6758   // nullptr external api references is not possible as nullptr is used as an
6759   // external_references table terminator, see v8::SnapshotCreator()
6760   // constructors.
6761   DCHECK_NOT_NULL(value);
6762   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6763   API_RCS_SCOPE(i_isolate, External, New);
6764   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6765   i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6766   return Utils::ExternalToLocal(external);
6767 }
6768 
Value() const6769 void* External::Value() const {
6770   auto self = Utils::OpenHandle(this);
6771   return i::JSExternalObject::cast(*self).value();
6772 }
6773 
6774 // anonymous namespace for string creation helper functions
6775 namespace {
6776 
StringLength(const char * string)6777 inline int StringLength(const char* string) {
6778   size_t len = strlen(string);
6779   CHECK_GE(i::kMaxInt, len);
6780   return static_cast<int>(len);
6781 }
6782 
StringLength(const uint8_t * string)6783 inline int StringLength(const uint8_t* string) {
6784   return StringLength(reinterpret_cast<const char*>(string));
6785 }
6786 
StringLength(const uint16_t * string)6787 inline int StringLength(const uint16_t* string) {
6788   size_t length = 0;
6789   while (string[length] != '\0') length++;
6790   CHECK_GE(i::kMaxInt, length);
6791   return static_cast<int>(length);
6792 }
6793 
6794 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6795 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6796                                            NewStringType type,
6797                                            base::Vector<const char> string) {
6798   if (type == NewStringType::kInternalized) {
6799     return factory->InternalizeUtf8String(string);
6800   }
6801   return factory->NewStringFromUtf8(string);
6802 }
6803 
6804 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6805 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6806                                            NewStringType type,
6807                                            base::Vector<const uint8_t> string) {
6808   if (type == NewStringType::kInternalized) {
6809     return factory->InternalizeString(string);
6810   }
6811   return factory->NewStringFromOneByte(string);
6812 }
6813 
6814 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6815 inline i::MaybeHandle<i::String> NewString(
6816     i::Factory* factory, NewStringType type,
6817     base::Vector<const uint16_t> string) {
6818   if (type == NewStringType::kInternalized) {
6819     return factory->InternalizeString(string);
6820   }
6821   return factory->NewStringFromTwoByte(string);
6822 }
6823 
6824 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6825 
6826 }  // anonymous namespace
6827 
6828 // TODO(dcarney): throw a context free exception.
6829 #define NEW_STRING(isolate, class_name, function_name, Char, data, type,   \
6830                    length)                                                 \
6831   MaybeLocal<String> result;                                               \
6832   if (length == 0) {                                                       \
6833     result = String::Empty(isolate);                                       \
6834   } else if (length > i::String::kMaxLength) {                             \
6835     result = MaybeLocal<String>();                                         \
6836   } else {                                                                 \
6837     i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6838     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);                            \
6839     API_RCS_SCOPE(i_isolate, class_name, function_name);                   \
6840     if (length < 0) length = StringLength(data);                           \
6841     i::Handle<i::String> handle_result =                                   \
6842         NewString(i_isolate->factory(), type,                              \
6843                   base::Vector<const Char>(data, length))                  \
6844             .ToHandleChecked();                                            \
6845     result = Utils::ToLocal(handle_result);                                \
6846   }
6847 
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6848 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6849                                          NewStringType type, int length) {
6850   DCHECK_LE(length, i::String::kMaxLength);
6851   i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6852   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6853   API_RCS_SCOPE(i_isolate, String, NewFromUtf8Literal);
6854   i::Handle<i::String> handle_result =
6855       NewString(i_isolate->factory(), type,
6856                 base::Vector<const char>(literal, length))
6857           .ToHandleChecked();
6858   return Utils::ToLocal(handle_result);
6859 }
6860 
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6861 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6862                                        NewStringType type, int length) {
6863   NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6864   return result;
6865 }
6866 
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6867 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6868                                           NewStringType type, int length) {
6869   NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6870   return result;
6871 }
6872 
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6873 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6874                                           const uint16_t* data,
6875                                           NewStringType type, int length) {
6876   NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6877   return result;
6878 }
6879 
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6880 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6881                                  Local<String> right) {
6882   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6883   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6884   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6885   API_RCS_SCOPE(isolate, String, Concat);
6886   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6887   // If we are steering towards a range error, do not wait for the error to be
6888   // thrown, and return the null handle instead.
6889   if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6890     return Local<String>();
6891   }
6892   i::Handle<i::String> result = isolate->factory()
6893                                     ->NewConsString(left_string, right_string)
6894                                     .ToHandleChecked();
6895   return Utils::ToLocal(result);
6896 }
6897 
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6898 MaybeLocal<String> v8::String::NewExternalTwoByte(
6899     Isolate* isolate, v8::String::ExternalStringResource* resource) {
6900   CHECK(resource && resource->data());
6901   // TODO(dcarney): throw a context free exception.
6902   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6903     return MaybeLocal<String>();
6904   }
6905   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6906   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6907   API_RCS_SCOPE(i_isolate, String, NewExternalTwoByte);
6908   if (resource->length() > 0) {
6909     i::Handle<i::String> string = i_isolate->factory()
6910                                       ->NewExternalStringFromTwoByte(resource)
6911                                       .ToHandleChecked();
6912     return Utils::ToLocal(string);
6913   } else {
6914     // The resource isn't going to be used, free it immediately.
6915     resource->Dispose();
6916     return Utils::ToLocal(i_isolate->factory()->empty_string());
6917   }
6918 }
6919 
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6920 MaybeLocal<String> v8::String::NewExternalOneByte(
6921     Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6922   CHECK_NOT_NULL(resource);
6923   // TODO(dcarney): throw a context free exception.
6924   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6925     return MaybeLocal<String>();
6926   }
6927   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6928   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6929   API_RCS_SCOPE(i_isolate, String, NewExternalOneByte);
6930   if (resource->length() == 0) {
6931     // The resource isn't going to be used, free it immediately.
6932     resource->Dispose();
6933     return Utils::ToLocal(i_isolate->factory()->empty_string());
6934   }
6935   CHECK_NOT_NULL(resource->data());
6936   i::Handle<i::String> string = i_isolate->factory()
6937                                     ->NewExternalStringFromOneByte(resource)
6938                                     .ToHandleChecked();
6939   return Utils::ToLocal(string);
6940 }
6941 
MakeExternal(v8::String::ExternalStringResource * resource)6942 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6943   i::DisallowGarbageCollection no_gc;
6944 
6945   i::String obj = *Utils::OpenHandle(this);
6946 
6947   if (obj.IsThinString()) {
6948     obj = i::ThinString::cast(obj).actual();
6949   }
6950 
6951   if (!obj.SupportsExternalization()) {
6952     return false;
6953   }
6954 
6955   // It is safe to call GetIsolateFromWritableHeapObject because
6956   // SupportsExternalization already checked that the object is writable.
6957   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6958   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6959 
6960   CHECK(resource && resource->data());
6961 
6962   bool result = obj.MakeExternal(resource);
6963   DCHECK(result);
6964   DCHECK(obj.IsExternalString());
6965   return result;
6966 }
6967 
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6968 bool v8::String::MakeExternal(
6969     v8::String::ExternalOneByteStringResource* resource) {
6970   i::DisallowGarbageCollection no_gc;
6971 
6972   i::String obj = *Utils::OpenHandle(this);
6973 
6974   if (obj.IsThinString()) {
6975     obj = i::ThinString::cast(obj).actual();
6976   }
6977 
6978   if (!obj.SupportsExternalization()) {
6979     return false;
6980   }
6981 
6982   // It is safe to call GetIsolateFromWritableHeapObject because
6983   // SupportsExternalization already checked that the object is writable.
6984   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6985   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6986 
6987   CHECK(resource && resource->data());
6988 
6989   bool result = obj.MakeExternal(resource);
6990   DCHECK_IMPLIES(result, obj.IsExternalString());
6991   return result;
6992 }
6993 
CanMakeExternal() const6994 bool v8::String::CanMakeExternal() const {
6995   i::String obj = *Utils::OpenHandle(this);
6996 
6997   if (obj.IsThinString()) {
6998     obj = i::ThinString::cast(obj).actual();
6999   }
7000 
7001   if (!obj.SupportsExternalization()) {
7002     return false;
7003   }
7004 
7005   // Only old space strings should be externalized.
7006   return !i::Heap::InYoungGeneration(obj);
7007 }
7008 
StringEquals(Local<String> that) const7009 bool v8::String::StringEquals(Local<String> that) const {
7010   auto self = Utils::OpenHandle(this);
7011   auto other = Utils::OpenHandle(*that);
7012   return self->Equals(*other);
7013 }
7014 
GetIsolate()7015 Isolate* v8::Object::GetIsolate() {
7016   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7017   return reinterpret_cast<Isolate*>(i_isolate);
7018 }
7019 
New(Isolate * isolate)7020 Local<v8::Object> v8::Object::New(Isolate* isolate) {
7021   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7022   API_RCS_SCOPE(i_isolate, Object, New);
7023   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7024   i::Handle<i::JSObject> obj =
7025       i_isolate->factory()->NewJSObject(i_isolate->object_function());
7026   return Utils::ToLocal(obj);
7027 }
7028 
7029 namespace {
7030 
7031 // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference
7032 // in the return types of the different Add functions:
7033 // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns
7034 // Handle.
7035 template <typename T>
ToHandle(i::Handle<T> h)7036 i::Handle<T> ToHandle(i::Handle<T> h) {
7037   return h;
7038 }
7039 template <typename T>
ToHandle(i::MaybeHandle<T> h)7040 i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
7041   return h.ToHandleChecked();
7042 }
7043 
7044 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)7045 void AddPropertiesAndElementsToObject(i::Isolate* i_isolate,
7046                                       i::Handle<Dictionary>& properties,
7047                                       i::Handle<i::FixedArrayBase>& elements,
7048                                       Local<Name>* names, Local<Value>* values,
7049                                       size_t length) {
7050   for (size_t i = 0; i < length; ++i) {
7051     i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
7052     i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
7053 
7054     // See if the {name} is a valid array index, in which case we need to
7055     // add the {name}/{value} pair to the {elements}, otherwise they end
7056     // up in the {properties} backing store.
7057     uint32_t index;
7058     if (name->AsArrayIndex(&index)) {
7059       // If this is the first element, allocate a proper
7060       // dictionary elements backing store for {elements}.
7061       if (!elements->IsNumberDictionary()) {
7062         elements =
7063             i::NumberDictionary::New(i_isolate, static_cast<int>(length));
7064       }
7065       elements = i::NumberDictionary::Set(
7066           i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
7067           value);
7068     } else {
7069       // Internalize the {name} first.
7070       name = i_isolate->factory()->InternalizeName(name);
7071       i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
7072       if (entry.is_not_found()) {
7073         // Add the {name}/{value} pair as a new entry.
7074         properties = ToHandle(Dictionary::Add(
7075             i_isolate, properties, name, value, i::PropertyDetails::Empty()));
7076       } else {
7077         // Overwrite the {entry} with the {value}.
7078         properties->ValueAtPut(entry, *value);
7079       }
7080     }
7081   }
7082 }
7083 
7084 }  // namespace
7085 
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)7086 Local<v8::Object> v8::Object::New(Isolate* isolate,
7087                                   Local<Value> prototype_or_null,
7088                                   Local<Name>* names, Local<Value>* values,
7089                                   size_t length) {
7090   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7091   i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
7092   if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
7093                        "v8::Object::New", "prototype must be null or object")) {
7094     return Local<v8::Object>();
7095   }
7096   API_RCS_SCOPE(i_isolate, Object, New);
7097   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7098 
7099   i::Handle<i::FixedArrayBase> elements =
7100       i_isolate->factory()->empty_fixed_array();
7101 
7102   // We assume that this API is mostly used to create objects with named
7103   // properties, and so we default to creating a properties backing store
7104   // large enough to hold all of them, while we start with no elements
7105   // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
7106   if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
7107     i::Handle<i::SwissNameDictionary> properties =
7108         i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length));
7109     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7110                                      values, length);
7111     i::Handle<i::JSObject> obj =
7112         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7113             i::Handle<i::HeapObject>::cast(proto), properties, elements);
7114     return Utils::ToLocal(obj);
7115   } else {
7116     i::Handle<i::NameDictionary> properties =
7117         i::NameDictionary::New(i_isolate, static_cast<int>(length));
7118     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7119                                      values, length);
7120     i::Handle<i::JSObject> obj =
7121         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7122             i::Handle<i::HeapObject>::cast(proto), properties, elements);
7123     return Utils::ToLocal(obj);
7124   }
7125 }
7126 
New(Isolate * isolate,double value)7127 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
7128   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7129   API_RCS_SCOPE(i_isolate, NumberObject, New);
7130   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7131   i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
7132   i::Handle<i::Object> obj =
7133       i::Object::ToObject(i_isolate, number).ToHandleChecked();
7134   return Utils::ToLocal(obj);
7135 }
7136 
ValueOf() const7137 double v8::NumberObject::ValueOf() const {
7138   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7139   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7140       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7141   API_RCS_SCOPE(js_primitive_wrapper->GetIsolate(), NumberObject, NumberValue);
7142   return js_primitive_wrapper->value().Number();
7143 }
7144 
New(Isolate * isolate,int64_t value)7145 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
7146   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7147   API_RCS_SCOPE(i_isolate, BigIntObject, New);
7148   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7149   i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
7150   i::Handle<i::Object> obj =
7151       i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
7152   return Utils::ToLocal(obj);
7153 }
7154 
ValueOf() const7155 Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
7156   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7157   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7158       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7159   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7160   API_RCS_SCOPE(isolate, BigIntObject, BigIntValue);
7161   return Utils::ToLocal(i::Handle<i::BigInt>(
7162       i::BigInt::cast(js_primitive_wrapper->value()), isolate));
7163 }
7164 
New(Isolate * isolate,bool value)7165 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7166   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7167   API_RCS_SCOPE(i_isolate, BooleanObject, New);
7168   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7169   i::Handle<i::Object> boolean(value
7170                                    ? i::ReadOnlyRoots(i_isolate).true_value()
7171                                    : i::ReadOnlyRoots(i_isolate).false_value(),
7172                                i_isolate);
7173   i::Handle<i::Object> obj =
7174       i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7175   return Utils::ToLocal(obj);
7176 }
7177 
ValueOf() const7178 bool v8::BooleanObject::ValueOf() const {
7179   i::Object obj = *Utils::OpenHandle(this);
7180   i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
7181   i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
7182   API_RCS_SCOPE(isolate, BooleanObject, BooleanValue);
7183   return js_primitive_wrapper.value().IsTrue(isolate);
7184 }
7185 
New(Isolate * v8_isolate,Local<String> value)7186 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
7187                                        Local<String> value) {
7188   i::Handle<i::String> string = Utils::OpenHandle(*value);
7189   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7190   API_RCS_SCOPE(isolate, StringObject, New);
7191   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7192   i::Handle<i::Object> obj =
7193       i::Object::ToObject(isolate, string).ToHandleChecked();
7194   return Utils::ToLocal(obj);
7195 }
7196 
ValueOf() const7197 Local<v8::String> v8::StringObject::ValueOf() const {
7198   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7199   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7200       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7201   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7202   API_RCS_SCOPE(isolate, StringObject, StringValue);
7203   return Utils::ToLocal(i::Handle<i::String>(
7204       i::String::cast(js_primitive_wrapper->value()), isolate));
7205 }
7206 
New(Isolate * isolate,Local<Symbol> value)7207 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7208   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7209   API_RCS_SCOPE(i_isolate, SymbolObject, New);
7210   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7211   i::Handle<i::Object> obj =
7212       i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
7213           .ToHandleChecked();
7214   return Utils::ToLocal(obj);
7215 }
7216 
ValueOf() const7217 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7218   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7219   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7220       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7221   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7222   API_RCS_SCOPE(isolate, SymbolObject, SymbolValue);
7223   return Utils::ToLocal(i::Handle<i::Symbol>(
7224       i::Symbol::cast(js_primitive_wrapper->value()), isolate));
7225 }
7226 
New(Local<Context> context,double time)7227 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7228   if (std::isnan(time)) {
7229     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7230     time = std::numeric_limits<double>::quiet_NaN();
7231   }
7232   PREPARE_FOR_EXECUTION(context, Date, New, Value);
7233   Local<Value> result;
7234   has_pending_exception = !ToLocal<Value>(
7235       i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7236       &result);
7237   RETURN_ON_FAILED_EXECUTION(Value);
7238   RETURN_ESCAPED(result);
7239 }
7240 
ValueOf() const7241 double v8::Date::ValueOf() const {
7242   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7243   i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7244   API_RCS_SCOPE(jsdate->GetIsolate(), Date, NumberValue);
7245   return jsdate->value().Number();
7246 }
7247 
7248 // Assert that the static TimeZoneDetection cast in
7249 // DateTimeConfigurationChangeNotification is valid.
7250 #define TIME_ZONE_DETECTION_ASSERT_EQ(value)                     \
7251   STATIC_ASSERT(                                                 \
7252       static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
7253       static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
7254 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7255 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7256 #undef TIME_ZONE_DETECTION_ASSERT_EQ
7257 
7258 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7259                                        Local<String> pattern, Flags flags) {
7260   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7261   Local<v8::RegExp> result;
7262   has_pending_exception =
7263       !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7264                                         static_cast<i::JSRegExp::Flags>(flags)),
7265                        &result);
7266   RETURN_ON_FAILED_EXECUTION(RegExp);
7267   RETURN_ESCAPED(result);
7268 }
7269 
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7270 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
7271     Local<Context> context, Local<String> pattern, Flags flags,
7272     uint32_t backtrack_limit) {
7273   Utils::ApiCheck(i::Smi::IsValid(backtrack_limit),
7274                   "v8::RegExp::NewWithBacktrackLimit",
7275                   "backtrack_limit is too large or too small.");
7276   Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit,
7277                   "v8::RegExp::NewWithBacktrackLimit",
7278                   "Must set backtrack_limit");
7279   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7280   Local<v8::RegExp> result;
7281   has_pending_exception = !ToLocal<RegExp>(
7282       i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7283                        static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
7284       &result);
7285   RETURN_ON_FAILED_EXECUTION(RegExp);
7286   RETURN_ESCAPED(result);
7287 }
7288 
GetSource() const7289 Local<v8::String> v8::RegExp::GetSource() const {
7290   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7291   return Utils::ToLocal(
7292       i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate()));
7293 }
7294 
7295 // Assert that the static flags cast in GetFlags is valid.
7296 #define REGEXP_FLAG_ASSERT_EQ(flag)                   \
7297   STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7298                 static_cast<int>(i::JSRegExp::flag))
7299 REGEXP_FLAG_ASSERT_EQ(kNone);
7300 REGEXP_FLAG_ASSERT_EQ(kGlobal);
7301 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7302 REGEXP_FLAG_ASSERT_EQ(kMultiline);
7303 REGEXP_FLAG_ASSERT_EQ(kSticky);
7304 REGEXP_FLAG_ASSERT_EQ(kUnicode);
7305 REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7306 REGEXP_FLAG_ASSERT_EQ(kLinear);
7307 #undef REGEXP_FLAG_ASSERT_EQ
7308 
GetFlags() const7309 v8::RegExp::Flags v8::RegExp::GetFlags() const {
7310   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7311   return RegExp::Flags(static_cast<int>(obj->flags()));
7312 }
7313 
Exec(Local<Context> context,Local<v8::String> subject)7314 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
7315                                         Local<v8::String> subject) {
7316   PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
7317 
7318   i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
7319   i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
7320 
7321   // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
7322   // mind. It fetches the 'exec' property and then calls it through JSEntry.
7323   // Unfortunately, this is currently the only full implementation of
7324   // RegExp.prototype.exec available in C++.
7325   Local<v8::Object> result;
7326   has_pending_exception = !ToLocal<Object>(
7327       i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
7328                                  isolate->factory()->undefined_value()),
7329       &result);
7330 
7331   RETURN_ON_FAILED_EXECUTION(Object);
7332   RETURN_ESCAPED(result);
7333 }
7334 
New(Isolate * isolate,int length)7335 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7336   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7337   API_RCS_SCOPE(i_isolate, Array, New);
7338   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7339   int real_length = length > 0 ? length : 0;
7340   i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7341   i::Handle<i::Object> length_obj =
7342       i_isolate->factory()->NewNumberFromInt(real_length);
7343   obj->set_length(*length_obj);
7344   return Utils::ToLocal(obj);
7345 }
7346 
New(Isolate * isolate,Local<Value> * elements,size_t length)7347 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
7348                                 size_t length) {
7349   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7350   i::Factory* factory = i_isolate->factory();
7351   API_RCS_SCOPE(i_isolate, Array, New);
7352   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7353   int len = static_cast<int>(length);
7354 
7355   i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
7356   for (int i = 0; i < len; i++) {
7357     i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
7358     result->set(i, *element);
7359   }
7360 
7361   return Utils::ToLocal(
7362       factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
7363 }
7364 
Length() const7365 uint32_t v8::Array::Length() const {
7366   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7367   i::Object length = obj->length();
7368   if (length.IsSmi()) {
7369     return i::Smi::ToInt(length);
7370   } else {
7371     return static_cast<uint32_t>(length.Number());
7372   }
7373 }
7374 
New(Isolate * isolate)7375 Local<v8::Map> v8::Map::New(Isolate* isolate) {
7376   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7377   API_RCS_SCOPE(i_isolate, Map, New);
7378   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7379   i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7380   return Utils::ToLocal(obj);
7381 }
7382 
Size() const7383 size_t v8::Map::Size() const {
7384   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7385   return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7386 }
7387 
Clear()7388 void Map::Clear() {
7389   auto self = Utils::OpenHandle(this);
7390   i::Isolate* isolate = self->GetIsolate();
7391   API_RCS_SCOPE(isolate, Map, Clear);
7392   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7393   i::JSMap::Clear(isolate, self);
7394 }
7395 
Get(Local<Context> context,Local<Value> key)7396 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7397   PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7398   auto self = Utils::OpenHandle(this);
7399   Local<Value> result;
7400   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7401   has_pending_exception =
7402       !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
7403                                                 self, arraysize(argv), argv),
7404                       &result);
7405   RETURN_ON_FAILED_EXECUTION(Value);
7406   RETURN_ESCAPED(result);
7407 }
7408 
Set(Local<Context> context,Local<Value> key,Local<Value> value)7409 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7410                          Local<Value> value) {
7411   PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7412   auto self = Utils::OpenHandle(this);
7413   i::Handle<i::Object> result;
7414   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7415                                  Utils::OpenHandle(*value)};
7416   has_pending_exception =
7417       !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
7418                                  arraysize(argv), argv)
7419            .ToHandle(&result);
7420   RETURN_ON_FAILED_EXECUTION(Map);
7421   RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7422 }
7423 
Has(Local<Context> context,Local<Value> key)7424 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7425   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7426   ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7427   auto self = Utils::OpenHandle(this);
7428   i::Handle<i::Object> result;
7429   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7430   has_pending_exception =
7431       !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
7432                                  arraysize(argv), argv)
7433            .ToHandle(&result);
7434   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7435   return Just(result->IsTrue(isolate));
7436 }
7437 
Delete(Local<Context> context,Local<Value> key)7438 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7439   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7440   ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7441   auto self = Utils::OpenHandle(this);
7442   i::Handle<i::Object> result;
7443   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7444   has_pending_exception =
7445       !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
7446                                  arraysize(argv), argv)
7447            .ToHandle(&result);
7448   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7449   return Just(result->IsTrue(isolate));
7450 }
7451 
7452 namespace {
7453 
7454 enum class MapAsArrayKind {
7455   kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7456   kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7457   kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7458 };
7459 
7460 enum class SetAsArrayKind {
7461   kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7462   kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7463 };
7464 
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7465 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7466                                  int offset, MapAsArrayKind kind) {
7467   i::Factory* factory = isolate->factory();
7468   i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7469                                      isolate);
7470   const bool collect_keys =
7471       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7472   const bool collect_values =
7473       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7474   int capacity = table->UsedCapacity();
7475   int max_length =
7476       (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7477   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7478   int result_index = 0;
7479   {
7480     i::DisallowGarbageCollection no_gc;
7481     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7482     for (int i = offset; i < capacity; ++i) {
7483       i::InternalIndex entry(i);
7484       i::Object key = table->KeyAt(entry);
7485       if (key == the_hole) continue;
7486       if (collect_keys) result->set(result_index++, key);
7487       if (collect_values) result->set(result_index++, table->ValueAt(entry));
7488     }
7489   }
7490   DCHECK_GE(max_length, result_index);
7491   if (result_index == 0) return factory->NewJSArray(0);
7492   result->Shrink(isolate, result_index);
7493   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7494                                          result_index);
7495 }
7496 
7497 }  // namespace
7498 
AsArray() const7499 Local<Array> Map::AsArray() const {
7500   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7501   i::Isolate* isolate = obj->GetIsolate();
7502   API_RCS_SCOPE(isolate, Map, AsArray);
7503   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7504   return Utils::ToLocal(
7505       MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7506 }
7507 
New(Isolate * isolate)7508 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7509   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7510   API_RCS_SCOPE(i_isolate, Set, New);
7511   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7512   i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7513   return Utils::ToLocal(obj);
7514 }
7515 
Size() const7516 size_t v8::Set::Size() const {
7517   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7518   return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7519 }
7520 
Clear()7521 void Set::Clear() {
7522   auto self = Utils::OpenHandle(this);
7523   i::Isolate* isolate = self->GetIsolate();
7524   API_RCS_SCOPE(isolate, Set, Clear);
7525   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7526   i::JSSet::Clear(isolate, self);
7527 }
7528 
Add(Local<Context> context,Local<Value> key)7529 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7530   PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7531   auto self = Utils::OpenHandle(this);
7532   i::Handle<i::Object> result;
7533   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7534   has_pending_exception =
7535       !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7536                                  arraysize(argv), argv)
7537            .ToHandle(&result);
7538   RETURN_ON_FAILED_EXECUTION(Set);
7539   RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7540 }
7541 
Has(Local<Context> context,Local<Value> key)7542 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7543   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7544   ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7545   auto self = Utils::OpenHandle(this);
7546   i::Handle<i::Object> result;
7547   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7548   has_pending_exception =
7549       !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7550                                  arraysize(argv), argv)
7551            .ToHandle(&result);
7552   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7553   return Just(result->IsTrue(isolate));
7554 }
7555 
Delete(Local<Context> context,Local<Value> key)7556 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7557   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7558   ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7559   auto self = Utils::OpenHandle(this);
7560   i::Handle<i::Object> result;
7561   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7562   has_pending_exception =
7563       !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7564                                  arraysize(argv), argv)
7565            .ToHandle(&result);
7566   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7567   return Just(result->IsTrue(isolate));
7568 }
7569 
7570 namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7571 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7572                                  int offset, SetAsArrayKind kind) {
7573   i::Factory* factory = isolate->factory();
7574   i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7575                                      isolate);
7576   // Elements skipped by |offset| may already be deleted.
7577   int capacity = table->UsedCapacity();
7578   const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7579   int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7580   if (max_length == 0) return factory->NewJSArray(0);
7581   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7582   int result_index = 0;
7583   {
7584     i::DisallowGarbageCollection no_gc;
7585     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7586     for (int i = offset; i < capacity; ++i) {
7587       i::InternalIndex entry(i);
7588       i::Object key = table->KeyAt(entry);
7589       if (key == the_hole) continue;
7590       result->set(result_index++, key);
7591       if (collect_key_values) result->set(result_index++, key);
7592     }
7593   }
7594   DCHECK_GE(max_length, result_index);
7595   if (result_index == 0) return factory->NewJSArray(0);
7596   result->Shrink(isolate, result_index);
7597   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7598                                          result_index);
7599 }
7600 }  // namespace
7601 
AsArray() const7602 Local<Array> Set::AsArray() const {
7603   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7604   i::Isolate* isolate = obj->GetIsolate();
7605   API_RCS_SCOPE(isolate, Set, AsArray);
7606   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7607   return Utils::ToLocal(
7608       SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7609 }
7610 
New(Local<Context> context)7611 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7612   PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7613   Local<Promise::Resolver> result;
7614   has_pending_exception =
7615       !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7616   RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7617   RETURN_ESCAPED(result);
7618 }
7619 
GetPromise()7620 Local<Promise> Promise::Resolver::GetPromise() {
7621   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7622   return Local<Promise>::Cast(Utils::ToLocal(promise));
7623 }
7624 
Resolve(Local<Context> context,Local<Value> value)7625 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7626                                        Local<Value> value) {
7627   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7628   ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7629            i::HandleScope);
7630   auto self = Utils::OpenHandle(this);
7631   auto promise = i::Handle<i::JSPromise>::cast(self);
7632 
7633   if (promise->status() != Promise::kPending) {
7634     return Just(true);
7635   }
7636 
7637   has_pending_exception =
7638       i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7639   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7640   return Just(true);
7641 }
7642 
Reject(Local<Context> context,Local<Value> value)7643 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7644                                       Local<Value> value) {
7645   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7646   ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7647            i::HandleScope);
7648   auto self = Utils::OpenHandle(this);
7649   auto promise = i::Handle<i::JSPromise>::cast(self);
7650 
7651   if (promise->status() != Promise::kPending) {
7652     return Just(true);
7653   }
7654 
7655   has_pending_exception =
7656       i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7657   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7658   return Just(true);
7659 }
7660 
Catch(Local<Context> context,Local<Function> handler)7661 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7662                                    Local<Function> handler) {
7663   PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7664   auto self = Utils::OpenHandle(this);
7665   i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(),
7666                                  Utils::OpenHandle(*handler)};
7667   i::Handle<i::Object> result;
7668   // Do not call the built-in Promise.prototype.catch!
7669   // v8::Promise should not call out to a monkeypatched Promise.prototype.then
7670   // as the implementation of Promise.prototype.catch does.
7671   has_pending_exception =
7672       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7673                                  arraysize(argv), argv)
7674            .ToHandle(&result);
7675   RETURN_ON_FAILED_EXECUTION(Promise);
7676   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7677 }
7678 
Then(Local<Context> context,Local<Function> handler)7679 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7680                                   Local<Function> handler) {
7681   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7682   auto self = Utils::OpenHandle(this);
7683   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7684   i::Handle<i::Object> result;
7685   has_pending_exception =
7686       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7687                                  arraysize(argv), argv)
7688            .ToHandle(&result);
7689   RETURN_ON_FAILED_EXECUTION(Promise);
7690   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7691 }
7692 
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7693 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7694                                   Local<Function> on_fulfilled,
7695                                   Local<Function> on_rejected) {
7696   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7697   auto self = Utils::OpenHandle(this);
7698   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7699                                  Utils::OpenHandle(*on_rejected)};
7700   i::Handle<i::Object> result;
7701   has_pending_exception =
7702       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7703                                  arraysize(argv), argv)
7704            .ToHandle(&result);
7705   RETURN_ON_FAILED_EXECUTION(Promise);
7706   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7707 }
7708 
HasHandler() const7709 bool Promise::HasHandler() const {
7710   i::JSReceiver promise = *Utils::OpenHandle(this);
7711   i::Isolate* isolate = promise.GetIsolate();
7712   API_RCS_SCOPE(isolate, Promise, HasRejectHandler);
7713   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7714   if (!promise.IsJSPromise()) return false;
7715   return i::JSPromise::cast(promise).has_handler();
7716 }
7717 
Result()7718 Local<Value> Promise::Result() {
7719   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7720   i::Isolate* isolate = promise->GetIsolate();
7721   API_RCS_SCOPE(isolate, Promise, Result);
7722   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7723   Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7724                   "Promise is still pending");
7725   i::Handle<i::Object> result(js_promise->result(), isolate);
7726   return Utils::ToLocal(result);
7727 }
7728 
State()7729 Promise::PromiseState Promise::State() {
7730   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7731   API_RCS_SCOPE(promise->GetIsolate(), Promise, Status);
7732   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7733   return static_cast<PromiseState>(js_promise->status());
7734 }
7735 
MarkAsHandled()7736 void Promise::MarkAsHandled() {
7737   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7738   js_promise->set_has_handler(true);
7739 }
7740 
MarkAsSilent()7741 void Promise::MarkAsSilent() {
7742   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7743   js_promise->set_is_silent(true);
7744 }
7745 
GetTarget()7746 Local<Value> Proxy::GetTarget() {
7747   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7748   i::Handle<i::Object> target(self->target(), self->GetIsolate());
7749   return Utils::ToLocal(target);
7750 }
7751 
GetHandler()7752 Local<Value> Proxy::GetHandler() {
7753   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7754   i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7755   return Utils::ToLocal(handler);
7756 }
7757 
IsRevoked() const7758 bool Proxy::IsRevoked() const {
7759   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7760   return self->IsRevoked();
7761 }
7762 
Revoke()7763 void Proxy::Revoke() {
7764   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7765   i::JSProxy::Revoke(self);
7766 }
7767 
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7768 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7769                              Local<Object> local_handler) {
7770   PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7771   i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7772   i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7773   Local<Proxy> result;
7774   has_pending_exception =
7775       !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7776   RETURN_ON_FAILED_EXECUTION(Proxy);
7777   RETURN_ESCAPED(result);
7778 }
7779 
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7780 CompiledWasmModule::CompiledWasmModule(
7781     std::shared_ptr<internal::wasm::NativeModule> native_module,
7782     const char* source_url, size_t url_length)
7783     : native_module_(std::move(native_module)),
7784       source_url_(source_url, url_length) {
7785   CHECK_NOT_NULL(native_module_);
7786 }
7787 
Serialize()7788 OwnedBuffer CompiledWasmModule::Serialize() {
7789 #if V8_ENABLE_WEBASSEMBLY
7790   TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7791   i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7792   size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7793   std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7794   if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7795     return {};
7796   return {std::move(buffer), buffer_size};
7797 #else
7798   UNREACHABLE();
7799 #endif  // V8_ENABLE_WEBASSEMBLY
7800 }
7801 
GetWireBytesRef()7802 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7803 #if V8_ENABLE_WEBASSEMBLY
7804   base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7805   return {bytes_vec.begin(), bytes_vec.size()};
7806 #else
7807   UNREACHABLE();
7808 #endif  // V8_ENABLE_WEBASSEMBLY
7809 }
7810 
Buffer()7811 Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() {
7812 #if V8_ENABLE_WEBASSEMBLY
7813   i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this);
7814   i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate());
7815   return Utils::ToLocal(buffer);
7816 #else
7817   UNREACHABLE();
7818 #endif  // V8_ENABLE_WEBASSEMBLY
7819 }
7820 
GetCompiledModule()7821 CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7822 #if V8_ENABLE_WEBASSEMBLY
7823   auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7824   auto url =
7825       i::handle(i::String::cast(obj->script().name()), obj->GetIsolate());
7826   int length;
7827   std::unique_ptr<char[]> cstring =
7828       url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7829   return CompiledWasmModule(std::move(obj->shared_native_module()),
7830                             cstring.get(), length);
7831 #else
7832   UNREACHABLE();
7833 #endif  // V8_ENABLE_WEBASSEMBLY
7834 }
7835 
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7836 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7837     Isolate* isolate, const CompiledWasmModule& compiled_module) {
7838 #if V8_ENABLE_WEBASSEMBLY
7839   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7840   i::Handle<i::WasmModuleObject> module_object =
7841       i::wasm::GetWasmEngine()->ImportNativeModule(
7842           i_isolate, compiled_module.native_module_,
7843           base::VectorOf(compiled_module.source_url()));
7844   return Local<WasmModuleObject>::Cast(
7845       Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7846 #else
7847   UNREACHABLE();
7848 #endif  // V8_ENABLE_WEBASSEMBLY
7849 }
7850 
Compile(Isolate * isolate,MemorySpan<const uint8_t> wire_bytes)7851 MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
7852     Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) {
7853 #if V8_ENABLE_WEBASSEMBLY
7854   const uint8_t* start = wire_bytes.data();
7855   size_t length = wire_bytes.size();
7856   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7857   if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7858     return MaybeLocal<WasmModuleObject>();
7859   }
7860   i::MaybeHandle<i::JSObject> maybe_compiled;
7861   {
7862     i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
7863     auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
7864     maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
7865         i_isolate, enabled_features, &thrower,
7866         i::wasm::ModuleWireBytes(start, start + length));
7867   }
7868   CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception());
7869   if (maybe_compiled.is_null()) {
7870     i_isolate->OptionalRescheduleException(false);
7871     return MaybeLocal<WasmModuleObject>();
7872   }
7873   return Local<WasmModuleObject>::Cast(
7874       Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7875 #else
7876   Utils::ApiCheck(false, "WasmModuleObject::Compile",
7877                   "WebAssembly support is not enabled.");
7878   UNREACHABLE();
7879 #endif  // V8_ENABLE_WEBASSEMBLY
7880 }
7881 
WasmModuleObjectBuilderStreaming(Isolate * isolate)7882 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7883     Isolate* isolate) {
7884   USE(isolate_);
7885 }
7886 
GetPromise()7887 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7888 
OnBytesReceived(const uint8_t * bytes,size_t size)7889 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7890                                                        size_t size) {}
7891 
Finish()7892 void WasmModuleObjectBuilderStreaming::Finish() {}
7893 
Abort(MaybeLocal<Value> exception)7894 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7895 
Reallocate(void * data,size_t old_length,size_t new_length)7896 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7897                                              size_t new_length) {
7898   if (old_length == new_length) return data;
7899   uint8_t* new_data =
7900       reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7901   if (new_data == nullptr) return nullptr;
7902   size_t bytes_to_copy = std::min(old_length, new_length);
7903   memcpy(new_data, data, bytes_to_copy);
7904   if (new_length > bytes_to_copy) {
7905     memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7906   }
7907   Free(data, old_length);
7908   return new_data;
7909 }
7910 
7911 // static
NewDefaultAllocator()7912 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7913   return new ArrayBufferAllocator();
7914 }
7915 
IsDetachable() const7916 bool v8::ArrayBuffer::IsDetachable() const {
7917   return Utils::OpenHandle(this)->is_detachable();
7918 }
7919 
WasDetached() const7920 bool v8::ArrayBuffer::WasDetached() const {
7921   return Utils::OpenHandle(this)->was_detached();
7922 }
7923 
7924 namespace {
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7925 std::shared_ptr<i::BackingStore> ToInternal(
7926     std::shared_ptr<i::BackingStoreBase> backing_store) {
7927   return std::static_pointer_cast<i::BackingStore>(backing_store);
7928 }
7929 }  // namespace
7930 
Detach()7931 void v8::ArrayBuffer::Detach() {
7932   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7933   i::Isolate* isolate = obj->GetIsolate();
7934   Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
7935                   "Only detachable ArrayBuffers can be detached");
7936   API_RCS_SCOPE(isolate, ArrayBuffer, Detach);
7937   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7938   obj->Detach();
7939 }
7940 
ByteLength() const7941 size_t v8::ArrayBuffer::ByteLength() const {
7942   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7943   return obj->byte_length();
7944 }
7945 
New(Isolate * isolate,size_t byte_length)7946 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7947   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7948   API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7949   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7950   i::MaybeHandle<i::JSArrayBuffer> result =
7951       i_isolate->factory()->NewJSArrayBufferAndBackingStore(
7952           byte_length, i::InitializedFlag::kZeroInitialized);
7953 
7954   i::Handle<i::JSArrayBuffer> array_buffer;
7955   if (!result.ToHandle(&array_buffer)) {
7956     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7957     // version that throws an exception or otherwise does not crash.
7958     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
7959   }
7960 
7961   return Utils::ToLocal(array_buffer);
7962 }
7963 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7964 Local<ArrayBuffer> v8::ArrayBuffer::New(
7965     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7966   CHECK_IMPLIES(backing_store->ByteLength() != 0,
7967                 backing_store->Data() != nullptr);
7968   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7969   API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7970   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7971   std::shared_ptr<i::BackingStore> i_backing_store(
7972       ToInternal(std::move(backing_store)));
7973   Utils::ApiCheck(
7974       !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
7975       "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
7976   i::Handle<i::JSArrayBuffer> obj =
7977       i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
7978   return Utils::ToLocal(obj);
7979 }
7980 
NewBackingStore(Isolate * isolate,size_t byte_length)7981 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7982     Isolate* isolate, size_t byte_length) {
7983   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7984   API_RCS_SCOPE(i_isolate, ArrayBuffer, NewBackingStore);
7985   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7986   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7987   std::unique_ptr<i::BackingStoreBase> backing_store =
7988       i::BackingStore::Allocate(i_isolate, byte_length,
7989                                 i::SharedFlag::kNotShared,
7990                                 i::InitializedFlag::kZeroInitialized);
7991   if (!backing_store) {
7992     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
7993   }
7994   return std::unique_ptr<v8::BackingStore>(
7995       static_cast<v8::BackingStore*>(backing_store.release()));
7996 }
7997 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)7998 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7999     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8000     void* deleter_data) {
8001   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8002   std::unique_ptr<i::BackingStoreBase> backing_store =
8003       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8004                                       i::SharedFlag::kNotShared);
8005   return std::unique_ptr<v8::BackingStore>(
8006       static_cast<v8::BackingStore*>(backing_store.release()));
8007 }
8008 
Buffer()8009 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
8010   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8011   i::Handle<i::JSArrayBuffer> buffer;
8012   if (obj->IsJSDataView()) {
8013     i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
8014                                        obj->GetIsolate());
8015     DCHECK(data_view->buffer().IsJSArrayBuffer());
8016     buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
8017                        data_view->GetIsolate());
8018   } else {
8019     DCHECK(obj->IsJSTypedArray());
8020     buffer = i::JSTypedArray::cast(*obj).GetBuffer();
8021   }
8022   return Utils::ToLocal(buffer);
8023 }
8024 
CopyContents(void * dest,size_t byte_length)8025 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
8026   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8027   size_t bytes_to_copy = std::min(byte_length, self->byte_length());
8028   if (bytes_to_copy) {
8029     i::DisallowGarbageCollection no_gc;
8030     i::Isolate* isolate = self->GetIsolate();
8031     const char* source;
8032     if (self->IsJSTypedArray()) {
8033       i::Handle<i::JSTypedArray> array(i::JSTypedArray::cast(*self), isolate);
8034       source = reinterpret_cast<char*>(array->DataPtr());
8035     } else {
8036       DCHECK(self->IsJSDataView());
8037       i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*self), isolate);
8038       source = reinterpret_cast<char*>(data_view->data_pointer());
8039     }
8040     memcpy(dest, source, bytes_to_copy);
8041   }
8042   return bytes_to_copy;
8043 }
8044 
HasBuffer() const8045 bool v8::ArrayBufferView::HasBuffer() const {
8046   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8047   if (!self->IsJSTypedArray()) return true;
8048   auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
8049   return !typed_array->is_on_heap();
8050 }
8051 
ByteOffset()8052 size_t v8::ArrayBufferView::ByteOffset() {
8053   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8054   return obj->WasDetached() ? 0 : obj->byte_offset();
8055 }
8056 
ByteLength()8057 size_t v8::ArrayBufferView::ByteLength() {
8058   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8059   return obj->WasDetached() ? 0 : obj->byte_length();
8060 }
8061 
Length()8062 size_t v8::TypedArray::Length() {
8063   i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8064   return obj->WasDetached() ? 0 : obj->length();
8065 }
8066 
8067 static_assert(
8068     v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
8069     "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
8070 
8071 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype)                           \
8072   Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer,     \
8073                                       size_t byte_offset, size_t length) { \
8074     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();  \
8075     API_RCS_SCOPE(isolate, Type##Array, New);                              \
8076     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8077     if (!Utils::ApiCheck(length <= kMaxLength,                             \
8078                          "v8::" #Type                                      \
8079                          "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
8080                          "length exceeds max allowed value")) {            \
8081       return Local<Type##Array>();                                         \
8082     }                                                                      \
8083     i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
8084     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8085         i::kExternal##Type##Array, buffer, byte_offset, length);           \
8086     return Utils::ToLocal##Type##Array(obj);                               \
8087   }                                                                        \
8088   Local<Type##Array> Type##Array::New(                                     \
8089       Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset,    \
8090       size_t length) {                                                     \
8091     CHECK(i::FLAG_harmony_sharedarraybuffer);                              \
8092     i::Isolate* isolate =                                                  \
8093         Utils::OpenHandle(*shared_array_buffer)->GetIsolate();             \
8094     API_RCS_SCOPE(isolate, Type##Array, New);                              \
8095     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
8096     if (!Utils::ApiCheck(                                                  \
8097             length <= kMaxLength,                                          \
8098             "v8::" #Type                                                   \
8099             "Array::New(Local<SharedArrayBuffer>, size_t, size_t)",        \
8100             "length exceeds max allowed value")) {                         \
8101       return Local<Type##Array>();                                         \
8102     }                                                                      \
8103     i::Handle<i::JSArrayBuffer> buffer =                                   \
8104         Utils::OpenHandle(*shared_array_buffer);                           \
8105     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
8106         i::kExternal##Type##Array, buffer, byte_offset, length);           \
8107     return Utils::ToLocal##Type##Array(obj);                               \
8108   }
8109 
TYPED_ARRAYS(TYPED_ARRAY_NEW)8110 TYPED_ARRAYS(TYPED_ARRAY_NEW)
8111 #undef TYPED_ARRAY_NEW
8112 
8113 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
8114                               size_t byte_offset, size_t byte_length) {
8115   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
8116   i::Isolate* isolate = buffer->GetIsolate();
8117   API_RCS_SCOPE(isolate, DataView, New);
8118   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8119   i::Handle<i::JSDataView> obj =
8120       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8121   return Utils::ToLocal(obj);
8122 }
8123 
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)8124 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
8125                               size_t byte_offset, size_t byte_length) {
8126   CHECK(i::FLAG_harmony_sharedarraybuffer);
8127   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
8128   i::Isolate* isolate = buffer->GetIsolate();
8129   API_RCS_SCOPE(isolate, DataView, New);
8130   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8131   i::Handle<i::JSDataView> obj =
8132       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8133   return Utils::ToLocal(obj);
8134 }
8135 
ByteLength() const8136 size_t v8::SharedArrayBuffer::ByteLength() const {
8137   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8138   return obj->byte_length();
8139 }
8140 
New(Isolate * isolate,size_t byte_length)8141 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
8142                                                     size_t byte_length) {
8143   CHECK(i::FLAG_harmony_sharedarraybuffer);
8144   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8145   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8146   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8147 
8148   std::unique_ptr<i::BackingStore> backing_store =
8149       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8150                                 i::InitializedFlag::kZeroInitialized);
8151 
8152   if (!backing_store) {
8153     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8154     // version that throws an exception or otherwise does not crash.
8155     i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
8156   }
8157 
8158   i::Handle<i::JSArrayBuffer> obj =
8159       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
8160   return Utils::ToLocalShared(obj);
8161 }
8162 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8163 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
8164     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
8165   CHECK(i::FLAG_harmony_sharedarraybuffer);
8166   CHECK_IMPLIES(backing_store->ByteLength() != 0,
8167                 backing_store->Data() != nullptr);
8168   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8169   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8170   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8171   std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
8172   Utils::ApiCheck(
8173       i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
8174       "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
8175   i::Handle<i::JSArrayBuffer> obj =
8176       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
8177   return Utils::ToLocalShared(obj);
8178 }
8179 
NewBackingStore(Isolate * isolate,size_t byte_length)8180 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8181     Isolate* isolate, size_t byte_length) {
8182   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8183   API_RCS_SCOPE(i_isolate, SharedArrayBuffer, NewBackingStore);
8184   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8185   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8186   std::unique_ptr<i::BackingStoreBase> backing_store =
8187       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8188                                 i::InitializedFlag::kZeroInitialized);
8189   if (!backing_store) {
8190     i::FatalProcessOutOfMemory(i_isolate,
8191                                "v8::SharedArrayBuffer::NewBackingStore");
8192   }
8193   return std::unique_ptr<v8::BackingStore>(
8194       static_cast<v8::BackingStore*>(backing_store.release()));
8195 }
8196 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8197 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8198     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8199     void* deleter_data) {
8200   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8201   std::unique_ptr<i::BackingStoreBase> backing_store =
8202       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8203                                       i::SharedFlag::kShared);
8204   return std::unique_ptr<v8::BackingStore>(
8205       static_cast<v8::BackingStore*>(backing_store.release()));
8206 }
8207 
New(Isolate * isolate,Local<String> name)8208 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8209   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8210   API_RCS_SCOPE(i_isolate, Symbol, New);
8211   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8212   i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8213   if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8214   return Utils::ToLocal(result);
8215 }
8216 
For(Isolate * isolate,Local<String> name)8217 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8218   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8219   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8220   return Utils::ToLocal(
8221       i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8222 }
8223 
ForApi(Isolate * isolate,Local<String> name)8224 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8225   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8226   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8227   return Utils::ToLocal(
8228       i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8229 }
8230 
8231 #define WELL_KNOWN_SYMBOLS(V)                 \
8232   V(AsyncIterator, async_iterator)            \
8233   V(HasInstance, has_instance)                \
8234   V(IsConcatSpreadable, is_concat_spreadable) \
8235   V(Iterator, iterator)                       \
8236   V(Match, match)                             \
8237   V(Replace, replace)                         \
8238   V(Search, search)                           \
8239   V(Split, split)                             \
8240   V(ToPrimitive, to_primitive)                \
8241   V(ToStringTag, to_string_tag)               \
8242   V(Unscopables, unscopables)
8243 
8244 #define SYMBOL_GETTER(Name, name)                                   \
8245   Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) {           \
8246     i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8247     return Utils::ToLocal(i_isolate->factory()->name##_symbol());   \
8248   }
8249 
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8250 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8251 
8252 #undef SYMBOL_GETTER
8253 #undef WELL_KNOWN_SYMBOLS
8254 
8255 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8256   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8257   API_RCS_SCOPE(i_isolate, Private, New);
8258   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8259   i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8260   if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8261   Local<Symbol> result = Utils::ToLocal(symbol);
8262   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8263 }
8264 
ForApi(Isolate * isolate,Local<String> name)8265 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8266   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8267   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8268   Local<Symbol> result = Utils::ToLocal(
8269       i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8270   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8271 }
8272 
New(Isolate * isolate,double value)8273 Local<Number> v8::Number::New(Isolate* isolate, double value) {
8274   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8275   if (std::isnan(value)) {
8276     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8277     value = std::numeric_limits<double>::quiet_NaN();
8278   }
8279   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8280   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8281   return Utils::NumberToLocal(result);
8282 }
8283 
New(Isolate * isolate,int32_t value)8284 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8285   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8286   if (i::Smi::IsValid(value)) {
8287     return Utils::IntegerToLocal(
8288         i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8289   }
8290   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8291   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8292   return Utils::IntegerToLocal(result);
8293 }
8294 
NewFromUnsigned(Isolate * isolate,uint32_t value)8295 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8296   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8297   bool fits_into_int32_t = (value & (1 << 31)) == 0;
8298   if (fits_into_int32_t) {
8299     return Integer::New(isolate, static_cast<int32_t>(value));
8300   }
8301   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8302   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8303   return Utils::IntegerToLocal(result);
8304 }
8305 
New(Isolate * isolate,int64_t value)8306 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8307   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8308   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8309   i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8310   return Utils::ToLocal(result);
8311 }
8312 
NewFromUnsigned(Isolate * isolate,uint64_t value)8313 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8314   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8315   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8316   i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8317   return Utils::ToLocal(result);
8318 }
8319 
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8320 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8321                                             int sign_bit, int word_count,
8322                                             const uint64_t* words) {
8323   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8324   ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8325                      MaybeLocal<BigInt>(), InternalEscapableScope);
8326   i::MaybeHandle<i::BigInt> result =
8327       i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8328   has_pending_exception = result.is_null();
8329   RETURN_ON_FAILED_EXECUTION(BigInt);
8330   RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8331 }
8332 
Uint64Value(bool * lossless) const8333 uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8334   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8335   return handle->AsUint64(lossless);
8336 }
8337 
Int64Value(bool * lossless) const8338 int64_t v8::BigInt::Int64Value(bool* lossless) const {
8339   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8340   return handle->AsInt64(lossless);
8341 }
8342 
WordCount() const8343 int BigInt::WordCount() const {
8344   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8345   return handle->Words64Count();
8346 }
8347 
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8348 void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8349                           uint64_t* words) const {
8350   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8351   return handle->ToWordsArray64(sign_bit, word_count, words);
8352 }
8353 
ReportExternalAllocationLimitReached()8354 void Isolate::ReportExternalAllocationLimitReached() {
8355   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8356   if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8357   heap->ReportExternalMemoryPressure();
8358 }
8359 
GetHeapProfiler()8360 HeapProfiler* Isolate::GetHeapProfiler() {
8361   i::HeapProfiler* heap_profiler =
8362       reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8363   return reinterpret_cast<HeapProfiler*>(heap_profiler);
8364 }
8365 
SetIdle(bool is_idle)8366 void Isolate::SetIdle(bool is_idle) {
8367   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8368   isolate->SetIdle(is_idle);
8369 }
8370 
GetArrayBufferAllocator()8371 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8372   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8373   return isolate->array_buffer_allocator();
8374 }
8375 
InContext()8376 bool Isolate::InContext() {
8377   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8378   return !isolate->context().is_null();
8379 }
8380 
ClearKeptObjects()8381 void Isolate::ClearKeptObjects() {
8382   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8383   isolate->ClearKeptObjects();
8384 }
8385 
GetCurrentContext()8386 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8387   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8388   i::Context context = isolate->context();
8389   if (context.is_null()) return Local<Context>();
8390   i::Context native_context = context.native_context();
8391   if (native_context.is_null()) return Local<Context>();
8392   return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8393 }
8394 
GetEnteredOrMicrotaskContext()8395 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8396   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8397   i::Handle<i::Object> last =
8398       isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8399   if (last.is_null()) return Local<Context>();
8400   DCHECK(last->IsNativeContext());
8401   return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8402 }
8403 
GetIncumbentContext()8404 v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8405   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8406   i::Handle<i::Context> context = isolate->GetIncumbentContext();
8407   return Utils::ToLocal(context);
8408 }
8409 
ThrowError(v8::Local<v8::String> message)8410 v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8411   return ThrowException(v8::Exception::Error(message));
8412 }
8413 
ThrowException(v8::Local<v8::Value> value)8414 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8415   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8416   ENTER_V8_DO_NOT_USE(isolate);
8417   // If we're passed an empty handle, we throw an undefined exception
8418   // to deal more gracefully with out of memory situations.
8419   if (value.IsEmpty()) {
8420     isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8421   } else {
8422     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8423   }
8424   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8425 }
8426 
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8427 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8428                                     GCType gc_type) {
8429   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8430   isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8431 }
8432 
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8433 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8434                                        void* data) {
8435   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8436   isolate->heap()->RemoveGCPrologueCallback(callback, data);
8437 }
8438 
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8439 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8440                                     GCType gc_type) {
8441   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8442   isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8443 }
8444 
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8445 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8446                                        void* data) {
8447   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8448   isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8449 }
8450 
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8451 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8452                                       GCCallbackFlags flags, void* data) {
8453   reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8454 }
8455 
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8456 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8457   void* data = reinterpret_cast<void*>(callback);
8458   AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8459 }
8460 
RemoveGCPrologueCallback(GCCallback callback)8461 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8462   void* data = reinterpret_cast<void*>(callback);
8463   RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8464 }
8465 
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8466 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8467   void* data = reinterpret_cast<void*>(callback);
8468   AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8469 }
8470 
RemoveGCEpilogueCallback(GCCallback callback)8471 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8472   void* data = reinterpret_cast<void*>(callback);
8473   RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8474 }
8475 
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8476 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8477   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8478   CHECK_NULL(isolate->heap()->cpp_heap());
8479   isolate->heap()->SetEmbedderHeapTracer(tracer);
8480 }
8481 
GetEmbedderHeapTracer()8482 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8483   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8484   return isolate->heap()->GetEmbedderHeapTracer();
8485 }
8486 
SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8487 void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8488   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8489   isolate->heap()->SetEmbedderRootsHandler(handler);
8490 }
8491 
AttachCppHeap(CppHeap * cpp_heap)8492 void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
8493   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8494   CHECK_NULL(GetEmbedderHeapTracer());
8495   isolate->heap()->AttachCppHeap(cpp_heap);
8496 }
8497 
DetachCppHeap()8498 void Isolate::DetachCppHeap() {
8499   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8500   isolate->heap()->DetachCppHeap();
8501 }
8502 
GetCppHeap() const8503 CppHeap* Isolate::GetCppHeap() const {
8504   const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8505   return isolate->heap()->cpp_heap();
8506 }
8507 
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8508 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8509     GetExternallyAllocatedMemoryInBytesCallback callback) {
8510   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8511   isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8512 }
8513 
TerminateExecution()8514 void Isolate::TerminateExecution() {
8515   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8516   isolate->stack_guard()->RequestTerminateExecution();
8517 }
8518 
IsExecutionTerminating()8519 bool Isolate::IsExecutionTerminating() {
8520   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8521   return IsExecutionTerminatingCheck(isolate);
8522 }
8523 
CancelTerminateExecution()8524 void Isolate::CancelTerminateExecution() {
8525   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8526   isolate->stack_guard()->ClearTerminateExecution();
8527   isolate->CancelTerminateExecution();
8528 }
8529 
RequestInterrupt(InterruptCallback callback,void * data)8530 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8531   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8532   isolate->RequestInterrupt(callback, data);
8533 }
8534 
HasPendingBackgroundTasks()8535 bool Isolate::HasPendingBackgroundTasks() {
8536 #if V8_ENABLE_WEBASSEMBLY
8537   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8538   return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate);
8539 #else
8540   return false;
8541 #endif  // V8_ENABLE_WEBASSEMBLY
8542 }
8543 
RequestGarbageCollectionForTesting(GarbageCollectionType type)8544 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8545   Utils::ApiCheck(i::FLAG_expose_gc,
8546                   "v8::Isolate::RequestGarbageCollectionForTesting",
8547                   "Must use --expose-gc");
8548   if (type == kMinorGarbageCollection) {
8549     reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8550         i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8551         kGCCallbackFlagForced);
8552   } else {
8553     DCHECK_EQ(kFullGarbageCollection, type);
8554     reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8555         i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8556         kGCCallbackFlagForced);
8557   }
8558 }
8559 
RequestGarbageCollectionForTesting(GarbageCollectionType type,EmbedderHeapTracer::EmbedderStackState stack_state)8560 void Isolate::RequestGarbageCollectionForTesting(
8561     GarbageCollectionType type,
8562     EmbedderHeapTracer::EmbedderStackState stack_state) {
8563   base::Optional<i::EmbedderStackStateScope> stack_scope;
8564   if (type == kFullGarbageCollection) {
8565     stack_scope.emplace(reinterpret_cast<i::Isolate*>(this)->heap(),
8566                         i::EmbedderStackStateScope::kExplicitInvocation,
8567                         stack_state);
8568   }
8569   RequestGarbageCollectionForTesting(type);
8570 }
8571 
GetCurrent()8572 Isolate* Isolate::GetCurrent() {
8573   i::Isolate* isolate = i::Isolate::Current();
8574   return reinterpret_cast<Isolate*>(isolate);
8575 }
8576 
TryGetCurrent()8577 Isolate* Isolate::TryGetCurrent() {
8578   i::Isolate* isolate = i::Isolate::TryGetCurrent();
8579   return reinterpret_cast<Isolate*>(isolate);
8580 }
8581 
IsCurrent() const8582 bool Isolate::IsCurrent() const {
8583   return reinterpret_cast<const i::Isolate*>(this)->IsCurrent();
8584 }
8585 
8586 // static
Allocate()8587 Isolate* Isolate::Allocate() {
8588   return reinterpret_cast<Isolate*>(i::Isolate::New());
8589 }
8590 
8591 Isolate::CreateParams::CreateParams() = default;
8592 
8593 Isolate::CreateParams::~CreateParams() = default;
8594 
8595 // static
8596 // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8597 void Isolate::Initialize(Isolate* isolate,
8598                          const v8::Isolate::CreateParams& params) {
8599   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8600   TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.IsolateInitialize");
8601   if (auto allocator = params.array_buffer_allocator_shared) {
8602     CHECK(params.array_buffer_allocator == nullptr ||
8603           params.array_buffer_allocator == allocator.get());
8604     i_isolate->set_array_buffer_allocator(allocator.get());
8605     i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8606   } else {
8607     CHECK_NOT_NULL(params.array_buffer_allocator);
8608     i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8609   }
8610   if (params.snapshot_blob != nullptr) {
8611     i_isolate->set_snapshot_blob(params.snapshot_blob);
8612   } else {
8613     i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8614   }
8615 
8616   if (params.fatal_error_callback) {
8617     isolate->SetFatalErrorHandler(params.fatal_error_callback);
8618   }
8619 
8620   if (params.oom_error_callback) {
8621     isolate->SetOOMErrorHandler(params.oom_error_callback);
8622   }
8623 
8624   if (params.counter_lookup_callback) {
8625     isolate->SetCounterFunction(params.counter_lookup_callback);
8626   }
8627 
8628   if (params.create_histogram_callback) {
8629     isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8630   }
8631 
8632   if (params.add_histogram_sample_callback) {
8633     isolate->SetAddHistogramSampleFunction(
8634         params.add_histogram_sample_callback);
8635   }
8636 
8637   i_isolate->set_api_external_references(params.external_references);
8638   i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8639 
8640   i_isolate->heap()->ConfigureHeap(params.constraints);
8641   if (params.constraints.stack_limit() != nullptr) {
8642     uintptr_t limit =
8643         reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8644     i_isolate->stack_guard()->SetStackLimit(limit);
8645   }
8646 
8647   if (params.experimental_attach_to_shared_isolate != nullptr) {
8648     i_isolate->set_shared_isolate(reinterpret_cast<i::Isolate*>(
8649         params.experimental_attach_to_shared_isolate));
8650   }
8651 
8652   // TODO(v8:2487): Once we got rid of Isolate::Current(), we can remove this.
8653   Isolate::Scope isolate_scope(isolate);
8654   if (i_isolate->snapshot_blob() == nullptr) {
8655     FATAL(
8656         "V8 snapshot blob was not set during initialization. This can mean "
8657         "that the snapshot blob file is corrupted or missing.");
8658   }
8659   if (!i::Snapshot::Initialize(i_isolate)) {
8660     // If snapshot data was provided and we failed to deserialize it must
8661     // have been corrupted.
8662     FATAL(
8663         "Failed to deserialize the V8 snapshot blob. This can mean that the "
8664         "snapshot blob file is corrupted or missing.");
8665   }
8666 
8667   {
8668     // Set up code event handlers. Needs to be after i::Snapshot::Initialize
8669     // because that is where we add the isolate to WasmEngine.
8670     auto code_event_handler = params.code_event_handler;
8671     if (code_event_handler) {
8672       isolate->SetJitCodeEventHandler(kJitCodeEventEnumExisting,
8673                                       code_event_handler);
8674     }
8675   }
8676 
8677   i_isolate->set_only_terminate_in_safe_scope(
8678       params.only_terminate_in_safe_scope);
8679   i_isolate->set_embedder_wrapper_type_index(
8680       params.embedder_wrapper_type_index);
8681   i_isolate->set_embedder_wrapper_object_index(
8682       params.embedder_wrapper_object_index);
8683 
8684   if (!i::V8::GetCurrentPlatform()
8685            ->GetForegroundTaskRunner(isolate)
8686            ->NonNestableTasksEnabled()) {
8687     FATAL(
8688         "The current platform's foreground task runner does not have "
8689         "non-nestable tasks enabled. The embedder must provide one.");
8690   }
8691 }
8692 
New(const Isolate::CreateParams & params)8693 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8694   Isolate* isolate = Allocate();
8695   Initialize(isolate, params);
8696   return isolate;
8697 }
8698 
Dispose()8699 void Isolate::Dispose() {
8700   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8701   if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8702                        "Disposing the isolate that is entered by a thread.")) {
8703     return;
8704   }
8705   i::Isolate::Delete(isolate);
8706 }
8707 
DumpAndResetStats()8708 void Isolate::DumpAndResetStats() {
8709   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8710   isolate->DumpAndResetStats();
8711 }
8712 
DiscardThreadSpecificMetadata()8713 void Isolate::DiscardThreadSpecificMetadata() {
8714   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8715   isolate->DiscardPerThreadDataForThisThread();
8716 }
8717 
Enter()8718 void Isolate::Enter() {
8719   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8720   isolate->Enter();
8721 }
8722 
Exit()8723 void Isolate::Exit() {
8724   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8725   isolate->Exit();
8726 }
8727 
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8728 void Isolate::SetAbortOnUncaughtExceptionCallback(
8729     AbortOnUncaughtExceptionCallback callback) {
8730   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8731   isolate->SetAbortOnUncaughtExceptionCallback(callback);
8732 }
8733 
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8734 void Isolate::SetHostImportModuleDynamicallyCallback(
8735     HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8736   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8737   isolate->SetHostImportModuleDynamicallyCallback(callback);
8738 }
8739 
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8740 void Isolate::SetHostImportModuleDynamicallyCallback(
8741     HostImportModuleDynamicallyCallback callback) {
8742   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8743   isolate->SetHostImportModuleDynamicallyCallback(callback);
8744 }
8745 
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8746 void Isolate::SetHostInitializeImportMetaObjectCallback(
8747     HostInitializeImportMetaObjectCallback callback) {
8748   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8749   isolate->SetHostInitializeImportMetaObjectCallback(callback);
8750 }
8751 
SetHostCreateShadowRealmContextCallback(HostCreateShadowRealmContextCallback callback)8752 void Isolate::SetHostCreateShadowRealmContextCallback(
8753     HostCreateShadowRealmContextCallback callback) {
8754   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8755   isolate->SetHostCreateShadowRealmContextCallback(callback);
8756 }
8757 
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8758 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8759   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8760   isolate->SetPrepareStackTraceCallback(callback);
8761 }
8762 
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8763 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8764     Isolate* isolate,
8765     Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8766     : on_failure_(on_failure), isolate_(isolate) {
8767   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8768   switch (on_failure_) {
8769     case CRASH_ON_FAILURE:
8770       i::DisallowJavascriptExecution::Open(i_isolate,
8771                                            &was_execution_allowed_assert_);
8772       break;
8773     case THROW_ON_FAILURE:
8774       i::ThrowOnJavascriptExecution::Open(i_isolate,
8775                                           &was_execution_allowed_throws_);
8776       break;
8777     case DUMP_ON_FAILURE:
8778       i::DumpOnJavascriptExecution::Open(i_isolate,
8779                                          &was_execution_allowed_dump_);
8780       break;
8781     default:
8782       UNREACHABLE();
8783   }
8784 }
8785 
~DisallowJavascriptExecutionScope()8786 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8787   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8788   switch (on_failure_) {
8789     case CRASH_ON_FAILURE:
8790       i::DisallowJavascriptExecution::Close(i_isolate,
8791                                             was_execution_allowed_assert_);
8792       break;
8793     case THROW_ON_FAILURE:
8794       i::ThrowOnJavascriptExecution::Close(i_isolate,
8795                                            was_execution_allowed_throws_);
8796       break;
8797     case DUMP_ON_FAILURE:
8798       i::DumpOnJavascriptExecution::Close(i_isolate,
8799                                           was_execution_allowed_dump_);
8800       break;
8801     default:
8802       UNREACHABLE();
8803   }
8804 }
8805 
AllowJavascriptExecutionScope(Isolate * isolate)8806 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8807     Isolate* isolate)
8808     : isolate_(isolate) {
8809   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8810   i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_);
8811   i::NoThrowOnJavascriptExecution::Open(i_isolate,
8812                                         &was_execution_allowed_throws_);
8813   i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_);
8814 }
8815 
~AllowJavascriptExecutionScope()8816 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8817   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8818   i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_);
8819   i::NoThrowOnJavascriptExecution::Close(i_isolate,
8820                                          was_execution_allowed_throws_);
8821   i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_);
8822 }
8823 
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8824 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8825     Isolate* isolate, MicrotaskQueue* microtask_queue)
8826     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8827       microtask_queue_(microtask_queue
8828                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8829                            : isolate_->default_microtask_queue()) {
8830   isolate_->thread_local_top()->IncrementCallDepth(this);
8831   microtask_queue_->IncrementMicrotasksSuppressions();
8832 }
8833 
~SuppressMicrotaskExecutionScope()8834 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8835   microtask_queue_->DecrementMicrotasksSuppressions();
8836   isolate_->thread_local_top()->DecrementCallDepth(this);
8837 }
8838 
SafeForTerminationScope(v8::Isolate * isolate)8839 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8840     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8841       prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8842   isolate_->set_next_v8_call_is_safe_for_termination(true);
8843 }
8844 
~SafeForTerminationScope()8845 Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8846   isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8847 }
8848 
GetDataFromSnapshotOnce(size_t index)8849 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8850   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8851   i::FixedArray list = i_isolate->heap()->serialized_objects();
8852   return GetSerializedDataFromFixedArray(i_isolate, list, index);
8853 }
8854 
GetHeapStatistics(HeapStatistics * heap_statistics)8855 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8856   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8857   i::Heap* heap = isolate->heap();
8858 
8859   // The order of acquiring memory statistics is important here. We query in
8860   // this order because of concurrent allocation: 1) used memory 2) comitted
8861   // physical memory 3) committed memory. Therefore the condition used <=
8862   // committed physical <= committed should hold.
8863   heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8864   heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8865   DCHECK_LE(heap_statistics->used_global_handles_size_,
8866             heap_statistics->total_global_handles_size_);
8867 
8868   heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8869   heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8870   heap_statistics->total_heap_size_ = heap->CommittedMemory();
8871 
8872   heap_statistics->total_available_size_ = heap->Available();
8873 
8874   if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8875     i::ReadOnlySpace* ro_space = heap->read_only_space();
8876     heap_statistics->used_heap_size_ += ro_space->Size();
8877     heap_statistics->total_physical_size_ +=
8878         ro_space->CommittedPhysicalMemory();
8879     heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8880   }
8881 
8882   // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8883   // this and add DCHECK.
8884   DCHECK_LE(heap_statistics->used_heap_size_,
8885             heap_statistics->total_heap_size_);
8886 
8887   heap_statistics->total_heap_size_executable_ =
8888       heap->CommittedMemoryExecutable();
8889   heap_statistics->heap_size_limit_ = heap->MaxReserved();
8890   // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8891   // API becomes available we should report the malloced memory separately. For
8892   // now we just add the values, thereby over-approximating the peak slightly.
8893   heap_statistics->malloced_memory_ =
8894       isolate->allocator()->GetCurrentMemoryUsage() +
8895       isolate->string_table()->GetCurrentMemoryUsage();
8896   // On 32-bit systems backing_store_bytes() might overflow size_t temporarily
8897   // due to concurrent array buffer sweeping.
8898   heap_statistics->external_memory_ =
8899       isolate->heap()->backing_store_bytes() < SIZE_MAX
8900           ? static_cast<size_t>(isolate->heap()->backing_store_bytes())
8901           : SIZE_MAX;
8902   heap_statistics->peak_malloced_memory_ =
8903       isolate->allocator()->GetMaxMemoryUsage();
8904   heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8905   heap_statistics->number_of_detached_contexts_ =
8906       heap->NumberOfDetachedContexts();
8907   heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8908 
8909 #if V8_ENABLE_WEBASSEMBLY
8910   heap_statistics->malloced_memory_ +=
8911       i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage();
8912   heap_statistics->peak_malloced_memory_ +=
8913       i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage();
8914 #endif  // V8_ENABLE_WEBASSEMBLY
8915 }
8916 
NumberOfHeapSpaces()8917 size_t Isolate::NumberOfHeapSpaces() {
8918   return i::LAST_SPACE - i::FIRST_SPACE + 1;
8919 }
8920 
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8921 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8922                                      size_t index) {
8923   if (!space_statistics) return false;
8924   if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8925     return false;
8926 
8927   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8928   i::Heap* heap = isolate->heap();
8929 
8930   i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
8931   space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
8932 
8933   if (allocation_space == i::RO_SPACE) {
8934     if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8935       // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
8936       space_statistics->space_size_ = 0;
8937       space_statistics->space_used_size_ = 0;
8938       space_statistics->space_available_size_ = 0;
8939       space_statistics->physical_space_size_ = 0;
8940     } else {
8941       i::ReadOnlySpace* space = heap->read_only_space();
8942       space_statistics->space_size_ = space->CommittedMemory();
8943       space_statistics->space_used_size_ = space->Size();
8944       space_statistics->space_available_size_ = 0;
8945       space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8946     }
8947   } else {
8948     i::Space* space = heap->space(static_cast<int>(index));
8949     space_statistics->space_size_ = space ? space->CommittedMemory() : 0;
8950     space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0;
8951     space_statistics->space_available_size_ = space ? space->Available() : 0;
8952     space_statistics->physical_space_size_ =
8953         space ? space->CommittedPhysicalMemory() : 0;
8954   }
8955   return true;
8956 }
8957 
NumberOfTrackedHeapObjectTypes()8958 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8959   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8960   i::Heap* heap = isolate->heap();
8961   return heap->NumberOfTrackedHeapObjectTypes();
8962 }
8963 
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8964 bool Isolate::GetHeapObjectStatisticsAtLastGC(
8965     HeapObjectStatistics* object_statistics, size_t type_index) {
8966   if (!object_statistics) return false;
8967   if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
8968 
8969   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8970   i::Heap* heap = isolate->heap();
8971   if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8972 
8973   const char* object_type;
8974   const char* object_sub_type;
8975   size_t object_count = heap->ObjectCountAtLastGC(type_index);
8976   size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8977   if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8978     // There should be no objects counted when the type is unknown.
8979     DCHECK_EQ(object_count, 0U);
8980     DCHECK_EQ(object_size, 0U);
8981     return false;
8982   }
8983 
8984   object_statistics->object_type_ = object_type;
8985   object_statistics->object_sub_type_ = object_sub_type;
8986   object_statistics->object_count_ = object_count;
8987   object_statistics->object_size_ = object_size;
8988   return true;
8989 }
8990 
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)8991 bool Isolate::GetHeapCodeAndMetadataStatistics(
8992     HeapCodeStatistics* code_statistics) {
8993   if (!code_statistics) return false;
8994 
8995   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8996   isolate->heap()->CollectCodeStatistics();
8997 
8998   code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8999   code_statistics->bytecode_and_metadata_size_ =
9000       isolate->bytecode_and_metadata_size();
9001   code_statistics->external_script_source_size_ =
9002       isolate->external_script_source_size();
9003   code_statistics->cpu_profiler_metadata_size_ =
9004       i::CpuProfiler::GetAllProfilersMemorySize(
9005           reinterpret_cast<i::Isolate*>(isolate));
9006 
9007   return true;
9008 }
9009 
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)9010 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
9011                             MeasureMemoryExecution execution) {
9012   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9013   return isolate->heap()->MeasureMemory(std::move(delegate), execution);
9014 }
9015 
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)9016 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
9017     Isolate* isolate, Local<Context> context,
9018     Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
9019   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9020   i::Handle<i::NativeContext> native_context =
9021       handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
9022   i::Handle<i::JSPromise> js_promise =
9023       i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
9024   return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
9025                                                   mode);
9026 }
9027 
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)9028 void Isolate::GetStackSample(const RegisterState& state, void** frames,
9029                              size_t frames_limit, SampleInfo* sample_info) {
9030   RegisterState regs = state;
9031   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9032   if (i::TickSample::GetStackSample(isolate, &regs,
9033                                     i::TickSample::kSkipCEntryFrame, frames,
9034                                     frames_limit, sample_info)) {
9035     return;
9036   }
9037   sample_info->frames_count = 0;
9038   sample_info->vm_state = OTHER;
9039   sample_info->external_callback_entry = nullptr;
9040 }
9041 
NumberOfPhantomHandleResetsSinceLastCall()9042 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
9043   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9044   return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
9045 }
9046 
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)9047 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
9048     int64_t change_in_bytes) {
9049   // Try to check for unreasonably large or small values from the embedder.
9050   const int64_t kMaxReasonableBytes = int64_t(1) << 60;
9051   const int64_t kMinReasonableBytes = -kMaxReasonableBytes;
9052   STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength);
9053 
9054   CHECK(kMinReasonableBytes <= change_in_bytes &&
9055         change_in_bytes < kMaxReasonableBytes);
9056 
9057   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9058   int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
9059 
9060   if (change_in_bytes <= 0) return amount;
9061 
9062   if (amount > i_isolate->heap()->external_memory_limit()) {
9063     ReportExternalAllocationLimitReached();
9064   }
9065   return amount;
9066 }
9067 
SetEventLogger(LogEventCallback that)9068 void Isolate::SetEventLogger(LogEventCallback that) {
9069   // Do not overwrite the event logger if we want to log explicitly.
9070   if (i::FLAG_log_internal_timer_events) return;
9071   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9072   isolate->set_event_logger(that);
9073 }
9074 
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9075 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
9076   if (callback == nullptr) return;
9077   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9078   isolate->AddBeforeCallEnteredCallback(callback);
9079 }
9080 
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9081 void Isolate::RemoveBeforeCallEnteredCallback(
9082     BeforeCallEnteredCallback callback) {
9083   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9084   isolate->RemoveBeforeCallEnteredCallback(callback);
9085 }
9086 
AddCallCompletedCallback(CallCompletedCallback callback)9087 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
9088   if (callback == nullptr) return;
9089   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9090   isolate->AddCallCompletedCallback(callback);
9091 }
9092 
RemoveCallCompletedCallback(CallCompletedCallback callback)9093 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
9094   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9095   isolate->RemoveCallCompletedCallback(callback);
9096 }
9097 
Wake()9098 void Isolate::AtomicsWaitWakeHandle::Wake() {
9099   reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
9100 }
9101 
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)9102 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
9103   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9104   isolate->SetAtomicsWaitCallback(callback, data);
9105 }
9106 
SetPromiseHook(PromiseHook hook)9107 void Isolate::SetPromiseHook(PromiseHook hook) {
9108   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9109   isolate->SetPromiseHook(hook);
9110 }
9111 
SetPromiseRejectCallback(PromiseRejectCallback callback)9112 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
9113   if (callback == nullptr) return;
9114   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9115   isolate->SetPromiseRejectCallback(callback);
9116 }
9117 
PerformMicrotaskCheckpoint()9118 void Isolate::PerformMicrotaskCheckpoint() {
9119   DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
9120   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9121   isolate->default_microtask_queue()->PerformCheckpoint(this);
9122 }
9123 
EnqueueMicrotask(Local<Function> v8_function)9124 void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
9125   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9126   i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
9127   i::Handle<i::NativeContext> handler_context;
9128   if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
9129           &handler_context))
9130     handler_context = isolate->native_context();
9131   MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
9132   if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
9133 }
9134 
EnqueueMicrotask(MicrotaskCallback callback,void * data)9135 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
9136   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9137   isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
9138 }
9139 
SetMicrotasksPolicy(MicrotasksPolicy policy)9140 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9141   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9142   isolate->default_microtask_queue()->set_microtasks_policy(policy);
9143 }
9144 
GetMicrotasksPolicy() const9145 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
9146   i::Isolate* isolate =
9147       reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
9148   return isolate->default_microtask_queue()->microtasks_policy();
9149 }
9150 
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9151 void Isolate::AddMicrotasksCompletedCallback(
9152     MicrotasksCompletedCallbackWithData callback, void* data) {
9153   DCHECK(callback);
9154   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9155   isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
9156                                                                      data);
9157 }
9158 
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9159 void Isolate::RemoveMicrotasksCompletedCallback(
9160     MicrotasksCompletedCallbackWithData callback, void* data) {
9161   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9162   isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
9163       callback, data);
9164 }
9165 
SetUseCounterCallback(UseCounterCallback callback)9166 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9167   reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9168 }
9169 
SetCounterFunction(CounterLookupCallback callback)9170 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9171   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9172   isolate->counters()->ResetCounterFunction(callback);
9173 }
9174 
SetCreateHistogramFunction(CreateHistogramCallback callback)9175 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9176   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9177   isolate->counters()->ResetCreateHistogramFunction(callback);
9178 }
9179 
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)9180 void Isolate::SetAddHistogramSampleFunction(
9181     AddHistogramSampleCallback callback) {
9182   reinterpret_cast<i::Isolate*>(this)
9183       ->counters()
9184       ->SetAddHistogramSampleFunction(callback);
9185 }
9186 
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)9187 void Isolate::SetMetricsRecorder(
9188     const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
9189   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9190   isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder);
9191 }
9192 
SetAddCrashKeyCallback(AddCrashKeyCallback callback)9193 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
9194   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9195   isolate->SetAddCrashKeyCallback(callback);
9196 }
9197 
IdleNotificationDeadline(double deadline_in_seconds)9198 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
9199   // Returning true tells the caller that it need not
9200   // continue to call IdleNotification.
9201   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9202   if (!i::FLAG_use_idle_notification) return true;
9203   return isolate->heap()->IdleNotification(deadline_in_seconds);
9204 }
9205 
LowMemoryNotification()9206 void Isolate::LowMemoryNotification() {
9207   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9208   {
9209     i::NestedTimedHistogramScope idle_notification_scope(
9210         isolate->counters()->gc_low_memory_notification());
9211     TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9212     isolate->heap()->CollectAllAvailableGarbage(
9213         i::GarbageCollectionReason::kLowMemoryNotification);
9214   }
9215 }
9216 
ContextDisposedNotification(bool dependant_context)9217 int Isolate::ContextDisposedNotification(bool dependant_context) {
9218   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9219 #if V8_ENABLE_WEBASSEMBLY
9220   if (!dependant_context) {
9221     if (!isolate->context().is_null()) {
9222       // We left the current context, we can abort all WebAssembly compilations
9223       // of that context.
9224       // A handle scope for the native context.
9225       i::HandleScope handle_scope(isolate);
9226       i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext(
9227           isolate->native_context());
9228     }
9229   }
9230 #endif  // V8_ENABLE_WEBASSEMBLY
9231   // TODO(ahaas): move other non-heap activity out of the heap call.
9232   return isolate->heap()->NotifyContextDisposed(dependant_context);
9233 }
9234 
IsolateInForegroundNotification()9235 void Isolate::IsolateInForegroundNotification() {
9236   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9237   return isolate->IsolateInForegroundNotification();
9238 }
9239 
IsolateInBackgroundNotification()9240 void Isolate::IsolateInBackgroundNotification() {
9241   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9242   return isolate->IsolateInBackgroundNotification();
9243 }
9244 
MemoryPressureNotification(MemoryPressureLevel level)9245 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9246   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9247   bool on_isolate_thread =
9248       isolate->was_locker_ever_used()
9249           ? isolate->thread_manager()->IsLockedByCurrentThread()
9250           : i::ThreadId::Current() == isolate->thread_id();
9251   isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9252 }
9253 
ClearCachesForTesting()9254 void Isolate::ClearCachesForTesting() {
9255   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9256   isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9257   isolate->ClearSerializerData();
9258 }
9259 
EnableMemorySavingsMode()9260 void Isolate::EnableMemorySavingsMode() {
9261   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9262   isolate->EnableMemorySavingsMode();
9263 }
9264 
DisableMemorySavingsMode()9265 void Isolate::DisableMemorySavingsMode() {
9266   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9267   isolate->DisableMemorySavingsMode();
9268 }
9269 
SetRAILMode(RAILMode rail_mode)9270 void Isolate::SetRAILMode(RAILMode rail_mode) {
9271   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9272   return isolate->SetRAILMode(rail_mode);
9273 }
9274 
UpdateLoadStartTime()9275 void Isolate::UpdateLoadStartTime() {
9276   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9277   isolate->UpdateLoadStartTime();
9278 }
9279 
IncreaseHeapLimitForDebugging()9280 void Isolate::IncreaseHeapLimitForDebugging() {
9281   // No-op.
9282 }
9283 
RestoreOriginalHeapLimit()9284 void Isolate::RestoreOriginalHeapLimit() {
9285   // No-op.
9286 }
9287 
IsHeapLimitIncreasedForDebugging()9288 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9289 
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9290 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9291                                      JitCodeEventHandler event_handler) {
9292   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9293   // Ensure that logging is initialized for our isolate.
9294   isolate->InitializeLoggingAndCounters();
9295   isolate->logger()->SetCodeEventHandler(options, event_handler);
9296 }
9297 
SetStackLimit(uintptr_t stack_limit)9298 void Isolate::SetStackLimit(uintptr_t stack_limit) {
9299   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9300   CHECK(stack_limit);
9301   isolate->stack_guard()->SetStackLimit(stack_limit);
9302 }
9303 
GetCodeRange(void ** start,size_t * length_in_bytes)9304 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9305   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9306   const base::AddressRegion& code_region = isolate->heap()->code_region();
9307   *start = reinterpret_cast<void*>(code_region.begin());
9308   *length_in_bytes = code_region.size();
9309 }
9310 
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9311 void Isolate::GetEmbeddedCodeRange(const void** start,
9312                                    size_t* length_in_bytes) {
9313   // Note, we should return the embedded code rande from the .text section here.
9314   i::EmbeddedData d = i::EmbeddedData::FromBlob();
9315   *start = reinterpret_cast<const void*>(d.code());
9316   *length_in_bytes = d.code_size();
9317 }
9318 
GetJSEntryStubs()9319 JSEntryStubs Isolate::GetJSEntryStubs() {
9320   JSEntryStubs entry_stubs;
9321 
9322   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9323   std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = {
9324       {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub},
9325        {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9326        {i::Builtin::kJSRunMicrotasksEntry,
9327         &entry_stubs.js_run_microtasks_entry_stub}}};
9328   for (auto& pair : stubs) {
9329     i::Code js_entry = FromCodeT(isolate->builtins()->code(pair.first));
9330     pair.second->code.start =
9331         reinterpret_cast<const void*>(js_entry.InstructionStart());
9332     pair.second->code.length_in_bytes = js_entry.InstructionSize();
9333   }
9334 
9335   return entry_stubs;
9336 }
9337 
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9338 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9339 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9340   // Not implemented on other platforms.
9341   UNREACHABLE();
9342 #else
9343 
9344   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9345   std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9346 
9347   DCHECK_NOT_NULL(code_pages);
9348 
9349   // Copy as many elements into the output vector as we can. If the
9350   // caller-provided buffer is not big enough, we fill it, and the caller can
9351   // provide a bigger one next time. We do it this way because allocation is not
9352   // allowed in signal handlers.
9353   size_t limit = std::min(capacity, code_pages->size());
9354   for (size_t i = 0; i < limit; i++) {
9355     code_pages_out[i] = code_pages->at(i);
9356   }
9357   return code_pages->size();
9358 #endif
9359 }
9360 
9361 #define CALLBACK_SETTER(ExternalName, Type, InternalName)      \
9362   void Isolate::Set##ExternalName(Type callback) {             \
9363     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9364     isolate->set_##InternalName(callback);                     \
9365   }
9366 
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9367 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9368 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9369 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9370                 ModifyCodeGenerationFromStringsCallback2,
9371                 modify_code_gen_callback2)
9372 CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9373                 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9374 
9375 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9376 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9377 
9378 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9379                 wasm_streaming_callback)
9380 
9381 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9382                 wasm_load_source_map_callback)
9383 
9384 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9385                 wasm_simd_enabled_callback)
9386 
9387 CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9388                 wasm_exceptions_enabled_callback)
9389 
9390 CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9391                 WasmDynamicTieringEnabledCallback,
9392                 wasm_dynamic_tiering_enabled_callback)
9393 
9394 CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9395                 SharedArrayBufferConstructorEnabledCallback,
9396                 sharedarraybuffer_constructor_enabled_callback)
9397 
9398 void Isolate::InstallConditionalFeatures(Local<Context> context) {
9399   v8::HandleScope handle_scope(this);
9400   v8::Context::Scope context_scope(context);
9401   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9402   isolate->InstallConditionalFeatures(Utils::OpenHandle(*context));
9403 #if V8_ENABLE_WEBASSEMBLY
9404   if (i::FLAG_expose_wasm) {
9405     i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context));
9406   }
9407 #endif  // V8_ENABLE_WEBASSEMBLY
9408 }
9409 
AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9410 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9411                                        void* data) {
9412   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9413   isolate->heap()->AddNearHeapLimitCallback(callback, data);
9414 }
9415 
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9416 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9417                                           size_t heap_limit) {
9418   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9419   isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9420 }
9421 
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9422 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9423   DCHECK_GT(threshold_percent, 0.0);
9424   DCHECK_LT(threshold_percent, 1.0);
9425   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9426   isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9427 }
9428 
IsDead()9429 bool Isolate::IsDead() {
9430   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9431   return isolate->IsDead();
9432 }
9433 
AddMessageListener(MessageCallback that,Local<Value> data)9434 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9435   return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9436 }
9437 
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9438 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9439                                                int message_levels,
9440                                                Local<Value> data) {
9441   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9442   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9443   i::HandleScope scope(isolate);
9444   i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9445   i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9446   i::Handle<i::Foreign> foreign =
9447       isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9448   listener->set(0, *foreign);
9449   listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9450                                   : *Utils::OpenHandle(*data));
9451   listener->set(2, i::Smi::FromInt(message_levels));
9452   list = i::TemplateList::Add(isolate, list, listener);
9453   isolate->heap()->SetMessageListeners(*list);
9454   return true;
9455 }
9456 
RemoveMessageListeners(MessageCallback that)9457 void Isolate::RemoveMessageListeners(MessageCallback that) {
9458   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9459   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9460   i::HandleScope scope(isolate);
9461   i::DisallowGarbageCollection no_gc;
9462   i::TemplateList listeners = isolate->heap()->message_listeners();
9463   for (int i = 0; i < listeners.length(); i++) {
9464     if (listeners.get(i).IsUndefined(isolate)) continue;  // skip deleted ones
9465     i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9466     i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9467     if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9468       listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9469     }
9470   }
9471 }
9472 
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9473 void Isolate::SetFailedAccessCheckCallbackFunction(
9474     FailedAccessCheckCallback callback) {
9475   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9476   isolate->SetFailedAccessCheckCallback(callback);
9477 }
9478 
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9479 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9480     bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9481   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9482   isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9483                                                      options);
9484 }
9485 
VisitExternalResources(ExternalResourceVisitor * visitor)9486 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9487   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9488   isolate->heap()->VisitExternalResources(visitor);
9489 }
9490 
IsInUse()9491 bool Isolate::IsInUse() {
9492   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9493   return isolate->IsInUse();
9494 }
9495 
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9496 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9497   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9498   i::DisallowGarbageCollection no_gc;
9499   isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9500 }
9501 
VisitWeakHandles(PersistentHandleVisitor * visitor)9502 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9503   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9504   i::DisallowGarbageCollection no_gc;
9505   isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9506 }
9507 
SetAllowAtomicsWait(bool allow)9508 void Isolate::SetAllowAtomicsWait(bool allow) {
9509   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9510   isolate->set_allow_atomics_wait(allow);
9511 }
9512 
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9513 void v8::Isolate::DateTimeConfigurationChangeNotification(
9514     TimeZoneDetection time_zone_detection) {
9515   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9516   API_RCS_SCOPE(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9517   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9518   i_isolate->date_cache()->ResetDateCache(
9519       static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9520 #ifdef V8_INTL_SUPPORT
9521   i_isolate->clear_cached_icu_object(
9522       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9523   i_isolate->clear_cached_icu_object(
9524       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9525   i_isolate->clear_cached_icu_object(
9526       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9527 #endif  // V8_INTL_SUPPORT
9528 }
9529 
LocaleConfigurationChangeNotification()9530 void v8::Isolate::LocaleConfigurationChangeNotification() {
9531   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9532   API_RCS_SCOPE(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9533   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9534 
9535 #ifdef V8_INTL_SUPPORT
9536   i_isolate->ResetDefaultLocale();
9537 #endif  // V8_INTL_SUPPORT
9538 }
9539 
IsCodeLike(v8::Isolate * isolate) const9540 bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
9541   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9542   API_RCS_SCOPE(i_isolate, Object, IsCodeLike);
9543   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9544   i::HandleScope scope(i_isolate);
9545   return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9546 }
9547 
9548 // static
New(Isolate * isolate,MicrotasksPolicy policy)9549 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9550                                                     MicrotasksPolicy policy) {
9551   auto microtask_queue =
9552       i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9553   microtask_queue->set_microtasks_policy(policy);
9554   std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9555   return ret;
9556 }
9557 
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9558 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9559     : MicrotasksScope(isolate, nullptr, type) {}
9560 
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9561 MicrotasksScope::MicrotasksScope(Isolate* isolate,
9562                                  MicrotaskQueue* microtask_queue,
9563                                  MicrotasksScope::Type type)
9564     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9565       microtask_queue_(microtask_queue
9566                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9567                            : isolate_->default_microtask_queue()),
9568       run_(type == MicrotasksScope::kRunMicrotasks) {
9569   if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9570 #ifdef DEBUG
9571   if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9572 #endif
9573 }
9574 
~MicrotasksScope()9575 MicrotasksScope::~MicrotasksScope() {
9576   if (run_) {
9577     microtask_queue_->DecrementMicrotasksScopeDepth();
9578     if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9579         !isolate_->has_scheduled_exception()) {
9580       DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9581                      isolate_->scheduled_exception() ==
9582                          i::ReadOnlyRoots(isolate_).termination_exception());
9583       microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9584     }
9585   }
9586 #ifdef DEBUG
9587   if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9588 #endif
9589 }
9590 
9591 // static
PerformCheckpoint(Isolate * v8_isolate)9592 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9593   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9594   auto* microtask_queue = isolate->default_microtask_queue();
9595   microtask_queue->PerformCheckpoint(v8_isolate);
9596 }
9597 
9598 // static
GetCurrentDepth(Isolate * v8_isolate)9599 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9600   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9601   auto* microtask_queue = isolate->default_microtask_queue();
9602   return microtask_queue->GetMicrotasksScopeDepth();
9603 }
9604 
9605 // static
IsRunningMicrotasks(Isolate * v8_isolate)9606 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9607   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9608   auto* microtask_queue = isolate->default_microtask_queue();
9609   return microtask_queue->IsRunningMicrotasks();
9610 }
9611 
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9612 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9613     : str_(nullptr), length_(0) {
9614   if (obj.IsEmpty()) return;
9615   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9616   ENTER_V8_DO_NOT_USE(i_isolate);
9617   i::HandleScope scope(i_isolate);
9618   Local<Context> context = isolate->GetCurrentContext();
9619   TryCatch try_catch(isolate);
9620   Local<String> str;
9621   if (!obj->ToString(context).ToLocal(&str)) return;
9622   length_ = str->Utf8Length(isolate);
9623   str_ = i::NewArray<char>(length_ + 1);
9624   str->WriteUtf8(isolate, str_);
9625 }
9626 
~Utf8Value()9627 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9628 
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9629 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9630     : str_(nullptr), length_(0) {
9631   if (obj.IsEmpty()) return;
9632   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9633   ENTER_V8_DO_NOT_USE(i_isolate);
9634   i::HandleScope scope(i_isolate);
9635   Local<Context> context = isolate->GetCurrentContext();
9636   TryCatch try_catch(isolate);
9637   Local<String> str;
9638   if (!obj->ToString(context).ToLocal(&str)) return;
9639   length_ = str->Length();
9640   str_ = i::NewArray<uint16_t>(length_ + 1);
9641   str->Write(isolate, str_);
9642 }
9643 
~Value()9644 String::Value::~Value() { i::DeleteArray(str_); }
9645 
9646 #define DEFINE_ERROR(NAME, name)                                         \
9647   Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) {      \
9648     i::Isolate* isolate = i::Isolate::Current();                         \
9649     API_RCS_SCOPE(isolate, NAME, New);                                   \
9650     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                            \
9651     i::Object error;                                                     \
9652     {                                                                    \
9653       i::HandleScope scope(isolate);                                     \
9654       i::Handle<i::String> message = Utils::OpenHandle(*raw_message);    \
9655       i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9656       error = *isolate->factory()->NewError(constructor, message);       \
9657     }                                                                    \
9658     i::Handle<i::Object> result(error, isolate);                         \
9659     return Utils::ToLocal(result);                                       \
9660   }
9661 
DEFINE_ERROR(RangeError,range_error)9662 DEFINE_ERROR(RangeError, range_error)
9663 DEFINE_ERROR(ReferenceError, reference_error)
9664 DEFINE_ERROR(SyntaxError, syntax_error)
9665 DEFINE_ERROR(TypeError, type_error)
9666 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9667 DEFINE_ERROR(WasmLinkError, wasm_link_error)
9668 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9669 DEFINE_ERROR(Error, error)
9670 
9671 #undef DEFINE_ERROR
9672 
9673 Local<Message> Exception::CreateMessage(Isolate* isolate,
9674                                         Local<Value> exception) {
9675   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9676   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9677   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9678   i::HandleScope scope(i_isolate);
9679   return Utils::MessageToLocal(
9680       scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9681 }
9682 
GetStackTrace(Local<Value> exception)9683 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9684   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9685   if (!obj->IsJSObject()) return Local<StackTrace>();
9686   i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9687   i::Isolate* isolate = js_obj->GetIsolate();
9688   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9689   return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9690 }
9691 
PreviewEntries(bool * is_key_value)9692 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
9693   if (IsMap()) {
9694     *is_key_value = true;
9695     return Map::Cast(this)->AsArray();
9696   }
9697   if (IsSet()) {
9698     *is_key_value = false;
9699     return Set::Cast(this)->AsArray();
9700   }
9701 
9702   i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
9703   i::Isolate* isolate = object->GetIsolate();
9704   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
9705   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9706   if (object->IsJSWeakCollection()) {
9707     *is_key_value = object->IsJSWeakMap();
9708     return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9709         i::Handle<i::JSWeakCollection>::cast(object), 0));
9710   }
9711   if (object->IsJSMapIterator()) {
9712     i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
9713     MapAsArrayKind const kind =
9714         static_cast<MapAsArrayKind>(it->map().instance_type());
9715     *is_key_value = kind == MapAsArrayKind::kEntries;
9716     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9717     return Utils::ToLocal(
9718         MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9719   }
9720   if (object->IsJSSetIterator()) {
9721     i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9722     SetAsArrayKind const kind =
9723         static_cast<SetAsArrayKind>(it->map().instance_type());
9724     *is_key_value = kind == SetAsArrayKind::kEntries;
9725     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9726     return Utils::ToLocal(
9727         SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9728   }
9729   return v8::MaybeLocal<v8::Array>();
9730 }
9731 
GetFunctionName() const9732 Local<String> CpuProfileNode::GetFunctionName() const {
9733   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9734   i::Isolate* isolate = node->isolate();
9735   const i::CodeEntry* entry = node->entry();
9736   i::Handle<i::String> name =
9737       isolate->factory()->InternalizeUtf8String(entry->name());
9738   return ToApiHandle<String>(name);
9739 }
9740 
GetFunctionNameStr() const9741 const char* CpuProfileNode::GetFunctionNameStr() const {
9742   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9743   return node->entry()->name();
9744 }
9745 
GetScriptId() const9746 int CpuProfileNode::GetScriptId() const {
9747   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9748   const i::CodeEntry* entry = node->entry();
9749   return entry->script_id();
9750 }
9751 
GetScriptResourceName() const9752 Local<String> CpuProfileNode::GetScriptResourceName() const {
9753   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9754   i::Isolate* isolate = node->isolate();
9755   return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9756       node->entry()->resource_name()));
9757 }
9758 
GetScriptResourceNameStr() const9759 const char* CpuProfileNode::GetScriptResourceNameStr() const {
9760   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9761   return node->entry()->resource_name();
9762 }
9763 
IsScriptSharedCrossOrigin() const9764 bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9765   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9766   return node->entry()->is_shared_cross_origin();
9767 }
9768 
GetLineNumber() const9769 int CpuProfileNode::GetLineNumber() const {
9770   return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9771 }
9772 
GetColumnNumber() const9773 int CpuProfileNode::GetColumnNumber() const {
9774   return reinterpret_cast<const i::ProfileNode*>(this)
9775       ->entry()
9776       ->column_number();
9777 }
9778 
GetHitLineCount() const9779 unsigned int CpuProfileNode::GetHitLineCount() const {
9780   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9781   return node->GetHitLineCount();
9782 }
9783 
GetLineTicks(LineTick * entries,unsigned int length) const9784 bool CpuProfileNode::GetLineTicks(LineTick* entries,
9785                                   unsigned int length) const {
9786   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9787   return node->GetLineTicks(entries, length);
9788 }
9789 
GetBailoutReason() const9790 const char* CpuProfileNode::GetBailoutReason() const {
9791   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9792   return node->entry()->bailout_reason();
9793 }
9794 
GetHitCount() const9795 unsigned CpuProfileNode::GetHitCount() const {
9796   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9797 }
9798 
GetNodeId() const9799 unsigned CpuProfileNode::GetNodeId() const {
9800   return reinterpret_cast<const i::ProfileNode*>(this)->id();
9801 }
9802 
GetSourceType() const9803 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9804   return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9805 }
9806 
GetChildrenCount() const9807 int CpuProfileNode::GetChildrenCount() const {
9808   return static_cast<int>(
9809       reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9810 }
9811 
GetChild(int index) const9812 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9813   const i::ProfileNode* child =
9814       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9815   return reinterpret_cast<const CpuProfileNode*>(child);
9816 }
9817 
GetParent() const9818 const CpuProfileNode* CpuProfileNode::GetParent() const {
9819   const i::ProfileNode* parent =
9820       reinterpret_cast<const i::ProfileNode*>(this)->parent();
9821   return reinterpret_cast<const CpuProfileNode*>(parent);
9822 }
9823 
GetDeoptInfos() const9824 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9825   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9826   return node->deopt_infos();
9827 }
9828 
Delete()9829 void CpuProfile::Delete() {
9830   i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9831   i::CpuProfiler* profiler = profile->cpu_profiler();
9832   DCHECK_NOT_NULL(profiler);
9833   profiler->DeleteProfile(profile);
9834 }
9835 
GetTitle() const9836 Local<String> CpuProfile::GetTitle() const {
9837   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9838   i::Isolate* isolate = profile->top_down()->isolate();
9839   return ToApiHandle<String>(
9840       isolate->factory()->InternalizeUtf8String(profile->title()));
9841 }
9842 
GetTopDownRoot() const9843 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9844   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9845   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9846 }
9847 
GetSample(int index) const9848 const CpuProfileNode* CpuProfile::GetSample(int index) const {
9849   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9850   return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
9851 }
9852 
9853 const int CpuProfileNode::kNoLineNumberInfo;
9854 const int CpuProfileNode::kNoColumnNumberInfo;
9855 
GetSampleTimestamp(int index) const9856 int64_t CpuProfile::GetSampleTimestamp(int index) const {
9857   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9858   return profile->sample(index).timestamp.since_origin().InMicroseconds();
9859 }
9860 
GetSampleState(int index) const9861 StateTag CpuProfile::GetSampleState(int index) const {
9862   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9863   return profile->sample(index).state_tag;
9864 }
9865 
GetSampleEmbedderState(int index) const9866 EmbedderStateTag CpuProfile::GetSampleEmbedderState(int index) const {
9867   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9868   return profile->sample(index).embedder_state_tag;
9869 }
9870 
GetStartTime() const9871 int64_t CpuProfile::GetStartTime() const {
9872   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9873   return profile->start_time().since_origin().InMicroseconds();
9874 }
9875 
GetEndTime() const9876 int64_t CpuProfile::GetEndTime() const {
9877   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9878   return profile->end_time().since_origin().InMicroseconds();
9879 }
9880 
GetSamplesCount() const9881 int CpuProfile::GetSamplesCount() const {
9882   return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9883 }
9884 
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)9885 CpuProfiler* CpuProfiler::New(Isolate* isolate,
9886                               CpuProfilingNamingMode naming_mode,
9887                               CpuProfilingLoggingMode logging_mode) {
9888   return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
9889       reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
9890 }
9891 
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)9892 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
9893                                          unsigned max_samples,
9894                                          int sampling_interval_us,
9895                                          MaybeLocal<Context> filter_context)
9896     : mode_(mode),
9897       max_samples_(max_samples),
9898       sampling_interval_us_(sampling_interval_us) {
9899   if (!filter_context.IsEmpty()) {
9900     Local<Context> local_filter_context = filter_context.ToLocalChecked();
9901     filter_context_.Reset(local_filter_context->GetIsolate(),
9902                           local_filter_context);
9903     filter_context_.SetWeak();
9904   }
9905 }
9906 
raw_filter_context() const9907 void* CpuProfilingOptions::raw_filter_context() const {
9908   return reinterpret_cast<void*>(
9909       i::Context::cast(*Utils::OpenPersistent(filter_context_))
9910           .native_context()
9911           .address());
9912 }
9913 
Dispose()9914 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9915 
9916 // static
CollectSample(Isolate * isolate)9917 void CpuProfiler::CollectSample(Isolate* isolate) {
9918   i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
9919 }
9920 
SetSamplingInterval(int us)9921 void CpuProfiler::SetSamplingInterval(int us) {
9922   DCHECK_GE(us, 0);
9923   return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
9924       base::TimeDelta::FromMicroseconds(us));
9925 }
9926 
SetUsePreciseSampling(bool use_precise_sampling)9927 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
9928   reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
9929       use_precise_sampling);
9930 }
9931 
Start(CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9932 CpuProfilingResult CpuProfiler::Start(
9933     CpuProfilingOptions options,
9934     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9935   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9936       options, std::move(delegate));
9937 }
9938 
Start(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9939 CpuProfilingResult CpuProfiler::Start(
9940     Local<String> title, CpuProfilingOptions options,
9941     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9942   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9943       *Utils::OpenHandle(*title), options, std::move(delegate));
9944 }
9945 
Start(Local<String> title,bool record_samples)9946 CpuProfilingResult CpuProfiler::Start(Local<String> title,
9947                                       bool record_samples) {
9948   CpuProfilingOptions options(
9949       kLeafNodeLineNumbers,
9950       record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
9951   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9952       *Utils::OpenHandle(*title), options);
9953 }
9954 
Start(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9955 CpuProfilingResult CpuProfiler::Start(Local<String> title,
9956                                       CpuProfilingMode mode,
9957                                       bool record_samples,
9958                                       unsigned max_samples) {
9959   CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
9960   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9961       *Utils::OpenHandle(*title), options);
9962 }
9963 
StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9964 CpuProfilingStatus CpuProfiler::StartProfiling(
9965     Local<String> title, CpuProfilingOptions options,
9966     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9967   return Start(title, options, std::move(delegate)).status;
9968 }
9969 
StartProfiling(Local<String> title,bool record_samples)9970 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9971                                                bool record_samples) {
9972   return Start(title, record_samples).status;
9973 }
9974 
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9975 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9976                                                CpuProfilingMode mode,
9977                                                bool record_samples,
9978                                                unsigned max_samples) {
9979   return Start(title, mode, record_samples, max_samples).status;
9980 }
9981 
StopProfiling(Local<String> title)9982 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
9983   return reinterpret_cast<CpuProfile*>(
9984       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
9985           *Utils::OpenHandle(*title)));
9986 }
9987 
Stop(ProfilerId id)9988 CpuProfile* CpuProfiler::Stop(ProfilerId id) {
9989   return reinterpret_cast<CpuProfile*>(
9990       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id));
9991 }
9992 
UseDetailedSourcePositionsForProfiling(Isolate * isolate)9993 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
9994   reinterpret_cast<i::Isolate*>(isolate)
9995       ->SetDetailedSourcePositionsForProfiling(true);
9996 }
9997 
GetCodeStartAddress()9998 uintptr_t CodeEvent::GetCodeStartAddress() {
9999   return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10000 }
10001 
GetCodeSize()10002 size_t CodeEvent::GetCodeSize() {
10003   return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10004 }
10005 
GetFunctionName()10006 Local<String> CodeEvent::GetFunctionName() {
10007   return ToApiHandle<String>(
10008       reinterpret_cast<i::CodeEvent*>(this)->function_name);
10009 }
10010 
GetScriptName()10011 Local<String> CodeEvent::GetScriptName() {
10012   return ToApiHandle<String>(
10013       reinterpret_cast<i::CodeEvent*>(this)->script_name);
10014 }
10015 
GetScriptLine()10016 int CodeEvent::GetScriptLine() {
10017   return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10018 }
10019 
GetScriptColumn()10020 int CodeEvent::GetScriptColumn() {
10021   return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10022 }
10023 
GetCodeType()10024 CodeEventType CodeEvent::GetCodeType() {
10025   return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10026 }
10027 
GetComment()10028 const char* CodeEvent::GetComment() {
10029   return reinterpret_cast<i::CodeEvent*>(this)->comment;
10030 }
10031 
GetPreviousCodeStartAddress()10032 uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10033   return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10034 }
10035 
GetCodeEventTypeName(CodeEventType code_event_type)10036 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
10037   switch (code_event_type) {
10038     case kUnknownType:
10039       return "Unknown";
10040 #define V(Name)       \
10041   case k##Name##Type: \
10042     return #Name;
10043       CODE_EVENTS_LIST(V)
10044 #undef V
10045   }
10046   // The execution should never pass here
10047   UNREACHABLE();
10048 }
10049 
CodeEventHandler(Isolate * isolate)10050 CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10051   internal_listener_ =
10052       new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10053 }
10054 
~CodeEventHandler()10055 CodeEventHandler::~CodeEventHandler() {
10056   delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10057 }
10058 
Enable()10059 void CodeEventHandler::Enable() {
10060   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10061       ->StartListening(this);
10062 }
10063 
Disable()10064 void CodeEventHandler::Disable() {
10065   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10066       ->StopListening();
10067 }
10068 
ToInternal(const HeapGraphEdge * edge)10069 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10070   return const_cast<i::HeapGraphEdge*>(
10071       reinterpret_cast<const i::HeapGraphEdge*>(edge));
10072 }
10073 
GetType() const10074 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10075   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10076 }
10077 
GetName() const10078 Local<Value> HeapGraphEdge::GetName() const {
10079   i::HeapGraphEdge* edge = ToInternal(this);
10080   i::Isolate* isolate = edge->isolate();
10081   switch (edge->type()) {
10082     case i::HeapGraphEdge::kContextVariable:
10083     case i::HeapGraphEdge::kInternal:
10084     case i::HeapGraphEdge::kProperty:
10085     case i::HeapGraphEdge::kShortcut:
10086     case i::HeapGraphEdge::kWeak:
10087       return ToApiHandle<String>(
10088           isolate->factory()->InternalizeUtf8String(edge->name()));
10089     case i::HeapGraphEdge::kElement:
10090     case i::HeapGraphEdge::kHidden:
10091       return ToApiHandle<Number>(
10092           isolate->factory()->NewNumberFromInt(edge->index()));
10093     default:
10094       UNREACHABLE();
10095   }
10096 }
10097 
GetFromNode() const10098 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10099   const i::HeapEntry* from = ToInternal(this)->from();
10100   return reinterpret_cast<const HeapGraphNode*>(from);
10101 }
10102 
GetToNode() const10103 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10104   const i::HeapEntry* to = ToInternal(this)->to();
10105   return reinterpret_cast<const HeapGraphNode*>(to);
10106 }
10107 
ToInternal(const HeapGraphNode * entry)10108 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10109   return const_cast<i::HeapEntry*>(
10110       reinterpret_cast<const i::HeapEntry*>(entry));
10111 }
10112 
GetType() const10113 HeapGraphNode::Type HeapGraphNode::GetType() const {
10114   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10115 }
10116 
GetName() const10117 Local<String> HeapGraphNode::GetName() const {
10118   i::Isolate* isolate = ToInternal(this)->isolate();
10119   return ToApiHandle<String>(
10120       isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10121 }
10122 
GetId() const10123 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10124 
GetShallowSize() const10125 size_t HeapGraphNode::GetShallowSize() const {
10126   return ToInternal(this)->self_size();
10127 }
10128 
GetChildrenCount() const10129 int HeapGraphNode::GetChildrenCount() const {
10130   return ToInternal(this)->children_count();
10131 }
10132 
GetChild(int index) const10133 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10134   return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10135 }
10136 
ToInternal(const HeapSnapshot * snapshot)10137 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10138   return const_cast<i::HeapSnapshot*>(
10139       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10140 }
10141 
Delete()10142 void HeapSnapshot::Delete() {
10143   i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10144   if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
10145       isolate->heap_profiler()->IsTakingSnapshot()) {
10146     ToInternal(this)->Delete();
10147   } else {
10148     // If this is the last snapshot, clean up all accessory data as well.
10149     isolate->heap_profiler()->DeleteAllSnapshots();
10150   }
10151 }
10152 
GetRoot() const10153 const HeapGraphNode* HeapSnapshot::GetRoot() const {
10154   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10155 }
10156 
GetNodeById(SnapshotObjectId id) const10157 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10158   return reinterpret_cast<const HeapGraphNode*>(
10159       ToInternal(this)->GetEntryById(id));
10160 }
10161 
GetNodesCount() const10162 int HeapSnapshot::GetNodesCount() const {
10163   return static_cast<int>(ToInternal(this)->entries().size());
10164 }
10165 
GetNode(int index) const10166 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10167   return reinterpret_cast<const HeapGraphNode*>(
10168       &ToInternal(this)->entries().at(index));
10169 }
10170 
GetMaxSnapshotJSObjectId() const10171 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10172   return ToInternal(this)->max_snapshot_js_object_id();
10173 }
10174 
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10175 void HeapSnapshot::Serialize(OutputStream* stream,
10176                              HeapSnapshot::SerializationFormat format) const {
10177   Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
10178                   "Unknown serialization format");
10179   Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
10180                   "Invalid stream chunk size");
10181   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10182   serializer.Serialize(stream);
10183 }
10184 
10185 // static
10186 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10187     HeapProfiler::kUnknownObjectId;
10188 
GetSnapshotCount()10189 int HeapProfiler::GetSnapshotCount() {
10190   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10191 }
10192 
GetHeapSnapshot(int index)10193 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10194   return reinterpret_cast<const HeapSnapshot*>(
10195       reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10196 }
10197 
GetObjectId(Local<Value> value)10198 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10199   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10200   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10201 }
10202 
GetObjectId(NativeObject value)10203 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10204   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10205 }
10206 
FindObjectById(SnapshotObjectId id)10207 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10208   i::Handle<i::Object> obj =
10209       reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10210   if (obj.is_null()) return Local<Value>();
10211   return Utils::ToLocal(obj);
10212 }
10213 
ClearObjectIds()10214 void HeapProfiler::ClearObjectIds() {
10215   reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10216 }
10217 
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)10218 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
10219     ActivityControl* control, ObjectNameResolver* resolver,
10220     bool treat_global_objects_as_roots, bool capture_numeric_value) {
10221   return reinterpret_cast<const HeapSnapshot*>(
10222       reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
10223           control, resolver, treat_global_objects_as_roots,
10224           capture_numeric_value));
10225 }
10226 
StartTrackingHeapObjects(bool track_allocations)10227 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10228   reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10229       track_allocations);
10230 }
10231 
StopTrackingHeapObjects()10232 void HeapProfiler::StopTrackingHeapObjects() {
10233   reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10234 }
10235 
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)10236 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
10237                                             int64_t* timestamp_us) {
10238   i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
10239   return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
10240 }
10241 
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)10242 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
10243                                              int stack_depth,
10244                                              SamplingFlags flags) {
10245   return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
10246       sample_interval, stack_depth, flags);
10247 }
10248 
StopSamplingHeapProfiler()10249 void HeapProfiler::StopSamplingHeapProfiler() {
10250   reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10251 }
10252 
GetAllocationProfile()10253 AllocationProfile* HeapProfiler::GetAllocationProfile() {
10254   return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10255 }
10256 
DeleteAllHeapSnapshots()10257 void HeapProfiler::DeleteAllHeapSnapshots() {
10258   reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10259 }
10260 
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10261 void HeapProfiler::AddBuildEmbedderGraphCallback(
10262     BuildEmbedderGraphCallback callback, void* data) {
10263   reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10264       callback, data);
10265 }
10266 
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10267 void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10268     BuildEmbedderGraphCallback callback, void* data) {
10269   reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10270       callback, data);
10271 }
10272 
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10273 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10274                                               void* data) {
10275   reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10276                                                                        data);
10277 }
10278 
SetStackStart(void * stack_start)10279 void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10280   CHECK(isolate_);
10281   reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10282       stack_start);
10283 }
10284 
FinalizeTracing()10285 void EmbedderHeapTracer::FinalizeTracing() {
10286   if (isolate_) {
10287     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10288     if (isolate->heap()->incremental_marking()->IsMarking()) {
10289       isolate->heap()->FinalizeIncrementalMarkingAtomically(
10290           i::GarbageCollectionReason::kExternalFinalize);
10291     }
10292   }
10293 }
10294 
IncreaseAllocatedSize(size_t bytes)10295 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
10296   if (isolate_) {
10297     i::LocalEmbedderHeapTracer* const tracer =
10298         reinterpret_cast<i::Isolate*>(isolate_)
10299             ->heap()
10300             ->local_embedder_heap_tracer();
10301     DCHECK_NOT_NULL(tracer);
10302     tracer->IncreaseAllocatedSize(bytes);
10303   }
10304 }
10305 
DecreaseAllocatedSize(size_t bytes)10306 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
10307   if (isolate_) {
10308     i::LocalEmbedderHeapTracer* const tracer =
10309         reinterpret_cast<i::Isolate*>(isolate_)
10310             ->heap()
10311             ->local_embedder_heap_tracer();
10312     DCHECK_NOT_NULL(tracer);
10313     tracer->DecreaseAllocatedSize(bytes);
10314   }
10315 }
10316 
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10317 void EmbedderHeapTracer::RegisterEmbedderReference(
10318     const BasicTracedReference<v8::Data>& ref) {
10319   if (ref.IsEmpty()) return;
10320 
10321   i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10322   heap->RegisterExternallyReferencedObject(
10323       reinterpret_cast<i::Address*>(ref.val_));
10324 }
10325 
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10326 void EmbedderHeapTracer::IterateTracedGlobalHandles(
10327     TracedGlobalHandleVisitor* visitor) {
10328   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10329   i::DisallowGarbageCollection no_gc;
10330   isolate->global_handles()->IterateTracedNodes(visitor);
10331 }
10332 
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10333 bool EmbedderHeapTracer::IsRootForNonTracingGC(
10334     const v8::TracedReference<v8::Value>& handle) {
10335   return true;
10336 }
10337 
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10338 void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10339     const v8::TracedReference<v8::Value>& handle) {
10340   UNREACHABLE();
10341 }
10342 
EmbedderStateScope(Isolate * isolate,Local<v8::Context> context,EmbedderStateTag tag)10343 EmbedderStateScope::EmbedderStateScope(Isolate* isolate,
10344                                        Local<v8::Context> context,
10345                                        EmbedderStateTag tag)
10346     : embedder_state_(new internal::EmbedderState(isolate, context, tag)) {}
10347 
10348 // std::unique_ptr's destructor is not compatible with Forward declared
10349 // EmbedderState class.
10350 // Default destructor must be defined in implementation file.
10351 EmbedderStateScope::~EmbedderStateScope() = default;
10352 
CheckValue() const10353 void TracedReferenceBase::CheckValue() const {
10354 #ifdef V8_HOST_ARCH_64_BIT
10355   if (!val_) return;
10356 
10357   CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_));
10358 #endif  // V8_HOST_ARCH_64_BIT
10359 }
10360 
CFunction(const void * address,const CFunctionInfo * type_info)10361 CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
10362     : address_(address), type_info_(type_info) {
10363   CHECK_NOT_NULL(address_);
10364   CHECK_NOT_NULL(type_info_);
10365 }
10366 
CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10367 CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info,
10368                              unsigned int arg_count, const CTypeInfo* arg_info)
10369     : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) {
10370   if (arg_count_ > 0) {
10371     for (unsigned int i = 0; i < arg_count_ - 1; ++i) {
10372       DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType);
10373     }
10374   }
10375 }
10376 
ArgumentInfo(unsigned int index) const10377 const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10378   DCHECK_LT(index, ArgumentCount());
10379   return arg_info_[index];
10380 }
10381 
ValidateIndex(size_t index) const10382 void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10383   DCHECK_LT(index, length_);
10384 }
10385 
RegisterState()10386 RegisterState::RegisterState()
10387     : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10388 RegisterState::~RegisterState() = default;
10389 
RegisterState(const RegisterState & other)10390 RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10391 
operator =(const RegisterState & other)10392 RegisterState& RegisterState::operator=(const RegisterState& other) {
10393   if (&other != this) {
10394     pc = other.pc;
10395     sp = other.sp;
10396     fp = other.fp;
10397     lr = other.lr;
10398     if (other.callee_saved) {
10399       // Make a deep copy if {other.callee_saved} is non-null.
10400       callee_saved =
10401           std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
10402     } else {
10403       // Otherwise, set {callee_saved} to null to match {other}.
10404       callee_saved.reset();
10405     }
10406   }
10407   return *this;
10408 }
10409 
10410 #if !V8_ENABLE_WEBASSEMBLY
10411 // If WebAssembly is disabled, we still need to provide an implementation of the
10412 // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all
10413 // methods are unreachable.
10414 
10415 class WasmStreaming::WasmStreamingImpl {};
10416 
WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10417 WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10418   UNREACHABLE();
10419 }
10420 
10421 WasmStreaming::~WasmStreaming() = default;
10422 
OnBytesReceived(const uint8_t * bytes,size_t size)10423 void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10424   UNREACHABLE();
10425 }
10426 
Finish(bool can_use_compiled_module)10427 void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); }
10428 
Abort(MaybeLocal<Value> exception)10429 void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10430 
SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10431 bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10432   UNREACHABLE();
10433 }
10434 
SetClient(std::shared_ptr<Client> client)10435 void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10436 
SetUrl(const char * url,size_t length)10437 void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10438 
10439 // static
Unpack(Isolate * isolate,Local<Value> value)10440 std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10441                                                      Local<Value> value) {
10442   FATAL("WebAssembly is disabled");
10443 }
10444 #endif  // !V8_ENABLE_WEBASSEMBLY
10445 
10446 namespace internal {
10447 
10448 const size_t HandleScopeImplementer::kEnteredContextsOffset =
10449     offsetof(HandleScopeImplementer, entered_contexts_);
10450 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10451     offsetof(HandleScopeImplementer, is_microtask_context_);
10452 
FreeThreadResources()10453 void HandleScopeImplementer::FreeThreadResources() { Free(); }
10454 
ArchiveThread(char * storage)10455 char* HandleScopeImplementer::ArchiveThread(char* storage) {
10456   HandleScopeData* current = isolate_->handle_scope_data();
10457   handle_scope_data_ = *current;
10458   MemCopy(storage, this, sizeof(*this));
10459 
10460   ResetAfterArchive();
10461   current->Initialize();
10462 
10463   return storage + ArchiveSpacePerThread();
10464 }
10465 
ArchiveSpacePerThread()10466 int HandleScopeImplementer::ArchiveSpacePerThread() {
10467   return sizeof(HandleScopeImplementer);
10468 }
10469 
RestoreThread(char * storage)10470 char* HandleScopeImplementer::RestoreThread(char* storage) {
10471   MemCopy(this, storage, sizeof(*this));
10472   *isolate_->handle_scope_data() = handle_scope_data_;
10473   return storage + ArchiveSpacePerThread();
10474 }
10475 
IterateThis(RootVisitor * v)10476 void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10477 #ifdef DEBUG
10478   bool found_block_before_deferred = false;
10479 #endif
10480   // Iterate over all handles in the blocks except for the last.
10481   for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10482     Address* block = blocks()->at(i);
10483     // Cast possibly-unrelated pointers to plain Address before comparing them
10484     // to avoid undefined behavior.
10485     if (last_handle_before_deferred_block_ != nullptr &&
10486         (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
10487          reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
10488         (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
10489          reinterpret_cast<Address>(block))) {
10490       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10491                            FullObjectSlot(last_handle_before_deferred_block_));
10492       DCHECK(!found_block_before_deferred);
10493 #ifdef DEBUG
10494       found_block_before_deferred = true;
10495 #endif
10496     } else {
10497       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10498                            FullObjectSlot(&block[kHandleBlockSize]));
10499     }
10500   }
10501 
10502   DCHECK(last_handle_before_deferred_block_ == nullptr ||
10503          found_block_before_deferred);
10504 
10505   // Iterate over live handles in the last block (if any).
10506   if (!blocks()->empty()) {
10507     v->VisitRootPointers(Root::kHandleScope, nullptr,
10508                          FullObjectSlot(blocks()->back()),
10509                          FullObjectSlot(handle_scope_data_.next));
10510   }
10511 
10512   DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
10513                                                  &entered_contexts_};
10514   for (unsigned i = 0; i < arraysize(context_lists); i++) {
10515     context_lists[i]->shrink_to_fit();
10516     if (context_lists[i]->empty()) continue;
10517     FullObjectSlot start(&context_lists[i]->front());
10518     v->VisitRootPointers(Root::kHandleScope, nullptr, start,
10519                          start + static_cast<int>(context_lists[i]->size()));
10520   }
10521   // The shape of |entered_contexts_| and |is_microtask_context_| stacks must
10522   // be in sync.
10523   is_microtask_context_.shrink_to_fit();
10524   DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
10525   DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
10526 }
10527 
Iterate(RootVisitor * v)10528 void HandleScopeImplementer::Iterate(RootVisitor* v) {
10529   HandleScopeData* current = isolate_->handle_scope_data();
10530   handle_scope_data_ = *current;
10531   IterateThis(v);
10532 }
10533 
Iterate(RootVisitor * v,char * storage)10534 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10535   HandleScopeImplementer* scope_implementer =
10536       reinterpret_cast<HandleScopeImplementer*>(storage);
10537   scope_implementer->IterateThis(v);
10538   return storage + ArchiveSpacePerThread();
10539 }
10540 
DetachPersistent(Address * prev_limit)10541 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
10542     Address* prev_limit) {
10543   std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
10544   DCHECK_NOT_NULL(prev_limit);
10545 
10546   while (!blocks_.empty()) {
10547     Address* block_start = blocks_.back();
10548     Address* block_limit = &block_start[kHandleBlockSize];
10549     // We should not need to check for SealHandleScope here. Assert this.
10550     DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
10551                    prev_limit == block_limit);
10552     if (prev_limit == block_limit) break;
10553     ph->blocks_.push_back(blocks_.back());
10554 #if DEBUG
10555     ph->ordered_blocks_.insert(blocks_.back());
10556 #endif
10557     blocks_.pop_back();
10558   }
10559 
10560   // ph->blocks_ now contains the blocks installed on the
10561   // HandleScope stack since BeginDeferredScope was called, but in
10562   // reverse order.
10563 
10564   // Switch first and last blocks, such that the last block is the one
10565   // that is potentially half full.
10566   DCHECK(!blocks_.empty() && !ph->blocks_.empty());
10567   std::swap(ph->blocks_.front(), ph->blocks_.back());
10568 
10569   ph->block_next_ = isolate()->handle_scope_data()->next;
10570   Address* block_start = ph->blocks_.back();
10571   ph->block_limit_ = block_start + kHandleBlockSize;
10572 
10573   DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10574   last_handle_before_deferred_block_ = nullptr;
10575   return ph;
10576 }
10577 
BeginDeferredScope()10578 void HandleScopeImplementer::BeginDeferredScope() {
10579   DCHECK_NULL(last_handle_before_deferred_block_);
10580   last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10581 }
10582 
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10583 void InvokeAccessorGetterCallback(
10584     v8::Local<v8::Name> property,
10585     const v8::PropertyCallbackInfo<v8::Value>& info,
10586     v8::AccessorNameGetterCallback getter) {
10587   // Leaving JavaScript.
10588   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10589   RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
10590   Address getter_address = reinterpret_cast<Address>(getter);
10591   ExternalCallbackScope call_scope(isolate, getter_address);
10592   getter(property, info);
10593 }
10594 
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10595 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10596                             v8::FunctionCallback callback) {
10597   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10598   RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
10599   Address callback_address = reinterpret_cast<Address>(callback);
10600   ExternalCallbackScope call_scope(isolate, callback_address);
10601   callback(info);
10602 }
10603 
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10604 void InvokeFinalizationRegistryCleanupFromTask(
10605     Handle<Context> context,
10606     Handle<JSFinalizationRegistry> finalization_registry,
10607     Handle<Object> callback) {
10608   Isolate* isolate = finalization_registry->native_context().GetIsolate();
10609   RCS_SCOPE(isolate,
10610             RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
10611   // Do not use ENTER_V8 because this is always called from a running
10612   // FinalizationRegistryCleanupTask within V8 and we should not log it as an
10613   // API call. This method is implemented here to avoid duplication of the
10614   // exception handling and microtask running logic in CallDepthScope.
10615   if (IsExecutionTerminatingCheck(isolate)) return;
10616   Local<v8::Context> api_context = Utils::ToLocal(context);
10617   CallDepthScope<true> call_depth_scope(isolate, api_context);
10618   VMState<OTHER> state(isolate);
10619   Handle<Object> argv[] = {callback};
10620   if (Execution::CallBuiltin(isolate,
10621                              isolate->finalization_registry_cleanup_some(),
10622                              finalization_registry, arraysize(argv), argv)
10623           .is_null()) {
10624     call_depth_scope.Escape();
10625   }
10626 }
10627 
10628 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10629 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10630 int32_t ConvertDouble(double d) {
10631   return internal::DoubleToInt32(d);
10632 }
10633 
10634 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10635 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10636 uint32_t ConvertDouble(double d) {
10637   return internal::DoubleToUint32(d);
10638 }
10639 
10640 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10641 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10642 float ConvertDouble(double d) {
10643   return internal::DoubleToFloat32(d);
10644 }
10645 
10646 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10647 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10648 double ConvertDouble(double d) {
10649   return d;
10650 }
10651 
10652 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10653 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10654 int64_t ConvertDouble(double d) {
10655   return internal::DoubleToWebIDLInt64(d);
10656 }
10657 
10658 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10659 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10660 uint64_t ConvertDouble(double d) {
10661   return internal::DoubleToWebIDLUint64(d);
10662 }
10663 
10664 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10665 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10666 bool ConvertDouble(double d) {
10667   // Implements https://tc39.es/ecma262/#sec-toboolean.
10668   return !std::isnan(d) && d != 0;
10669 }
10670 
10671 // Undefine macros for jumbo build.
10672 #undef SET_FIELD_WRAPPED
10673 #undef NEW_STRING
10674 #undef CALLBACK_SETTER
10675 
10676 }  // namespace internal
10677 
10678 template <>
10679 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10680 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
10681                                     int32_t>(Local<Array> src, int32_t* dst,
10682                                              uint32_t max_length) {
10683   return CopyAndConvertArrayToCppBuffer<
10684       CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence)
10685           .GetId(),
10686       int32_t>(src, dst, max_length);
10687 }
10688 
10689 template <>
10690 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10691 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
10692                                     uint32_t>(Local<Array> src, uint32_t* dst,
10693                                               uint32_t max_length) {
10694   return CopyAndConvertArrayToCppBuffer<
10695       CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence)
10696           .GetId(),
10697       uint32_t>(src, dst, max_length);
10698 }
10699 
10700 template <>
10701 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10702 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
10703                                     float>(Local<Array> src, float* dst,
10704                                            uint32_t max_length) {
10705   return CopyAndConvertArrayToCppBuffer<
10706       CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence)
10707           .GetId(),
10708       float>(src, dst, max_length);
10709 }
10710 
10711 template <>
10712 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10713 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
10714                                     double>(Local<Array> src, double* dst,
10715                                             uint32_t max_length) {
10716   return CopyAndConvertArrayToCppBuffer<
10717       CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence)
10718           .GetId(),
10719       double>(src, dst, max_length);
10720 }
10721 
10722 }  // namespace v8
10723 
10724 #undef TRACE_BS
10725 #include "src/api/api-macros-undef.h"
10726