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-extension.h"
19 #include "include/v8-fast-api-calls.h"
20 #include "include/v8-function.h"
21 #include "include/v8-json.h"
22 #include "include/v8-locker.h"
23 #include "include/v8-primitive-object.h"
24 #include "include/v8-profiler.h"
25 #include "include/v8-unwinder-state.h"
26 #include "include/v8-util.h"
27 #include "include/v8-wasm.h"
28 #include "src/api/api-inl.h"
29 #include "src/api/api-natives.h"
30 #include "src/base/functional.h"
31 #include "src/base/logging.h"
32 #include "src/base/platform/platform.h"
33 #include "src/base/platform/time.h"
34 #include "src/base/safe_conversions.h"
35 #include "src/base/utils/random-number-generator.h"
36 #include "src/baseline/baseline-batch-compiler.h"
37 #include "src/builtins/accessors.h"
38 #include "src/builtins/builtins-utils.h"
39 #include "src/codegen/compiler.h"
40 #include "src/codegen/cpu-features.h"
41 #include "src/codegen/script-details.h"
42 #include "src/common/assert-scope.h"
43 #include "src/common/external-pointer.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/debug/liveedit.h"
48 #include "src/deoptimizer/deoptimizer.h"
49 #include "src/diagnostics/gdb-jit.h"
50 #include "src/execution/execution.h"
51 #include "src/execution/frames-inl.h"
52 #include "src/execution/isolate-inl.h"
53 #include "src/execution/messages.h"
54 #include "src/execution/microtask-queue.h"
55 #include "src/execution/runtime-profiler.h"
56 #include "src/execution/simulator.h"
57 #include "src/execution/v8threads.h"
58 #include "src/execution/vm-state-inl.h"
59 #include "src/handles/global-handles.h"
60 #include "src/handles/persistent-handles.h"
61 #include "src/heap/embedder-tracing.h"
62 #include "src/heap/heap-inl.h"
63 #include "src/init/bootstrapper.h"
64 #include "src/init/icu_util.h"
65 #include "src/init/startup-data-util.h"
66 #include "src/init/v8.h"
67 #include "src/init/vm-cage.h"
68 #include "src/json/json-parser.h"
69 #include "src/json/json-stringifier.h"
70 #include "src/logging/counters-scopes.h"
71 #include "src/logging/metrics.h"
72 #include "src/logging/runtime-call-stats-scope.h"
73 #include "src/logging/tracing-flags.h"
74 #include "src/numbers/conversions-inl.h"
75 #include "src/objects/api-callbacks.h"
76 #include "src/objects/contexts.h"
77 #include "src/objects/embedder-data-array-inl.h"
78 #include "src/objects/embedder-data-slot-inl.h"
79 #include "src/objects/hash-table-inl.h"
80 #include "src/objects/heap-object.h"
81 #include "src/objects/js-array-buffer-inl.h"
82 #include "src/objects/js-array-inl.h"
83 #include "src/objects/js-collection-inl.h"
84 #include "src/objects/js-promise-inl.h"
85 #include "src/objects/js-regexp-inl.h"
86 #include "src/objects/js-weak-refs-inl.h"
87 #include "src/objects/module-inl.h"
88 #include "src/objects/objects-inl.h"
89 #include "src/objects/oddball.h"
90 #include "src/objects/ordered-hash-table-inl.h"
91 #include "src/objects/property-descriptor.h"
92 #include "src/objects/property-details.h"
93 #include "src/objects/property.h"
94 #include "src/objects/prototype.h"
95 #include "src/objects/shared-function-info.h"
96 #include "src/objects/slots.h"
97 #include "src/objects/smi.h"
98 #include "src/objects/stack-frame-info-inl.h"
99 #include "src/objects/synthetic-module-inl.h"
100 #include "src/objects/templates.h"
101 #include "src/objects/value-serializer.h"
102 #include "src/parsing/parse-info.h"
103 #include "src/parsing/parser.h"
104 #include "src/parsing/pending-compilation-error-handler.h"
105 #include "src/parsing/scanner-character-streams.h"
106 #include "src/profiler/cpu-profiler.h"
107 #include "src/profiler/heap-profiler.h"
108 #include "src/profiler/heap-snapshot-generator-inl.h"
109 #include "src/profiler/profile-generator-inl.h"
110 #include "src/profiler/tick-sample.h"
111 #include "src/regexp/regexp-utils.h"
112 #include "src/runtime/runtime.h"
113 #include "src/snapshot/code-serializer.h"
114 #include "src/snapshot/embedded/embedded-data.h"
115 #include "src/snapshot/snapshot.h"
116 #include "src/snapshot/startup-serializer.h"  // For SerializedHandleChecker.
117 #include "src/strings/char-predicates-inl.h"
118 #include "src/strings/string-hasher.h"
119 #include "src/strings/unicode-inl.h"
120 #include "src/tracing/trace-event.h"
121 #include "src/utils/detachable-vector.h"
122 #include "src/utils/version.h"
123 
124 #if V8_ENABLE_WEBASSEMBLY
125 #include "src/trap-handler/trap-handler.h"
126 #include "src/wasm/streaming-decoder.h"
127 #include "src/wasm/value-type.h"
128 #include "src/wasm/wasm-engine.h"
129 #include "src/wasm/wasm-js.h"
130 #include "src/wasm/wasm-objects-inl.h"
131 #include "src/wasm/wasm-result.h"
132 #include "src/wasm/wasm-serialization.h"
133 #endif  // V8_ENABLE_WEBASSEMBLY
134 
135 #if V8_OS_LINUX || V8_OS_MACOSX || V8_OS_FREEBSD
136 #include <signal.h>
137 #include "include/v8-wasm-trap-handler-posix.h"
138 #include "src/trap-handler/handler-inside-posix.h"
139 #endif
140 
141 #if V8_OS_WIN
142 #include <windows.h>
143 
144 // This has to come after windows.h.
145 #include <versionhelpers.h>
146 
147 #include "include/v8-wasm-trap-handler-win.h"
148 #include "src/trap-handler/handler-inside-win.h"
149 #if defined(V8_OS_WIN64)
150 #include "src/base/platform/wrappers.h"
151 #include "src/diagnostics/unwinding-info-win64.h"
152 #endif  // V8_OS_WIN64
153 #if defined(V8_ENABLE_SYSTEM_INSTRUMENTATION)
154 #include "src/diagnostics/system-jit-win.h"
155 #endif
156 #endif  // V8_OS_WIN
157 
158 // Has to be the last include (doesn't have include guards):
159 #include "src/api/api-macros.h"
160 
161 #define TRACE_BS(...)                                     \
162   do {                                                    \
163     if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \
164   } while (false)
165 
166 namespace v8 {
167 
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)168 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
169                                              i::Handle<i::Script> script) {
170   i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
171   i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
172   i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(),
173                                                 isolate);
174   ScriptOriginOptions options(script->origin_options());
175   bool is_wasm = false;
176 #if V8_ENABLE_WEBASSEMBLY
177   is_wasm = script->type() == i::Script::TYPE_WASM;
178 #endif  // V8_ENABLE_WEBASSEMBLY
179   v8::ScriptOrigin origin(
180       reinterpret_cast<v8::Isolate*>(isolate), Utils::ToLocal(scriptName),
181       script->line_offset(), script->column_offset(),
182       options.IsSharedCrossOrigin(), script->id(),
183       Utils::ToLocal(source_map_url), options.IsOpaque(), is_wasm,
184       options.IsModule(), Utils::PrimitiveArrayToLocal(host_defined_options));
185   return origin;
186 }
187 
ScriptOrigin(Local<Value> resource_name,Local<Integer> line_offset,Local<Integer> column_offset,Local<Boolean> is_shared_cross_origin,Local<Integer> script_id,Local<Value> source_map_url,Local<Boolean> is_opaque,Local<Boolean> is_wasm,Local<Boolean> is_module,Local<PrimitiveArray> host_defined_options)188 ScriptOrigin::ScriptOrigin(
189     Local<Value> resource_name, Local<Integer> line_offset,
190     Local<Integer> column_offset, Local<Boolean> is_shared_cross_origin,
191     Local<Integer> script_id, Local<Value> source_map_url,
192     Local<Boolean> is_opaque, Local<Boolean> is_wasm, Local<Boolean> is_module,
193     Local<PrimitiveArray> host_defined_options)
194     : ScriptOrigin(
195           Isolate::GetCurrent(), resource_name,
196           line_offset.IsEmpty() ? 0 : static_cast<int>(line_offset->Value()),
197           column_offset.IsEmpty() ? 0
198                                   : static_cast<int>(column_offset->Value()),
199           !is_shared_cross_origin.IsEmpty() && is_shared_cross_origin->IsTrue(),
200           static_cast<int>(script_id.IsEmpty() ? -1 : script_id->Value()),
201           source_map_url, !is_opaque.IsEmpty() && is_opaque->IsTrue(),
202           !is_wasm.IsEmpty() && is_wasm->IsTrue(),
203           !is_module.IsEmpty() && is_module->IsTrue(), host_defined_options) {}
204 
ScriptOrigin(Local<Value> resource_name,int line_offset,int column_offset,bool is_shared_cross_origin,int script_id,Local<Value> source_map_url,bool is_opaque,bool is_wasm,bool is_module,Local<PrimitiveArray> host_defined_options)205 ScriptOrigin::ScriptOrigin(Local<Value> resource_name, int line_offset,
206                            int column_offset, bool is_shared_cross_origin,
207                            int script_id, Local<Value> source_map_url,
208                            bool is_opaque, bool is_wasm, bool is_module,
209                            Local<PrimitiveArray> host_defined_options)
210     : isolate_(Isolate::GetCurrent()),
211       resource_name_(resource_name),
212       resource_line_offset_(line_offset),
213       resource_column_offset_(column_offset),
214       options_(is_shared_cross_origin, is_opaque, is_wasm, is_module),
215       script_id_(script_id),
216       source_map_url_(source_map_url),
217       host_defined_options_(host_defined_options) {}
218 
ResourceLineOffset() const219 Local<Integer> ScriptOrigin::ResourceLineOffset() const {
220   return v8::Integer::New(isolate_, resource_line_offset_);
221 }
222 
ResourceColumnOffset() const223 Local<Integer> ScriptOrigin::ResourceColumnOffset() const {
224   return v8::Integer::New(isolate_, resource_column_offset_);
225 }
226 
ScriptID() const227 Local<Integer> ScriptOrigin::ScriptID() const {
228   return v8::Integer::New(isolate_, script_id_);
229 }
230 
231 // --- E x c e p t i o n   B e h a v i o r ---
232 
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location)233 void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
234   i::V8::FatalProcessOutOfMemory(isolate, location, false);
235 }
236 
237 // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
238 // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location,bool is_heap_oom)239 void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
240                                     bool is_heap_oom) {
241   char last_few_messages[Heap::kTraceRingBufferSize + 1];
242   char js_stacktrace[Heap::kStacktraceBufferSize + 1];
243   i::HeapStats heap_stats;
244 
245   if (isolate == nullptr) {
246     isolate = Isolate::TryGetCurrent();
247   }
248 
249   if (isolate == nullptr) {
250     // If the Isolate is not available for the current thread we cannot retrieve
251     // memory information from the Isolate. Write easy-to-recognize values on
252     // the stack.
253     memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
254     memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
255     memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
256     // Note that the embedder's oom handler is also not available and therefore
257     // won't be called in this case. We just crash.
258     FATAL("Fatal process out of memory: %s", location);
259     UNREACHABLE();
260   }
261 
262   memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
263   memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
264 
265   intptr_t start_marker;
266   heap_stats.start_marker = &start_marker;
267   size_t ro_space_size;
268   heap_stats.ro_space_size = &ro_space_size;
269   size_t ro_space_capacity;
270   heap_stats.ro_space_capacity = &ro_space_capacity;
271   size_t new_space_size;
272   heap_stats.new_space_size = &new_space_size;
273   size_t new_space_capacity;
274   heap_stats.new_space_capacity = &new_space_capacity;
275   size_t old_space_size;
276   heap_stats.old_space_size = &old_space_size;
277   size_t old_space_capacity;
278   heap_stats.old_space_capacity = &old_space_capacity;
279   size_t code_space_size;
280   heap_stats.code_space_size = &code_space_size;
281   size_t code_space_capacity;
282   heap_stats.code_space_capacity = &code_space_capacity;
283   size_t map_space_size;
284   heap_stats.map_space_size = &map_space_size;
285   size_t map_space_capacity;
286   heap_stats.map_space_capacity = &map_space_capacity;
287   size_t lo_space_size;
288   heap_stats.lo_space_size = &lo_space_size;
289   size_t code_lo_space_size;
290   heap_stats.code_lo_space_size = &code_lo_space_size;
291   size_t global_handle_count;
292   heap_stats.global_handle_count = &global_handle_count;
293   size_t weak_global_handle_count;
294   heap_stats.weak_global_handle_count = &weak_global_handle_count;
295   size_t pending_global_handle_count;
296   heap_stats.pending_global_handle_count = &pending_global_handle_count;
297   size_t near_death_global_handle_count;
298   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
299   size_t free_global_handle_count;
300   heap_stats.free_global_handle_count = &free_global_handle_count;
301   size_t memory_allocator_size;
302   heap_stats.memory_allocator_size = &memory_allocator_size;
303   size_t memory_allocator_capacity;
304   heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
305   size_t malloced_memory;
306   heap_stats.malloced_memory = &malloced_memory;
307   size_t malloced_peak_memory;
308   heap_stats.malloced_peak_memory = &malloced_peak_memory;
309   size_t objects_per_type[LAST_TYPE + 1] = {0};
310   heap_stats.objects_per_type = objects_per_type;
311   size_t size_per_type[LAST_TYPE + 1] = {0};
312   heap_stats.size_per_type = size_per_type;
313   int os_error;
314   heap_stats.os_error = &os_error;
315   heap_stats.last_few_messages = last_few_messages;
316   heap_stats.js_stacktrace = js_stacktrace;
317   intptr_t end_marker;
318   heap_stats.end_marker = &end_marker;
319   if (isolate->heap()->HasBeenSetUp()) {
320     // BUG(1718): Don't use the take_snapshot since we don't support
321     // HeapObjectIterator here without doing a special GC.
322     isolate->heap()->RecordStats(&heap_stats, false);
323     if (!FLAG_correctness_fuzzer_suppressions) {
324       char* first_newline = strchr(last_few_messages, '\n');
325       if (first_newline == nullptr || first_newline[1] == '\0')
326         first_newline = last_few_messages;
327       base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline);
328       base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
329     }
330   }
331   Utils::ReportOOMFailure(isolate, location, is_heap_oom);
332   // If the fatal error handler returns, we stop execution.
333   FATAL("API fatal error handler returned after process out of memory");
334 }
335 
ReportApiFailure(const char * location,const char * message)336 void Utils::ReportApiFailure(const char* location, const char* message) {
337   i::Isolate* isolate = i::Isolate::TryGetCurrent();
338   FatalErrorCallback callback = nullptr;
339   if (isolate != nullptr) {
340     callback = isolate->exception_behavior();
341   }
342   if (callback == nullptr) {
343     base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
344                          message);
345     base::OS::Abort();
346   } else {
347     callback(location, message);
348   }
349   isolate->SignalFatalError();
350 }
351 
ReportOOMFailure(i::Isolate * isolate,const char * location,bool is_heap_oom)352 void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location,
353                              bool is_heap_oom) {
354   OOMErrorCallback oom_callback = isolate->oom_behavior();
355   if (oom_callback == nullptr) {
356     // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
357     // crbug.com/614440.
358     FatalErrorCallback fatal_callback = isolate->exception_behavior();
359     if (fatal_callback == nullptr) {
360       base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
361                            is_heap_oom ? "javascript" : "process", location);
362 #ifdef V8_FUZZILLI
363       exit(0);
364 #else
365       base::OS::Abort();
366 #endif  // V8_FUZZILLI
367     } else {
368       fatal_callback(location,
369                      is_heap_oom
370                          ? "Allocation failed - JavaScript heap out of memory"
371                          : "Allocation failed - process out of memory");
372     }
373   } else {
374     oom_callback(location, is_heap_oom);
375   }
376   isolate->SignalFatalError();
377 }
378 
SetSnapshotDataBlob(StartupData * snapshot_blob)379 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
380   i::V8::SetSnapshotBlob(snapshot_blob);
381 }
382 
383 namespace {
384 
385 #ifdef V8_VIRTUAL_MEMORY_CAGE
386 // ArrayBufferAllocator to use when the virtual memory cage is enabled, in which
387 // case all ArrayBuffer backing stores need to be allocated inside the data
388 // cage. Note, the current implementation is extremely inefficient as it uses
389 // the BoundedPageAllocator. In the future, we'll need a proper allocator
390 // implementation.
391 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
392  public:
ArrayBufferAllocator()393   ArrayBufferAllocator() { CHECK(page_allocator_); }
394 
Allocate(size_t length)395   void* Allocate(size_t length) override {
396     return page_allocator_->AllocatePages(nullptr, RoundUp(length, page_size_),
397                                           page_size_,
398                                           PageAllocator::kReadWrite);
399   }
400 
AllocateUninitialized(size_t length)401   void* AllocateUninitialized(size_t length) override {
402     return Allocate(length);
403   }
404 
Free(void * data,size_t length)405   void Free(void* data, size_t length) override {
406     page_allocator_->FreePages(data, RoundUp(length, page_size_));
407   }
408 
409  private:
410   PageAllocator* page_allocator_ = internal::GetArrayBufferPageAllocator();
411   const size_t page_size_ = page_allocator_->AllocatePageSize();
412 };
413 
414 #else
415 
416 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
417  public:
418   void* Allocate(size_t length) override {
419 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
420     // Work around for GCC bug on AIX
421     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
422     void* data = __linux_calloc(length, 1);
423 #else
424     void* data = base::Calloc(length, 1);
425 #endif
426     return data;
427   }
428 
429   void* AllocateUninitialized(size_t length) override {
430 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
431     // Work around for GCC bug on AIX
432     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
433     void* data = __linux_malloc(length);
434 #else
435     void* data = base::Malloc(length);
436 #endif
437     return data;
438   }
439 
440   void Free(void* data, size_t) override { base::Free(data); }
441 
442   void* Reallocate(void* data, size_t old_length, size_t new_length) override {
443 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
444     // Work around for GCC bug on AIX
445     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
446     void* new_data = __linux_realloc(data, new_length);
447 #else
448     void* new_data = base::Realloc(data, new_length);
449 #endif
450     if (new_length > old_length) {
451       memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0,
452              new_length - old_length);
453     }
454     return new_data;
455   }
456 };
457 #endif  // V8_VIRTUAL_MEMORY_CAGE
458 
459 struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anon68be8ea50111::SnapshotCreatorData460   explicit SnapshotCreatorData(Isolate* isolate)
461       : isolate_(isolate),
462         default_context_(),
463         contexts_(isolate),
464         created_(false) {}
465 
castv8::__anon68be8ea50111::SnapshotCreatorData466   static SnapshotCreatorData* cast(void* data) {
467     return reinterpret_cast<SnapshotCreatorData*>(data);
468   }
469 
470   ArrayBufferAllocator allocator_;
471   Isolate* isolate_;
472   Persistent<Context> default_context_;
473   SerializeInternalFieldsCallback default_embedder_fields_serializer_;
474   PersistentValueVector<Context> contexts_;
475   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
476   bool created_;
477 };
478 
479 }  // namespace
480 
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)481 SnapshotCreator::SnapshotCreator(Isolate* isolate,
482                                  const intptr_t* external_references,
483                                  StartupData* existing_snapshot) {
484   SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
485   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
486   internal_isolate->set_array_buffer_allocator(&data->allocator_);
487   internal_isolate->set_api_external_references(external_references);
488   internal_isolate->enable_serializer();
489   isolate->Enter();
490   const StartupData* blob = existing_snapshot
491                                 ? existing_snapshot
492                                 : i::Snapshot::DefaultSnapshotBlob();
493   if (blob && blob->raw_size > 0) {
494     internal_isolate->set_snapshot_blob(blob);
495     i::Snapshot::Initialize(internal_isolate);
496   } else {
497     internal_isolate->InitWithoutSnapshot();
498   }
499   data_ = data;
500   // Disable batch compilation during snapshot creation.
501   internal_isolate->baseline_batch_compiler()->set_enabled(false);
502 }
503 
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)504 SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
505                                  StartupData* existing_snapshot)
506     : SnapshotCreator(Isolate::Allocate(), external_references,
507                       existing_snapshot) {}
508 
~SnapshotCreator()509 SnapshotCreator::~SnapshotCreator() {
510   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
511   DCHECK(data->created_);
512   Isolate* isolate = data->isolate_;
513   isolate->Exit();
514   isolate->Dispose();
515   delete data;
516 }
517 
GetIsolate()518 Isolate* SnapshotCreator::GetIsolate() {
519   return SnapshotCreatorData::cast(data_)->isolate_;
520 }
521 
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)522 void SnapshotCreator::SetDefaultContext(
523     Local<Context> context, SerializeInternalFieldsCallback callback) {
524   DCHECK(!context.IsEmpty());
525   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
526   DCHECK(!data->created_);
527   DCHECK(data->default_context_.IsEmpty());
528   Isolate* isolate = data->isolate_;
529   CHECK_EQ(isolate, context->GetIsolate());
530   data->default_context_.Reset(isolate, context);
531   data->default_embedder_fields_serializer_ = callback;
532 }
533 
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)534 size_t SnapshotCreator::AddContext(Local<Context> context,
535                                    SerializeInternalFieldsCallback callback) {
536   DCHECK(!context.IsEmpty());
537   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
538   DCHECK(!data->created_);
539   Isolate* isolate = data->isolate_;
540   CHECK_EQ(isolate, context->GetIsolate());
541   size_t index = data->contexts_.Size();
542   data->contexts_.Append(context);
543   data->embedder_fields_serializers_.push_back(callback);
544   return index;
545 }
546 
AddData(i::Address object)547 size_t SnapshotCreator::AddData(i::Address object) {
548   DCHECK_NE(object, i::kNullAddress);
549   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
550   DCHECK(!data->created_);
551   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
552   i::HandleScope scope(isolate);
553   i::Handle<i::Object> obj(i::Object(object), isolate);
554   i::Handle<i::ArrayList> list;
555   if (!isolate->heap()->serialized_objects().IsArrayList()) {
556     list = i::ArrayList::New(isolate, 1);
557   } else {
558     list = i::Handle<i::ArrayList>(
559         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
560   }
561   size_t index = static_cast<size_t>(list->Length());
562   list = i::ArrayList::Add(isolate, list, obj);
563   isolate->heap()->SetSerializedObjects(*list);
564   return index;
565 }
566 
AddData(Local<Context> context,i::Address object)567 size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
568   DCHECK_NE(object, i::kNullAddress);
569   DCHECK(!SnapshotCreatorData::cast(data_)->created_);
570   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
571   i::Isolate* isolate = ctx->GetIsolate();
572   i::HandleScope scope(isolate);
573   i::Handle<i::Object> obj(i::Object(object), isolate);
574   i::Handle<i::ArrayList> list;
575   if (!ctx->serialized_objects().IsArrayList()) {
576     list = i::ArrayList::New(isolate, 1);
577   } else {
578     list = i::Handle<i::ArrayList>(
579         i::ArrayList::cast(ctx->serialized_objects()), isolate);
580   }
581   size_t index = static_cast<size_t>(list->Length());
582   list = i::ArrayList::Add(isolate, list, obj);
583   ctx->set_serialized_objects(*list);
584   return index;
585 }
586 
587 namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)588 void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
589   i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
590   i::Isolate* isolate = ctx->GetIsolate();
591   if (!ctx->serialized_objects().IsArrayList()) {
592     ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
593   } else {
594     i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
595                                  isolate);
596     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
597     ctx->set_serialized_objects(*elements);
598   }
599 }
600 
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)601 void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
602   if (!isolate->heap()->serialized_objects().IsArrayList()) {
603     isolate->heap()->SetSerializedObjects(
604         i::ReadOnlyRoots(isolate).empty_fixed_array());
605   } else {
606     i::Handle<i::ArrayList> list(
607         i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
608     i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
609     isolate->heap()->SetSerializedObjects(*elements);
610   }
611 }
612 }  // anonymous namespace
613 
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)614 StartupData SnapshotCreator::CreateBlob(
615     SnapshotCreator::FunctionCodeHandling function_code_handling) {
616   SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
617   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
618   DCHECK(!data->created_);
619   DCHECK(!data->default_context_.IsEmpty());
620 
621   const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
622   const int num_contexts = num_additional_contexts + 1;  // The default context.
623 
624   // Create and store lists of embedder-provided data needed during
625   // serialization.
626   {
627     i::HandleScope scope(isolate);
628     // Convert list of context-independent data to FixedArray.
629     ConvertSerializedObjectsToFixedArray(isolate);
630 
631     // Convert lists of context-dependent data to FixedArray.
632     ConvertSerializedObjectsToFixedArray(
633         data->default_context_.Get(data->isolate_));
634     for (int i = 0; i < num_additional_contexts; i++) {
635       ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
636     }
637 
638     // We need to store the global proxy size upfront in case we need the
639     // bootstrapper to create a global proxy before we deserialize the context.
640     i::Handle<i::FixedArray> global_proxy_sizes =
641         isolate->factory()->NewFixedArray(num_additional_contexts,
642                                           i::AllocationType::kOld);
643     for (int i = 0; i < num_additional_contexts; i++) {
644       i::Handle<i::Context> context =
645           v8::Utils::OpenHandle(*data->contexts_.Get(i));
646       global_proxy_sizes->set(i,
647                               i::Smi::FromInt(context->global_proxy().Size()));
648     }
649     isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
650   }
651 
652   // We might rehash strings and re-sort descriptors. Clear the lookup cache.
653   isolate->descriptor_lookup_cache()->Clear();
654 
655   // If we don't do this then we end up with a stray root pointing at the
656   // context even after we have disposed of the context.
657   isolate->heap()->CollectAllAvailableGarbage(
658       i::GarbageCollectionReason::kSnapshotCreator);
659   {
660     i::HandleScope scope(isolate);
661     isolate->heap()->CompactWeakArrayLists();
662   }
663 
664   i::Snapshot::ClearReconstructableDataForSerialization(
665       isolate, function_code_handling == FunctionCodeHandling::kClear);
666 
667   i::DisallowGarbageCollection no_gc_from_here_on;
668 
669   // Create a vector with all contexts and clear associated Persistent fields.
670   // Note these contexts may be dead after calling Clear(), but will not be
671   // collected until serialization completes and the DisallowGarbageCollection
672   // scope above goes out of scope.
673   std::vector<i::Context> contexts;
674   contexts.reserve(num_contexts);
675   {
676     i::HandleScope scope(isolate);
677     contexts.push_back(
678         *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
679     data->default_context_.Reset();
680     for (int i = 0; i < num_additional_contexts; i++) {
681       i::Handle<i::Context> context =
682           v8::Utils::OpenHandle(*data->contexts_.Get(i));
683       contexts.push_back(*context);
684     }
685     data->contexts_.Clear();
686   }
687 
688   // Check that values referenced by global/eternal handles are accounted for.
689   i::SerializedHandleChecker handle_checker(isolate, &contexts);
690   CHECK(handle_checker.CheckGlobalAndEternalHandles());
691 
692   // Create a vector with all embedder fields serializers.
693   std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
694   embedder_fields_serializers.reserve(num_contexts);
695   embedder_fields_serializers.push_back(
696       data->default_embedder_fields_serializer_);
697   for (int i = 0; i < num_additional_contexts; i++) {
698     embedder_fields_serializers.push_back(
699         data->embedder_fields_serializers_[i]);
700   }
701 
702   data->created_ = true;
703   return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
704                              no_gc_from_here_on);
705 }
706 
CanBeRehashed() const707 bool StartupData::CanBeRehashed() const {
708   DCHECK(i::Snapshot::VerifyChecksum(this));
709   return i::Snapshot::ExtractRehashability(this);
710 }
711 
IsValid() const712 bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
713 
SetDcheckErrorHandler(DcheckErrorCallback that)714 void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
715   v8::base::SetDcheckFunction(that);
716 }
717 
SetFlagsFromString(const char * str)718 void V8::SetFlagsFromString(const char* str) {
719   SetFlagsFromString(str, strlen(str));
720 }
721 
SetFlagsFromString(const char * str,size_t length)722 void V8::SetFlagsFromString(const char* str, size_t length) {
723   i::FlagList::SetFlagsFromString(str, length);
724   i::FlagList::EnforceFlagImplications();
725 }
726 
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)727 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
728   using HelpOptions = i::FlagList::HelpOptions;
729   i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
730                                        HelpOptions(HelpOptions::kDontExit));
731 }
732 
733 RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
734 
RegisteredExtension(std::unique_ptr<Extension> extension)735 RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
736     : extension_(std::move(extension)) {}
737 
738 // static
Register(std::unique_ptr<Extension> extension)739 void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
740   RegisteredExtension* new_extension =
741       new RegisteredExtension(std::move(extension));
742   new_extension->next_ = first_extension_;
743   first_extension_ = new_extension;
744 }
745 
746 // static
UnregisterAll()747 void RegisteredExtension::UnregisterAll() {
748   RegisteredExtension* re = first_extension_;
749   while (re != nullptr) {
750     RegisteredExtension* next = re->next();
751     delete re;
752     re = next;
753   }
754   first_extension_ = nullptr;
755 }
756 
757 namespace {
758 class ExtensionResource : public String::ExternalOneByteStringResource {
759  public:
ExtensionResource()760   ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)761   ExtensionResource(const char* data, size_t length)
762       : data_(data), length_(length) {}
data() const763   const char* data() const override { return data_; }
length() const764   size_t length() const override { return length_; }
Dispose()765   void Dispose() override {}
766 
767  private:
768   const char* data_;
769   size_t length_;
770 };
771 }  // anonymous namespace
772 
RegisterExtension(std::unique_ptr<Extension> extension)773 void RegisterExtension(std::unique_ptr<Extension> extension) {
774   RegisteredExtension::Register(std::move(extension));
775 }
776 
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)777 Extension::Extension(const char* name, const char* source, int dep_count,
778                      const char** deps, int source_length)
779     : name_(name),
780       source_length_(source_length >= 0
781                          ? source_length
782                          : (source ? static_cast<int>(strlen(source)) : 0)),
783       dep_count_(dep_count),
784       deps_(deps),
785       auto_enable_(false) {
786   source_ = new ExtensionResource(source, source_length_);
787   CHECK(source != nullptr || source_length_ == 0);
788 }
789 
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)790 void ResourceConstraints::ConfigureDefaultsFromHeapSize(
791     size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
792   CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
793   if (maximum_heap_size_in_bytes == 0) {
794     return;
795   }
796   size_t young_generation, old_generation;
797   i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
798                                        &young_generation, &old_generation);
799   set_max_young_generation_size_in_bytes(
800       std::max(young_generation, i::Heap::MinYoungGenerationSize()));
801   set_max_old_generation_size_in_bytes(
802       std::max(old_generation, i::Heap::MinOldGenerationSize()));
803   if (initial_heap_size_in_bytes > 0) {
804     i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
805                                          &young_generation, &old_generation);
806     // We do not set lower bounds for the initial sizes.
807     set_initial_young_generation_size_in_bytes(young_generation);
808     set_initial_old_generation_size_in_bytes(old_generation);
809   }
810   if (i::kPlatformRequiresCodeRange) {
811     set_code_range_size_in_bytes(
812         std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
813   }
814 }
815 
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)816 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
817                                             uint64_t virtual_memory_limit) {
818   size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
819   size_t young_generation, old_generation;
820   i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
821                                        &old_generation);
822   set_max_young_generation_size_in_bytes(young_generation);
823   set_max_old_generation_size_in_bytes(old_generation);
824 
825   if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
826     set_code_range_size_in_bytes(
827         std::min(i::kMaximalCodeRangeSize,
828                  static_cast<size_t>(virtual_memory_limit / 8)));
829   }
830 }
831 
832 namespace api_internal {
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,bool has_destructor)833 i::Address* GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
834                                      internal::Address* slot,
835                                      bool has_destructor) {
836   LOG_API(isolate, TracedGlobal, New);
837 #ifdef DEBUG
838   Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
839                   "the address slot must be not null");
840 #endif
841   i::Handle<i::Object> result =
842       isolate->global_handles()->CreateTraced(*obj, slot, has_destructor);
843 #ifdef VERIFY_HEAP
844   if (i::FLAG_verify_heap) {
845     i::Object(*obj).ObjectVerify(isolate);
846   }
847 #endif  // VERIFY_HEAP
848   return result.location();
849 }
850 
GlobalizeReference(i::Isolate * isolate,i::Address * obj)851 i::Address* GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
852   LOG_API(isolate, Persistent, New);
853   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
854 #ifdef VERIFY_HEAP
855   if (i::FLAG_verify_heap) {
856     i::Object(*obj).ObjectVerify(isolate);
857   }
858 #endif  // VERIFY_HEAP
859   return result.location();
860 }
861 
CopyGlobalReference(i::Address * from)862 i::Address* CopyGlobalReference(i::Address* from) {
863   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
864   return result.location();
865 }
866 
MoveGlobalReference(internal::Address ** from,internal::Address ** to)867 void MoveGlobalReference(internal::Address** from, internal::Address** to) {
868   i::GlobalHandles::MoveGlobal(from, to);
869 }
870 
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)871 void MakeWeak(i::Address* location, void* parameter,
872               WeakCallbackInfo<void>::Callback weak_callback,
873               WeakCallbackType type) {
874   i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
875 }
876 
MakeWeak(i::Address ** location_addr)877 void MakeWeak(i::Address** location_addr) {
878   i::GlobalHandles::MakeWeak(location_addr);
879 }
880 
ClearWeak(i::Address * location)881 void* ClearWeak(i::Address* location) {
882   return i::GlobalHandles::ClearWeakness(location);
883 }
884 
AnnotateStrongRetainer(i::Address * location,const char * label)885 void AnnotateStrongRetainer(i::Address* location, const char* label) {
886   i::GlobalHandles::AnnotateStrongRetainer(location, label);
887 }
888 
DisposeGlobal(i::Address * location)889 void DisposeGlobal(i::Address* location) {
890   i::GlobalHandles::Destroy(location);
891 }
892 
Eternalize(Isolate * v8_isolate,Value * value)893 Value* Eternalize(Isolate* v8_isolate, Value* value) {
894   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
895   i::Object object = *Utils::OpenHandle(value);
896   int index = -1;
897   isolate->eternal_handles()->Create(isolate, object, &index);
898   return reinterpret_cast<Value*>(
899       isolate->eternal_handles()->Get(index).location());
900 }
901 
MoveTracedGlobalReference(internal::Address ** from,internal::Address ** to)902 void MoveTracedGlobalReference(internal::Address** from,
903                                internal::Address** to) {
904   i::GlobalHandles::MoveTracedGlobal(from, to);
905 }
906 
CopyTracedGlobalReference(const internal::Address * const * from,internal::Address ** to)907 void CopyTracedGlobalReference(const internal::Address* const* from,
908                                internal::Address** to) {
909   i::GlobalHandles::CopyTracedGlobal(from, to);
910 }
911 
DisposeTracedGlobal(internal::Address * location)912 void DisposeTracedGlobal(internal::Address* location) {
913   i::GlobalHandles::DestroyTraced(location);
914 }
915 
SetFinalizationCallbackTraced(internal::Address * location,void * parameter,WeakCallbackInfo<void>::Callback callback)916 void SetFinalizationCallbackTraced(internal::Address* location, void* parameter,
917                                    WeakCallbackInfo<void>::Callback callback) {
918   i::GlobalHandles::SetFinalizationCallbackForTraced(location, parameter,
919                                                      callback);
920 }
921 
FromJustIsNothing()922 void FromJustIsNothing() {
923   Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
924 }
925 
ToLocalEmpty()926 void ToLocalEmpty() {
927   Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
928 }
929 
InternalFieldOutOfBounds(int index)930 void InternalFieldOutOfBounds(int index) {
931   Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
932                   "WeakCallbackInfo::GetInternalField",
933                   "Internal field out of bounds.");
934 }
935 
936 }  // namespace api_internal
937 
938 // --- H a n d l e s ---
939 
HandleScope(Isolate * isolate)940 HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
941 
Initialize(Isolate * isolate)942 void HandleScope::Initialize(Isolate* isolate) {
943   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
944   // We do not want to check the correct usage of the Locker class all over the
945   // place, so we do it only here: Without a HandleScope, an embedder can do
946   // almost nothing, so it is enough to check in this central place.
947   // We make an exception if the serializer is enabled, which means that the
948   // Isolate is exclusively used to create a snapshot.
949   Utils::ApiCheck(
950       !v8::Locker::WasEverUsed() ||
951           internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
952           internal_isolate->serializer_enabled(),
953       "HandleScope::HandleScope",
954       "Entering the V8 API without proper locking in place");
955   i::HandleScopeData* current = internal_isolate->handle_scope_data();
956   isolate_ = internal_isolate;
957   prev_next_ = current->next;
958   prev_limit_ = current->limit;
959   current->level++;
960 }
961 
~HandleScope()962 HandleScope::~HandleScope() {
963   i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
964 }
965 
operator new(size_t)966 void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)967 void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)968 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)969 void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
970 
NumberOfHandles(Isolate * isolate)971 int HandleScope::NumberOfHandles(Isolate* isolate) {
972   return i::HandleScope::NumberOfHandles(
973       reinterpret_cast<i::Isolate*>(isolate));
974 }
975 
CreateHandle(i::Isolate * isolate,i::Address value)976 i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
977   return i::HandleScope::CreateHandle(isolate, value);
978 }
979 
EscapableHandleScope(Isolate * v8_isolate)980 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
981   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
982   escape_slot_ =
983       CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
984   Initialize(v8_isolate);
985 }
986 
Escape(i::Address * escape_value)987 i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
988   i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
989   Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
990                   "EscapableHandleScope::Escape", "Escape value set twice");
991   if (escape_value == nullptr) {
992     *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
993     return nullptr;
994   }
995   *escape_slot_ = *escape_value;
996   return escape_slot_;
997 }
998 
operator new(size_t)999 void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1000 void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1001 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1002 void EscapableHandleScope::operator delete[](void*, size_t) {
1003   base::OS::Abort();
1004 }
1005 
SealHandleScope(Isolate * isolate)1006 SealHandleScope::SealHandleScope(Isolate* isolate)
1007     : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
1008   i::HandleScopeData* current = isolate_->handle_scope_data();
1009   prev_limit_ = current->limit;
1010   current->limit = current->next;
1011   prev_sealed_level_ = current->sealed_level;
1012   current->sealed_level = current->level;
1013 }
1014 
~SealHandleScope()1015 SealHandleScope::~SealHandleScope() {
1016   i::HandleScopeData* current = isolate_->handle_scope_data();
1017   DCHECK_EQ(current->next, current->limit);
1018   current->limit = prev_limit_;
1019   DCHECK_EQ(current->level, current->sealed_level);
1020   current->sealed_level = prev_sealed_level_;
1021 }
1022 
operator new(size_t)1023 void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1024 void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1025 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1026 void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1027 
IsModule() const1028 bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
1029 
IsValue() const1030 bool Data::IsValue() const {
1031   i::DisallowGarbageCollection no_gc;
1032   i::Object self = *Utils::OpenHandle(this);
1033   if (self.IsSmi()) return true;
1034   i::HeapObject heap_object = i::HeapObject::cast(self);
1035   DCHECK(!heap_object.IsTheHole());
1036   if (heap_object.IsSymbol()) {
1037     return !i::Symbol::cast(heap_object).is_private();
1038   }
1039   return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1040 }
1041 
IsPrivate() const1042 bool Data::IsPrivate() const {
1043   return Utils::OpenHandle(this)->IsPrivateSymbol();
1044 }
1045 
IsObjectTemplate() const1046 bool Data::IsObjectTemplate() const {
1047   return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1048 }
1049 
IsFunctionTemplate() const1050 bool Data::IsFunctionTemplate() const {
1051   return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1052 }
1053 
IsContext() const1054 bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1055 
Enter()1056 void Context::Enter() {
1057   i::Handle<i::Context> env = Utils::OpenHandle(this);
1058   i::Isolate* isolate = env->GetIsolate();
1059   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1060   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1061   impl->EnterContext(*env);
1062   impl->SaveContext(isolate->context());
1063   isolate->set_context(*env);
1064 }
1065 
Exit()1066 void Context::Exit() {
1067   i::Handle<i::Context> env = Utils::OpenHandle(this);
1068   i::Isolate* isolate = env->GetIsolate();
1069   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1070   i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1071   if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1072                        "Cannot exit non-entered context")) {
1073     return;
1074   }
1075   impl->LeaveContext();
1076   isolate->set_context(impl->RestoreContext());
1077 }
1078 
BackupIncumbentScope(Local<Context> backup_incumbent_context)1079 Context::BackupIncumbentScope::BackupIncumbentScope(
1080     Local<Context> backup_incumbent_context)
1081     : backup_incumbent_context_(backup_incumbent_context) {
1082   DCHECK(!backup_incumbent_context_.IsEmpty());
1083 
1084   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1085   i::Isolate* isolate = env->GetIsolate();
1086 
1087   js_stack_comparable_address_ =
1088       i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1089 
1090   prev_ = isolate->top_backup_incumbent_scope();
1091   isolate->set_top_backup_incumbent_scope(this);
1092 }
1093 
~BackupIncumbentScope()1094 Context::BackupIncumbentScope::~BackupIncumbentScope() {
1095   i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1096   i::Isolate* isolate = env->GetIsolate();
1097 
1098   i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1099 
1100   isolate->set_top_backup_incumbent_scope(prev_);
1101 }
1102 
1103 STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1104 
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1105 static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1106                                                        int index, bool can_grow,
1107                                                        const char* location) {
1108   i::Handle<i::Context> env = Utils::OpenHandle(context);
1109   i::Isolate* isolate = env->GetIsolate();
1110   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
1111   bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1112                             "Not a native context") &&
1113             Utils::ApiCheck(index >= 0, location, "Negative index");
1114   if (!ok) return i::Handle<i::EmbedderDataArray>();
1115   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1116   i::Handle<i::EmbedderDataArray> data(
1117       i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1118   if (index < data->length()) return data;
1119   if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1120                        location, "Index too large")) {
1121     return i::Handle<i::EmbedderDataArray>();
1122   }
1123   data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1124   env->set_embedder_data(*data);
1125   return data;
1126 }
1127 
GetNumberOfEmbedderDataFields()1128 uint32_t Context::GetNumberOfEmbedderDataFields() {
1129   i::Handle<i::Context> context = Utils::OpenHandle(this);
1130   ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate());
1131   Utils::ApiCheck(context->IsNativeContext(),
1132                   "Context::GetNumberOfEmbedderDataFields",
1133                   "Not a native context");
1134   // TODO(ishell): remove cast once embedder_data slot has a proper type.
1135   return static_cast<uint32_t>(
1136       i::EmbedderDataArray::cast(context->embedder_data()).length());
1137 }
1138 
SlowGetEmbedderData(int index)1139 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1140   const char* location = "v8::Context::GetEmbedderData()";
1141   i::Handle<i::EmbedderDataArray> data =
1142       EmbedderDataFor(this, index, false, location);
1143   if (data.is_null()) return Local<Value>();
1144   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1145   i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1146                               isolate);
1147   return Utils::ToLocal(result);
1148 }
1149 
SetEmbedderData(int index,v8::Local<Value> value)1150 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1151   const char* location = "v8::Context::SetEmbedderData()";
1152   i::Handle<i::EmbedderDataArray> data =
1153       EmbedderDataFor(this, index, true, location);
1154   if (data.is_null()) return;
1155   i::Handle<i::Object> val = Utils::OpenHandle(*value);
1156   i::EmbedderDataSlot::store_tagged(*data, index, *val);
1157   DCHECK_EQ(*Utils::OpenHandle(*value),
1158             *Utils::OpenHandle(*GetEmbedderData(index)));
1159 }
1160 
SlowGetAlignedPointerFromEmbedderData(int index)1161 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1162   const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1163   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1164   i::HandleScope handle_scope(isolate);
1165   i::Handle<i::EmbedderDataArray> data =
1166       EmbedderDataFor(this, index, false, location);
1167   if (data.is_null()) return nullptr;
1168   void* result;
1169   Utils::ApiCheck(
1170       i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1171       location, "Pointer is not aligned");
1172   return result;
1173 }
1174 
SetAlignedPointerInEmbedderData(int index,void * value)1175 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1176   const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1177   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1178   i::Handle<i::EmbedderDataArray> data =
1179       EmbedderDataFor(this, index, true, location);
1180   bool ok =
1181       i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1182   Utils::ApiCheck(ok, location, "Pointer is not aligned");
1183   DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1184 }
1185 
1186 // --- T e m p l a t e ---
1187 
InitializeTemplate(i::TemplateInfo that,int type,bool do_not_cache)1188 static void InitializeTemplate(i::TemplateInfo that, int type,
1189                                bool do_not_cache) {
1190   that.set_number_of_properties(0);
1191   that.set_tag(type);
1192   int serial_number =
1193       do_not_cache ? i::TemplateInfo::kDoNotCache : i::TemplateInfo::kUncached;
1194   that.set_serial_number(serial_number);
1195 }
1196 
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1197 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1198                    v8::PropertyAttribute attribute) {
1199   auto templ = Utils::OpenHandle(this);
1200   i::Isolate* isolate = templ->GetIsolate();
1201   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1202   i::HandleScope scope(isolate);
1203   auto value_obj = Utils::OpenHandle(*value);
1204 
1205   Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(),
1206                   "v8::Template::Set",
1207                   "Invalid value, must be a primitive or a Template");
1208 
1209   // The template cache only performs shallow clones, if we set an
1210   // ObjectTemplate as a property value then we can not cache the receiver
1211   // template.
1212   if (value_obj->IsObjectTemplateInfo()) {
1213     templ->set_serial_number(i::TemplateInfo::kDoNotCache);
1214   }
1215 
1216   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1217                                  value_obj,
1218                                  static_cast<i::PropertyAttributes>(attribute));
1219 }
1220 
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1221 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1222                           v8::PropertyAttribute attribute) {
1223   Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1224       attribute);
1225 }
1226 
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1227 void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1228                                    v8::Local<FunctionTemplate> getter,
1229                                    v8::Local<FunctionTemplate> setter,
1230                                    v8::PropertyAttribute attribute,
1231                                    v8::AccessControl access_control) {
1232   // TODO(verwaest): Remove |access_control|.
1233   DCHECK_EQ(v8::DEFAULT, access_control);
1234   auto templ = Utils::OpenHandle(this);
1235   auto isolate = templ->GetIsolate();
1236   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1237   DCHECK(!name.IsEmpty());
1238   DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1239   i::HandleScope scope(isolate);
1240   i::ApiNatives::AddAccessorProperty(
1241       isolate, templ, Utils::OpenHandle(*name),
1242       Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1243       static_cast<i::PropertyAttributes>(attribute));
1244 }
1245 
1246 // --- F u n c t i o n   T e m p l a t e ---
InitializeFunctionTemplate(i::FunctionTemplateInfo info,bool do_not_cache)1247 static void InitializeFunctionTemplate(i::FunctionTemplateInfo info,
1248                                        bool do_not_cache) {
1249   InitializeTemplate(info, Consts::FUNCTION_TEMPLATE, do_not_cache);
1250   info.set_flag(0);
1251 }
1252 
1253 static Local<ObjectTemplate> ObjectTemplateNew(
1254     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1255     bool do_not_cache);
1256 
PrototypeTemplate()1257 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1258   auto self = Utils::OpenHandle(this);
1259   i::Isolate* i_isolate = self->GetIsolate();
1260   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1261   i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1262   if (result->IsUndefined(i_isolate)) {
1263     // Do not cache prototype objects.
1264     result = Utils::OpenHandle(
1265         *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1266     i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1267   }
1268   return ToApiHandle<ObjectTemplate>(result);
1269 }
1270 
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1271 void FunctionTemplate::SetPrototypeProviderTemplate(
1272     Local<FunctionTemplate> prototype_provider) {
1273   auto self = Utils::OpenHandle(this);
1274   i::Isolate* i_isolate = self->GetIsolate();
1275   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1276   i::Handle<i::FunctionTemplateInfo> result =
1277       Utils::OpenHandle(*prototype_provider);
1278   Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
1279                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1280                   "Protoype must be undefined");
1281   Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
1282                   "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1283                   "Prototype provider must be empty");
1284   i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1285                                                         result);
1286 }
1287 
EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,const char * func)1288 static void EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,
1289                                const char* func) {
1290   DCHECK_IMPLIES(info->instantiated(), info->published());
1291   Utils::ApiCheck(!info->published(), func,
1292                   "FunctionTemplate already instantiated");
1293 }
1294 
Inherit(v8::Local<FunctionTemplate> value)1295 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1296   auto info = Utils::OpenHandle(this);
1297   EnsureNotPublished(info, "v8::FunctionTemplate::Inherit");
1298   i::Isolate* i_isolate = info->GetIsolate();
1299   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1300   Utils::ApiCheck(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate),
1301                   "v8::FunctionTemplate::Inherit",
1302                   "Protoype provider must be empty");
1303   i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1304                                              Utils::OpenHandle(*value));
1305 }
1306 
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)1307 static Local<FunctionTemplate> FunctionTemplateNew(
1308     i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1309     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1310     bool do_not_cache,
1311     v8::Local<Private> cached_property_name = v8::Local<Private>(),
1312     SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1313     const MemorySpan<const CFunction>& c_function_overloads = {},
1314     uint8_t instance_type = 0,
1315     uint8_t allowed_receiver_instance_type_range_start = 0,
1316     uint8_t allowed_receiver_instance_type_range_end = 0) {
1317   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1318       i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1319   i::Handle<i::FunctionTemplateInfo> obj =
1320       i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1321   {
1322     // Disallow GC until all fields of obj have acceptable types.
1323     i::DisallowGarbageCollection no_gc;
1324     i::FunctionTemplateInfo raw = *obj;
1325     InitializeFunctionTemplate(raw, do_not_cache);
1326     raw.set_length(length);
1327     raw.set_undetectable(false);
1328     raw.set_needs_access_check(false);
1329     raw.set_accept_any_receiver(true);
1330     if (!signature.IsEmpty()) {
1331       raw.set_signature(*Utils::OpenHandle(*signature));
1332     }
1333     raw.set_cached_property_name(
1334         cached_property_name.IsEmpty()
1335             ? i::ReadOnlyRoots(isolate).the_hole_value()
1336             : *Utils::OpenHandle(*cached_property_name));
1337     if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
1338     raw.SetInstanceType(instance_type);
1339     raw.set_allowed_receiver_instance_type_range_start(
1340         allowed_receiver_instance_type_range_start);
1341     raw.set_allowed_receiver_instance_type_range_end(
1342         allowed_receiver_instance_type_range_end);
1343   }
1344   if (callback != nullptr) {
1345     Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1346                                         c_function_overloads);
1347   }
1348   return Utils::ToLocal(obj);
1349 }
1350 
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)1351 Local<FunctionTemplate> FunctionTemplate::New(
1352     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1353     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1354     SideEffectType side_effect_type, const CFunction* c_function,
1355     uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
1356     uint16_t allowed_receiver_instance_type_range_end) {
1357   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1358   // Changes to the environment cannot be captured in the snapshot. Expect no
1359   // function templates when the isolate is created for serialization.
1360   LOG_API(i_isolate, FunctionTemplate, New);
1361   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1362   return FunctionTemplateNew(
1363       i_isolate, callback, data, signature, length, behavior, false,
1364       Local<Private>(), side_effect_type,
1365       c_function ? MemorySpan<const CFunction>{c_function, 1}
1366                  : MemorySpan<const CFunction>{},
1367       instance_type, allowed_receiver_instance_type_range_start,
1368       allowed_receiver_instance_type_range_end);
1369 }
1370 
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)1371 Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1372     Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1373     v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1374     SideEffectType side_effect_type,
1375     const MemorySpan<const CFunction>& c_function_overloads) {
1376   // TODO(mslekova): Once runtime overload resolution between sequences is
1377   // supported, check that if (c_function_overloads.size() == 2), then
1378   // c_function_overloads.data()[0].
1379   //   CanResolveOverload(c_function_overloads.data()[1]). We won't support
1380   // the case where the size is greater than 2 for runtime resolution, until
1381   // we've added support for ArrayBuffers and ArrayBufferViews. OTOH the
1382   // overloads list might contain more than 2 functions with different arity,
1383   // the resolution between which is available at compile time.
1384 
1385   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1386   LOG_API(i_isolate, FunctionTemplate, New);
1387   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1388   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1389                              behavior, false, Local<Private>(),
1390                              side_effect_type, c_function_overloads);
1391 }
1392 
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1393 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1394     Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1395     Local<Value> data, Local<Signature> signature, int length,
1396     SideEffectType side_effect_type) {
1397   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1398   LOG_API(i_isolate, FunctionTemplate, NewWithCache);
1399   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1400   return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1401                              ConstructorBehavior::kAllow, false, cache_property,
1402                              side_effect_type);
1403 }
1404 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1405 Local<Signature> Signature::New(Isolate* isolate,
1406                                 Local<FunctionTemplate> receiver) {
1407   return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1408 }
1409 
New(Isolate * isolate,Local<FunctionTemplate> receiver)1410 Local<AccessorSignature> AccessorSignature::New(
1411     Isolate* isolate, Local<FunctionTemplate> receiver) {
1412   return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1413 }
1414 
1415 #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata)        \
1416   do {                                                        \
1417     i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1418     (obj)->setter(*foreign);                                  \
1419   } while (false)
1420 
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1421 void FunctionTemplate::SetCallHandler(
1422     FunctionCallback callback, v8::Local<Value> data,
1423     SideEffectType side_effect_type,
1424     const MemorySpan<const CFunction>& c_function_overloads) {
1425   auto info = Utils::OpenHandle(this);
1426   EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
1427   i::Isolate* isolate = info->GetIsolate();
1428   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1429   i::HandleScope scope(isolate);
1430   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1431       side_effect_type == SideEffectType::kHasNoSideEffect);
1432   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1433   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1434   if (data.IsEmpty()) {
1435     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1436   }
1437   obj->set_data(*Utils::OpenHandle(*data));
1438   if (c_function_overloads.size() > 0) {
1439     // Stores the data for a sequence of CFunction overloads into a single
1440     // FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
1441     i::Handle<i::FixedArray> function_overloads =
1442         isolate->factory()->NewFixedArray(static_cast<int>(
1443             c_function_overloads.size() *
1444             i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
1445     int function_count = static_cast<int>(c_function_overloads.size());
1446     for (int i = 0; i < function_count; i++) {
1447       const CFunction& c_function = c_function_overloads.data()[i];
1448       i::Handle<i::Object> address =
1449           FromCData(isolate, c_function.GetAddress());
1450       function_overloads->set(
1451           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
1452       i::Handle<i::Object> signature =
1453           FromCData(isolate, c_function.GetTypeInfo());
1454       function_overloads->set(
1455           i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
1456           *signature);
1457     }
1458     i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
1459                                                    function_overloads);
1460   }
1461   info->set_call_code(*obj, kReleaseStore);
1462 }
1463 
1464 namespace {
1465 
1466 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)1467 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1468     i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1469     v8::Local<Value> data, v8::AccessControl settings,
1470     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1471     bool replace_on_access) {
1472   i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1473   SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1474   DCHECK_IMPLIES(replace_on_access,
1475                  is_special_data_property && setter == nullptr);
1476   if (is_special_data_property && setter == nullptr) {
1477     setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1478   }
1479   SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1480   i::Address redirected = obj->redirected_getter();
1481   if (redirected != i::kNullAddress) {
1482     SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1483   }
1484   if (data.IsEmpty()) {
1485     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1486   }
1487   obj->set_data(*Utils::OpenHandle(*data));
1488   obj->set_is_special_data_property(is_special_data_property);
1489   obj->set_replace_on_access(replace_on_access);
1490   i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1491   if (!accessor_name->IsUniqueName()) {
1492     accessor_name = isolate->factory()->InternalizeString(
1493         i::Handle<i::String>::cast(accessor_name));
1494   }
1495   obj->set_name(*accessor_name);
1496   if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1497   if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1498   obj->set_initial_property_attributes(i::NONE);
1499   if (!signature.IsEmpty()) {
1500     obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1501   }
1502   return obj;
1503 }
1504 
1505 }  // namespace
1506 
InstanceTemplate()1507 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1508   i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1509   if (!Utils::ApiCheck(!handle.is_null(),
1510                        "v8::FunctionTemplate::InstanceTemplate()",
1511                        "Reading from empty handle")) {
1512     return Local<ObjectTemplate>();
1513   }
1514   i::Isolate* isolate = handle->GetIsolate();
1515   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1516   if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1517     Local<ObjectTemplate> templ =
1518         ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1519     i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1520                                                  Utils::OpenHandle(*templ));
1521   }
1522   i::Handle<i::ObjectTemplateInfo> result(
1523       i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1524   return Utils::ToLocal(result);
1525 }
1526 
SetLength(int length)1527 void FunctionTemplate::SetLength(int length) {
1528   auto info = Utils::OpenHandle(this);
1529   EnsureNotPublished(info, "v8::FunctionTemplate::SetLength");
1530   auto isolate = info->GetIsolate();
1531   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1532   info->set_length(length);
1533 }
1534 
SetClassName(Local<String> name)1535 void FunctionTemplate::SetClassName(Local<String> name) {
1536   auto info = Utils::OpenHandle(this);
1537   EnsureNotPublished(info, "v8::FunctionTemplate::SetClassName");
1538   auto isolate = info->GetIsolate();
1539   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1540   info->set_class_name(*Utils::OpenHandle(*name));
1541 }
1542 
SetAcceptAnyReceiver(bool value)1543 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1544   auto info = Utils::OpenHandle(this);
1545   EnsureNotPublished(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1546   auto isolate = info->GetIsolate();
1547   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548   info->set_accept_any_receiver(value);
1549 }
1550 
ReadOnlyPrototype()1551 void FunctionTemplate::ReadOnlyPrototype() {
1552   auto info = Utils::OpenHandle(this);
1553   EnsureNotPublished(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1554   auto isolate = info->GetIsolate();
1555   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1556   info->set_read_only_prototype(true);
1557 }
1558 
RemovePrototype()1559 void FunctionTemplate::RemovePrototype() {
1560   auto info = Utils::OpenHandle(this);
1561   EnsureNotPublished(info, "v8::FunctionTemplate::RemovePrototype");
1562   auto isolate = info->GetIsolate();
1563   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1564   info->set_remove_prototype(true);
1565 }
1566 
1567 // --- O b j e c t T e m p l a t e ---
1568 
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1569 Local<ObjectTemplate> ObjectTemplate::New(
1570     Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1571   return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1572 }
1573 
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1574 static Local<ObjectTemplate> ObjectTemplateNew(
1575     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1576     bool do_not_cache) {
1577   LOG_API(isolate, ObjectTemplate, New);
1578   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1579   i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1580       i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1581   i::Handle<i::ObjectTemplateInfo> obj =
1582       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1583   {
1584     // Disallow GC until all fields of obj have acceptable types.
1585     i::DisallowGarbageCollection no_gc;
1586     i::ObjectTemplateInfo raw = *obj;
1587     InitializeTemplate(raw, Consts::OBJECT_TEMPLATE, do_not_cache);
1588     raw.set_data(0);
1589     if (!constructor.IsEmpty()) {
1590       raw.set_constructor(*Utils::OpenHandle(*constructor));
1591     }
1592   }
1593   return Utils::ToLocal(obj);
1594 }
1595 
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1596 Local<ObjectTemplate> ObjectTemplate::New(
1597     i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1598   return ObjectTemplateNew(isolate, constructor, false);
1599 }
1600 
1601 // Ensure that the object template has a constructor.  If no
1602 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1603 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1604     i::Isolate* isolate, ObjectTemplate* object_template) {
1605   i::Object obj = Utils::OpenHandle(object_template)->constructor();
1606   if (!obj.IsUndefined(isolate)) {
1607     i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1608     return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1609   }
1610   Local<FunctionTemplate> templ =
1611       FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1612   i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1613   i::FunctionTemplateInfo::SetInstanceTemplate(
1614       isolate, constructor, Utils::OpenHandle(object_template));
1615   Utils::OpenHandle(object_template)->set_constructor(*constructor);
1616   return constructor;
1617 }
1618 
1619 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)1620 static void TemplateSetAccessor(
1621     Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1622     Data data, AccessControl settings, PropertyAttribute attribute,
1623     v8::Local<AccessorSignature> signature, bool is_special_data_property,
1624     bool replace_on_access, SideEffectType getter_side_effect_type,
1625     SideEffectType setter_side_effect_type) {
1626   auto info = Utils::OpenHandle(template_obj);
1627   auto isolate = info->GetIsolate();
1628   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1629   i::HandleScope scope(isolate);
1630   i::Handle<i::AccessorInfo> accessor_info =
1631       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1632                        is_special_data_property, replace_on_access);
1633   accessor_info->set_initial_property_attributes(
1634       static_cast<i::PropertyAttributes>(attribute));
1635   accessor_info->set_getter_side_effect_type(getter_side_effect_type);
1636   accessor_info->set_setter_side_effect_type(setter_side_effect_type);
1637   i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1638 }
1639 
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)1640 void Template::SetNativeDataProperty(
1641     v8::Local<String> name, AccessorGetterCallback getter,
1642     AccessorSetterCallback setter, v8::Local<Value> data,
1643     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1644     AccessControl settings, SideEffectType getter_side_effect_type,
1645     SideEffectType setter_side_effect_type) {
1646   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1647                       signature, true, false, getter_side_effect_type,
1648                       setter_side_effect_type);
1649 }
1650 
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)1651 void Template::SetNativeDataProperty(
1652     v8::Local<Name> name, AccessorNameGetterCallback getter,
1653     AccessorNameSetterCallback setter, v8::Local<Value> data,
1654     PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1655     AccessControl settings, SideEffectType getter_side_effect_type,
1656     SideEffectType setter_side_effect_type) {
1657   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1658                       signature, true, false, getter_side_effect_type,
1659                       setter_side_effect_type);
1660 }
1661 
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1662 void Template::SetLazyDataProperty(v8::Local<Name> name,
1663                                    AccessorNameGetterCallback getter,
1664                                    v8::Local<Value> data,
1665                                    PropertyAttribute attribute,
1666                                    SideEffectType getter_side_effect_type,
1667                                    SideEffectType setter_side_effect_type) {
1668   TemplateSetAccessor(this, name, getter,
1669                       static_cast<AccessorNameSetterCallback>(nullptr), data,
1670                       DEFAULT, attribute, Local<AccessorSignature>(), true,
1671                       true, getter_side_effect_type, setter_side_effect_type);
1672 }
1673 
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1674 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1675                                         PropertyAttribute attribute) {
1676   auto templ = Utils::OpenHandle(this);
1677   i::Isolate* isolate = templ->GetIsolate();
1678   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1679   i::HandleScope scope(isolate);
1680   i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1681                                  intrinsic,
1682                                  static_cast<i::PropertyAttributes>(attribute));
1683 }
1684 
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)1685 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1686                                  AccessorGetterCallback getter,
1687                                  AccessorSetterCallback setter,
1688                                  v8::Local<Value> data, AccessControl settings,
1689                                  PropertyAttribute attribute,
1690                                  v8::Local<AccessorSignature> signature,
1691                                  SideEffectType getter_side_effect_type,
1692                                  SideEffectType setter_side_effect_type) {
1693   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1694                       signature, i::FLAG_disable_old_api_accessors, false,
1695                       getter_side_effect_type, setter_side_effect_type);
1696 }
1697 
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)1698 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1699                                  AccessorNameGetterCallback getter,
1700                                  AccessorNameSetterCallback setter,
1701                                  v8::Local<Value> data, AccessControl settings,
1702                                  PropertyAttribute attribute,
1703                                  v8::Local<AccessorSignature> signature,
1704                                  SideEffectType getter_side_effect_type,
1705                                  SideEffectType setter_side_effect_type) {
1706   TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1707                       signature, i::FLAG_disable_old_api_accessors, false,
1708                       getter_side_effect_type, setter_side_effect_type);
1709 }
1710 
1711 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1712           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)1713 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1714     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1715     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1716     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1717   auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1718       i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1719   obj->set_flags(0);
1720 
1721   if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1722   if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1723   if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1724   if (descriptor != nullptr)
1725     SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1726   if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1727   if (enumerator != nullptr)
1728     SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1729   if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1730   obj->set_can_intercept_symbols(
1731       !(static_cast<int>(flags) &
1732         static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1733   obj->set_all_can_read(static_cast<int>(flags) &
1734                         static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1735   obj->set_non_masking(static_cast<int>(flags) &
1736                        static_cast<int>(PropertyHandlerFlags::kNonMasking));
1737   obj->set_has_no_side_effect(
1738       static_cast<int>(flags) &
1739       static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1740 
1741   if (data.IsEmpty()) {
1742     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1743   }
1744   obj->set_data(*Utils::OpenHandle(*data));
1745   return obj;
1746 }
1747 
1748 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1749           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)1750 static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1751     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1752     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1753     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1754   auto interceptor =
1755       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1756                             enumerator, definer, data, flags);
1757   interceptor->set_is_named(true);
1758   return interceptor;
1759 }
1760 
1761 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1762           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)1763 static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1764     i::Isolate* isolate, Getter getter, Setter setter, Query query,
1765     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1766     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1767   auto interceptor =
1768       CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1769                             enumerator, definer, data, flags);
1770   interceptor->set_is_named(false);
1771   return interceptor;
1772 }
1773 
1774 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1775           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)1776 static void ObjectTemplateSetNamedPropertyHandler(
1777     ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1778     Descriptor descriptor, Deleter remover, Enumerator enumerator,
1779     Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1780   i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1781   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1782   i::HandleScope scope(isolate);
1783   auto cons = EnsureConstructor(isolate, templ);
1784   EnsureNotPublished(cons, "ObjectTemplateSetNamedPropertyHandler");
1785   auto obj =
1786       CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1787                                  remover, enumerator, definer, data, flags);
1788   i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1789 }
1790 
SetHandler(const NamedPropertyHandlerConfiguration & config)1791 void ObjectTemplate::SetHandler(
1792     const NamedPropertyHandlerConfiguration& config) {
1793   ObjectTemplateSetNamedPropertyHandler(
1794       this, config.getter, config.setter, config.query, config.descriptor,
1795       config.deleter, config.enumerator, config.definer, config.data,
1796       config.flags);
1797 }
1798 
MarkAsUndetectable()1799 void ObjectTemplate::MarkAsUndetectable() {
1800   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1801   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1802   i::HandleScope scope(isolate);
1803   auto cons = EnsureConstructor(isolate, this);
1804   EnsureNotPublished(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1805   cons->set_undetectable(true);
1806 }
1807 
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1808 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1809                                             Local<Value> data) {
1810   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1811   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1812   i::HandleScope scope(isolate);
1813   auto cons = EnsureConstructor(isolate, this);
1814   EnsureNotPublished(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1815 
1816   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1817       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1818   i::Handle<i::AccessCheckInfo> info =
1819       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1820 
1821   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1822   info->set_named_interceptor(i::Object());
1823   info->set_indexed_interceptor(i::Object());
1824 
1825   if (data.IsEmpty()) {
1826     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1827   }
1828   info->set_data(*Utils::OpenHandle(*data));
1829 
1830   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1831   cons->set_needs_access_check(true);
1832 }
1833 
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1834 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1835     AccessCheckCallback callback,
1836     const NamedPropertyHandlerConfiguration& named_handler,
1837     const IndexedPropertyHandlerConfiguration& indexed_handler,
1838     Local<Value> data) {
1839   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1840   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1841   i::HandleScope scope(isolate);
1842   auto cons = EnsureConstructor(isolate, this);
1843   EnsureNotPublished(cons,
1844                      "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1845 
1846   i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1847       i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1848   i::Handle<i::AccessCheckInfo> info =
1849       i::Handle<i::AccessCheckInfo>::cast(struct_info);
1850 
1851   SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1852   auto named_interceptor = CreateNamedInterceptorInfo(
1853       isolate, named_handler.getter, named_handler.setter, named_handler.query,
1854       named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1855       named_handler.definer, named_handler.data, named_handler.flags);
1856   info->set_named_interceptor(*named_interceptor);
1857   auto indexed_interceptor = CreateIndexedInterceptorInfo(
1858       isolate, indexed_handler.getter, indexed_handler.setter,
1859       indexed_handler.query, indexed_handler.descriptor,
1860       indexed_handler.deleter, indexed_handler.enumerator,
1861       indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1862   info->set_indexed_interceptor(*indexed_interceptor);
1863 
1864   if (data.IsEmpty()) {
1865     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1866   }
1867   info->set_data(*Utils::OpenHandle(*data));
1868 
1869   i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1870   cons->set_needs_access_check(true);
1871 }
1872 
SetHandler(const IndexedPropertyHandlerConfiguration & config)1873 void ObjectTemplate::SetHandler(
1874     const IndexedPropertyHandlerConfiguration& config) {
1875   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1876   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1877   i::HandleScope scope(isolate);
1878   auto cons = EnsureConstructor(isolate, this);
1879   EnsureNotPublished(cons, "v8::ObjectTemplate::SetHandler");
1880   auto obj = CreateIndexedInterceptorInfo(
1881       isolate, config.getter, config.setter, config.query, config.descriptor,
1882       config.deleter, config.enumerator, config.definer, config.data,
1883       config.flags);
1884   i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1885 }
1886 
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1887 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1888                                               Local<Value> data) {
1889   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1890   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1891   i::HandleScope scope(isolate);
1892   auto cons = EnsureConstructor(isolate, this);
1893   EnsureNotPublished(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1894   i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1895   SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1896   SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1897   if (data.IsEmpty()) {
1898     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1899   }
1900   obj->set_data(*Utils::OpenHandle(*data));
1901   i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1902 }
1903 
InternalFieldCount() const1904 int ObjectTemplate::InternalFieldCount() const {
1905   return Utils::OpenHandle(this)->embedder_field_count();
1906 }
1907 
SetInternalFieldCount(int value)1908 void ObjectTemplate::SetInternalFieldCount(int value) {
1909   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1910   if (!Utils::ApiCheck(i::Smi::IsValid(value),
1911                        "v8::ObjectTemplate::SetInternalFieldCount()",
1912                        "Invalid embedder field count")) {
1913     return;
1914   }
1915   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1916   if (value > 0) {
1917     // The embedder field count is set by the constructor function's
1918     // construct code, so we ensure that there is a constructor
1919     // function to do the setting.
1920     EnsureConstructor(isolate, this);
1921   }
1922   Utils::OpenHandle(this)->set_embedder_field_count(value);
1923 }
1924 
IsImmutableProto() const1925 bool ObjectTemplate::IsImmutableProto() const {
1926   return Utils::OpenHandle(this)->immutable_proto();
1927 }
1928 
SetImmutableProto()1929 void ObjectTemplate::SetImmutableProto() {
1930   auto self = Utils::OpenHandle(this);
1931   i::Isolate* isolate = self->GetIsolate();
1932   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1933   self->set_immutable_proto(true);
1934 }
1935 
IsCodeLike() const1936 bool ObjectTemplate::IsCodeLike() const {
1937   return Utils::OpenHandle(this)->code_like();
1938 }
1939 
SetCodeLike()1940 void ObjectTemplate::SetCodeLike() {
1941   auto self = Utils::OpenHandle(this);
1942   i::Isolate* isolate = self->GetIsolate();
1943   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1944   self->set_code_like(true);
1945 }
1946 
1947 // --- S c r i p t s ---
1948 
1949 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1950 // JSFunction.
1951 
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)1952 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1953                                        BufferPolicy buffer_policy_)
1954     : data(data_),
1955       length(length_),
1956       rejected(false),
1957       buffer_policy(buffer_policy_) {}
1958 
~CachedData()1959 ScriptCompiler::CachedData::~CachedData() {
1960   if (buffer_policy == BufferOwned) {
1961     delete[] data;
1962   }
1963 }
1964 
SetBookmark()1965 bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
1966 
ResetToBookmark()1967 void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
1968 
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)1969 ScriptCompiler::StreamedSource::StreamedSource(
1970     std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
1971     : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
1972 
1973 ScriptCompiler::StreamedSource::~StreamedSource() = default;
1974 
BindToCurrentContext()1975 Local<Script> UnboundScript::BindToCurrentContext() {
1976   auto function_info =
1977       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1978   i::Isolate* isolate = function_info->GetIsolate();
1979   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1980   i::Handle<i::JSFunction> function =
1981       i::Factory::JSFunctionBuilder{isolate, function_info,
1982                                     isolate->native_context()}
1983           .Build();
1984   return ToApiHandle<Script>(function);
1985 }
1986 
GetId() const1987 int UnboundScript::GetId() const {
1988   auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
1989   i::Isolate* isolate = function_info.GetIsolate();
1990   LOG_API(isolate, UnboundScript, GetId);
1991   return i::Script::cast(function_info.script()).id();
1992 }
1993 
GetLineNumber(int code_pos)1994 int UnboundScript::GetLineNumber(int code_pos) {
1995   i::Handle<i::SharedFunctionInfo> obj =
1996       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1997   i::Isolate* isolate = obj->GetIsolate();
1998   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1999   LOG_API(isolate, UnboundScript, GetLineNumber);
2000   if (obj->script().IsScript()) {
2001     i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2002     return i::Script::GetLineNumber(script, code_pos);
2003   } else {
2004     return -1;
2005   }
2006 }
2007 
GetScriptName()2008 Local<Value> UnboundScript::GetScriptName() {
2009   i::Handle<i::SharedFunctionInfo> obj =
2010       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2011   i::Isolate* isolate = obj->GetIsolate();
2012   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2013   LOG_API(isolate, UnboundScript, GetName);
2014   if (obj->script().IsScript()) {
2015     i::Object name = i::Script::cast(obj->script()).name();
2016     return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2017   } else {
2018     return Local<String>();
2019   }
2020 }
2021 
GetSourceURL()2022 Local<Value> UnboundScript::GetSourceURL() {
2023   i::Handle<i::SharedFunctionInfo> obj =
2024       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2025   i::Isolate* isolate = obj->GetIsolate();
2026   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2027   LOG_API(isolate, UnboundScript, GetSourceURL);
2028   if (obj->script().IsScript()) {
2029     i::Object url = i::Script::cast(obj->script()).source_url();
2030     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2031   } else {
2032     return Local<String>();
2033   }
2034 }
2035 
GetSourceMappingURL()2036 Local<Value> UnboundScript::GetSourceMappingURL() {
2037   i::Handle<i::SharedFunctionInfo> obj =
2038       i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2039   i::Isolate* isolate = obj->GetIsolate();
2040   LOG_API(isolate, UnboundScript, GetSourceMappingURL);
2041   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2042   if (obj->script().IsScript()) {
2043     i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2044     return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2045   } else {
2046     return Local<String>();
2047   }
2048 }
2049 
Run(Local<Context> context)2050 MaybeLocal<Value> Script::Run(Local<Context> context) {
2051   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2052   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2053   ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2054            InternalEscapableScope);
2055   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2056   i::NestedTimedHistogramScope execute_timer(
2057       isolate->counters()->execute_precise());
2058   i::AggregatingHistogramTimerScope histogram_timer(
2059       isolate->counters()->compile_lazy());
2060   auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2061 
2062   // TODO(crbug.com/1193459): remove once ablation study is completed
2063   base::ElapsedTimer timer;
2064   base::TimeDelta delta;
2065   if (i::FLAG_script_delay > 0) {
2066     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay);
2067   }
2068   if (i::FLAG_script_delay_once > 0 && !isolate->did_run_script_delay()) {
2069     delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay_once);
2070     isolate->set_did_run_script_delay(true);
2071   }
2072   if (i::FLAG_script_delay_fraction > 0.0) {
2073     timer.Start();
2074   } else if (delta.InMicroseconds() > 0) {
2075     timer.Start();
2076     while (timer.Elapsed() < delta) {
2077       // Busy wait.
2078     }
2079   }
2080 
2081   i::Handle<i::Object> receiver = isolate->global_proxy();
2082   Local<Value> result;
2083   has_pending_exception = !ToLocal<Value>(
2084       i::Execution::Call(isolate, fun, receiver, 0, nullptr), &result);
2085 
2086   if (i::FLAG_script_delay_fraction > 0.0) {
2087     delta = v8::base::TimeDelta::FromMillisecondsD(
2088         timer.Elapsed().InMillisecondsF() * i::FLAG_script_delay_fraction);
2089     timer.Restart();
2090     while (timer.Elapsed() < delta) {
2091       // Busy wait.
2092     }
2093   }
2094 
2095   RETURN_ON_FAILED_EXECUTION(Value);
2096   RETURN_ESCAPED(result);
2097 }
2098 
GetResourceName()2099 Local<Value> ScriptOrModule::GetResourceName() {
2100   i::Handle<i::Script> obj = Utils::OpenHandle(this);
2101   i::Isolate* isolate = obj->GetIsolate();
2102   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2103   i::Handle<i::Object> val(obj->name(), isolate);
2104   return ToApiHandle<Value>(val);
2105 }
2106 
GetHostDefinedOptions()2107 Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2108   i::Handle<i::Script> obj = Utils::OpenHandle(this);
2109   i::Isolate* isolate = obj->GetIsolate();
2110   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2111   i::Handle<i::FixedArray> val(obj->host_defined_options(), isolate);
2112   return ToApiHandle<PrimitiveArray>(val);
2113 }
2114 
GetUnboundScript()2115 Local<UnboundScript> Script::GetUnboundScript() {
2116   i::Handle<i::Object> obj = Utils::OpenHandle(this);
2117   i::SharedFunctionInfo sfi = i::JSFunction::cast(*obj).shared();
2118   i::Isolate* isolate = sfi.GetIsolate();
2119   return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2120 }
2121 
2122 // static
New(Isolate * v8_isolate,int length)2123 Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2124   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2125   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2126   Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2127                   "length must be equal or greater than zero");
2128   i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2129   return ToApiHandle<PrimitiveArray>(array);
2130 }
2131 
Length() const2132 int PrimitiveArray::Length() const {
2133   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2134   return array->length();
2135 }
2136 
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2137 void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2138                          Local<Primitive> item) {
2139   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2140   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2141   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2142   Utils::ApiCheck(index >= 0 && index < array->length(),
2143                   "v8::PrimitiveArray::Set",
2144                   "index must be greater than or equal to 0 and less than the "
2145                   "array length");
2146   i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2147   array->set(index, *i_item);
2148 }
2149 
Get(Isolate * v8_isolate,int index)2150 Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2151   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2152   i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2153   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2154   Utils::ApiCheck(index >= 0 && index < array->length(),
2155                   "v8::PrimitiveArray::Get",
2156                   "index must be greater than or equal to 0 and less than the "
2157                   "array length");
2158   i::Handle<i::Object> i_item(array->get(index), isolate);
2159   return ToApiHandle<Primitive>(i_item);
2160 }
2161 
Length() const2162 int FixedArray::Length() const {
2163   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2164   return self->length();
2165 }
2166 
Get(Local<Context> context,int i) const2167 Local<Data> FixedArray::Get(Local<Context> context, int i) const {
2168   i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2169   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2170   CHECK_LT(i, self->length());
2171   i::Handle<i::Object> entry(self->get(i), isolate);
2172   return ToApiHandle<Data>(entry);
2173 }
2174 
GetSpecifier() const2175 Local<String> ModuleRequest::GetSpecifier() const {
2176   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2177   i::Isolate* isolate = self->GetIsolate();
2178   return ToApiHandle<String>(i::handle(self->specifier(), isolate));
2179 }
2180 
GetSourceOffset() const2181 int ModuleRequest::GetSourceOffset() const {
2182   return Utils::OpenHandle(this)->position();
2183 }
2184 
GetImportAssertions() const2185 Local<FixedArray> ModuleRequest::GetImportAssertions() const {
2186   i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2187   i::Isolate* isolate = self->GetIsolate();
2188   return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate));
2189 }
2190 
GetStatus() const2191 Module::Status Module::GetStatus() const {
2192   i::Handle<i::Module> self = Utils::OpenHandle(this);
2193   switch (self->status()) {
2194     case i::Module::kUnlinked:
2195     case i::Module::kPreLinking:
2196       return kUninstantiated;
2197     case i::Module::kLinking:
2198       return kInstantiating;
2199     case i::Module::kLinked:
2200       return kInstantiated;
2201     case i::Module::kEvaluating:
2202     case i::Module::kEvaluatingAsync:
2203       return kEvaluating;
2204     case i::Module::kEvaluated:
2205       return kEvaluated;
2206     case i::Module::kErrored:
2207       return kErrored;
2208   }
2209   UNREACHABLE();
2210 }
2211 
GetException() const2212 Local<Value> Module::GetException() const {
2213   Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2214                   "Module status must be kErrored");
2215   i::Handle<i::Module> self = Utils::OpenHandle(this);
2216   i::Isolate* isolate = self->GetIsolate();
2217   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2218   return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2219 }
2220 
GetModuleRequestsLength() const2221 int Module::GetModuleRequestsLength() const {
2222   i::Module self = *Utils::OpenHandle(this);
2223   if (self.IsSyntheticModule()) return 0;
2224   ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2225   return i::SourceTextModule::cast(self).info().module_requests().length();
2226 }
2227 
GetModuleRequest(int i) const2228 Local<String> Module::GetModuleRequest(int i) const {
2229   Utils::ApiCheck(i >= 0, "v8::Module::GetModuleRequest",
2230                   "index must be positive");
2231   i::Handle<i::Module> self = Utils::OpenHandle(this);
2232   Utils::ApiCheck(self->IsSourceTextModule(), "v8::Module::GetModuleRequest",
2233                   "Expected SourceTextModule");
2234   i::Isolate* isolate = self->GetIsolate();
2235   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2236   i::Handle<i::FixedArray> module_requests(
2237       i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2238       isolate);
2239   Utils::ApiCheck(i < module_requests->length(), "v8::Module::GetModuleRequest",
2240                   "index is out of bounds");
2241   i::Handle<i::ModuleRequest> module_request(
2242       i::ModuleRequest::cast(module_requests->get(i)), isolate);
2243   return ToApiHandle<String>(i::handle(module_request->specifier(), isolate));
2244 }
2245 
GetModuleRequestLocation(int i) const2246 Location Module::GetModuleRequestLocation(int i) const {
2247   Utils::ApiCheck(i >= 0, "v8::Module::GetModuleRequest",
2248                   "index must be positive");
2249   i::Handle<i::Module> self = Utils::OpenHandle(this);
2250   i::Isolate* isolate = self->GetIsolate();
2251   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2252   i::HandleScope scope(isolate);
2253   Utils::ApiCheck(self->IsSourceTextModule(),
2254                   "Module::GetModuleRequestLocation",
2255                   "Expected SourceTextModule");
2256   i::Handle<i::FixedArray> module_requests(
2257       i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2258       isolate);
2259   Utils::ApiCheck(i < module_requests->length(), "v8::Module::GetModuleRequest",
2260                   "index is out of bounds");
2261   i::Handle<i::ModuleRequest> module_request(
2262       i::ModuleRequest::cast(module_requests->get(i)), isolate);
2263   int position = module_request->position();
2264   i::Handle<i::Script> script(
2265       i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2266   i::Script::PositionInfo info;
2267   i::Script::GetPositionInfo(script, position, &info, i::Script::WITH_OFFSET);
2268   return v8::Location(info.line, info.column);
2269 }
2270 
GetModuleRequests() const2271 Local<FixedArray> Module::GetModuleRequests() const {
2272   i::Handle<i::Module> self = Utils::OpenHandle(this);
2273   if (self->IsSyntheticModule()) {
2274     // Synthetic modules are leaf nodes in the module graph. They have no
2275     // ModuleRequests.
2276     return ToApiHandle<FixedArray>(
2277         self->GetReadOnlyRoots().empty_fixed_array_handle());
2278   } else {
2279     i::Isolate* isolate = self->GetIsolate();
2280     i::Handle<i::FixedArray> module_requests(
2281         i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2282         isolate);
2283     return ToApiHandle<FixedArray>(module_requests);
2284   }
2285 }
2286 
SourceOffsetToLocation(int offset) const2287 Location Module::SourceOffsetToLocation(int offset) const {
2288   i::Handle<i::Module> self = Utils::OpenHandle(this);
2289   i::Isolate* isolate = self->GetIsolate();
2290   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2291   i::HandleScope scope(isolate);
2292   Utils::ApiCheck(
2293       self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation",
2294       "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule");
2295   i::Handle<i::Script> script(
2296       i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2297   i::Script::PositionInfo info;
2298   i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
2299   return v8::Location(info.line, info.column);
2300 }
2301 
GetModuleNamespace()2302 Local<Value> Module::GetModuleNamespace() {
2303   Utils::ApiCheck(
2304       GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2305       "v8::Module::GetModuleNamespace must be used on an instantiated module");
2306   i::Handle<i::Module> self = Utils::OpenHandle(this);
2307   auto isolate = self->GetIsolate();
2308   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2309   i::Handle<i::JSModuleNamespace> module_namespace =
2310       i::Module::GetModuleNamespace(isolate, self);
2311   return ToApiHandle<Value>(module_namespace);
2312 }
2313 
GetUnboundModuleScript()2314 Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2315   i::Handle<i::Module> self = Utils::OpenHandle(this);
2316   Utils::ApiCheck(
2317       self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript",
2318       "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule");
2319   auto isolate = self->GetIsolate();
2320   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2321   return ToApiHandle<UnboundModuleScript>(i::handle(
2322       i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2323       isolate));
2324 }
2325 
ScriptId() const2326 int Module::ScriptId() const {
2327   i::Module self = *Utils::OpenHandle(this);
2328   Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
2329                   "v8::Module::ScriptId must be used on an SourceTextModule");
2330   ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2331   return i::SourceTextModule::cast(self).GetScript().id();
2332 }
2333 
IsGraphAsync() const2334 bool Module::IsGraphAsync() const {
2335   Utils::ApiCheck(
2336       GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2337       "v8::Module::IsGraphAsync must be used on an instantiated module");
2338   i::Module self = *Utils::OpenHandle(this);
2339   auto isolate = self.GetIsolate();
2340   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2341   return self.IsGraphAsync(isolate);
2342 }
2343 
IsSourceTextModule() const2344 bool Module::IsSourceTextModule() const {
2345   return Utils::OpenHandle(this)->IsSourceTextModule();
2346 }
2347 
IsSyntheticModule() const2348 bool Module::IsSyntheticModule() const {
2349   return Utils::OpenHandle(this)->IsSyntheticModule();
2350 }
2351 
GetIdentityHash() const2352 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2353 
InstantiateModule(Local<Context> context,Module::ResolveCallback callback)2354 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2355                                       Module::ResolveCallback callback) {
2356   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2357   ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2358            i::HandleScope);
2359   ResolveModuleCallback callback_with_import_assertions = nullptr;
2360   has_pending_exception =
2361       !i::Module::Instantiate(isolate, Utils::OpenHandle(this), context,
2362                               callback_with_import_assertions, callback);
2363   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2364   return Just(true);
2365 }
2366 
InstantiateModule(Local<Context> context,Module::ResolveModuleCallback callback)2367 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2368                                       Module::ResolveModuleCallback callback) {
2369   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2370   ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2371            i::HandleScope);
2372   has_pending_exception = !i::Module::Instantiate(
2373       isolate, Utils::OpenHandle(this), context, callback, nullptr);
2374   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2375   return Just(true);
2376 }
2377 
Evaluate(Local<Context> context)2378 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2379   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2380   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2381   ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2382            InternalEscapableScope);
2383   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2384   i::NestedTimedHistogramScope execute_timer(
2385       isolate->counters()->execute_precise());
2386   i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2387 
2388   i::Handle<i::Module> self = Utils::OpenHandle(this);
2389   Utils::ApiCheck(self->status() >= i::Module::kLinked, "Module::Evaluate",
2390                   "Expected instantiated module");
2391 
2392   Local<Value> result;
2393   has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2394   RETURN_ON_FAILED_EXECUTION(Value);
2395   RETURN_ESCAPED(result);
2396 }
2397 
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2398 Local<Module> Module::CreateSyntheticModule(
2399     Isolate* isolate, Local<String> module_name,
2400     const std::vector<Local<v8::String>>& export_names,
2401     v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2402   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2403   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
2404   i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2405   i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2406       static_cast<int>(export_names.size()));
2407   for (int i = 0; i < i_export_names->length(); ++i) {
2408     i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2409         Utils::OpenHandle(*export_names[i]));
2410     i_export_names->set(i, *str);
2411   }
2412   return v8::Utils::ToLocal(
2413       i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2414           i_module_name, i_export_names, evaluation_steps)));
2415 }
2416 
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2417 Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2418                                              Local<String> export_name,
2419                                              Local<v8::Value> export_value) {
2420   auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2421   i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2422   i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2423   i::Handle<i::Module> self = Utils::OpenHandle(this);
2424   Utils::ApiCheck(self->IsSyntheticModule(),
2425                   "v8::Module::SyntheticModuleSetExport",
2426                   "v8::Module::SyntheticModuleSetExport must only be called on "
2427                   "a SyntheticModule");
2428   ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2429                      SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2430   has_pending_exception =
2431       i::SyntheticModule::SetExport(i_isolate,
2432                                     i::Handle<i::SyntheticModule>::cast(self),
2433                                     i_export_name, i_export_value)
2434           .IsNothing();
2435   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2436   return Just(true);
2437 }
2438 
2439 namespace {
2440 
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,int resource_line_offset,int resource_column_offset,Local<Value> source_map_url,Local<PrimitiveArray> host_defined_options,ScriptOriginOptions origin_options)2441 i::ScriptDetails GetScriptDetails(i::Isolate* isolate,
2442                                   Local<Value> resource_name,
2443                                   int resource_line_offset,
2444                                   int resource_column_offset,
2445                                   Local<Value> source_map_url,
2446                                   Local<PrimitiveArray> host_defined_options,
2447                                   ScriptOriginOptions origin_options) {
2448   i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
2449                                   origin_options);
2450   script_details.line_offset = resource_line_offset;
2451   script_details.column_offset = resource_column_offset;
2452   script_details.host_defined_options =
2453       host_defined_options.IsEmpty()
2454           ? isolate->factory()->empty_fixed_array()
2455           : Utils::OpenHandle(*(host_defined_options));
2456   if (!source_map_url.IsEmpty()) {
2457     script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2458   }
2459   return script_details;
2460 }
2461 
2462 }  // namespace
2463 
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2464 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2465     Isolate* v8_isolate, Source* source, CompileOptions options,
2466     NoCacheReason no_cache_reason) {
2467   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2468   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2469   ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2470                      CompileUnbound, MaybeLocal<UnboundScript>(),
2471                      InternalEscapableScope);
2472 
2473   i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2474 
2475   i::Handle<i::SharedFunctionInfo> result;
2476   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2477   i::ScriptDetails script_details = GetScriptDetails(
2478       isolate, source->resource_name, source->resource_line_offset,
2479       source->resource_column_offset, source->source_map_url,
2480       source->host_defined_options, source->resource_options);
2481 
2482   i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info;
2483   if (options == kConsumeCodeCache) {
2484     if (source->consume_cache_task) {
2485       // Take ownership of the internal deserialization task and clear it off
2486       // the consume task on the source.
2487       DCHECK_NOT_NULL(source->consume_cache_task->impl_);
2488       std::unique_ptr<i::BackgroundDeserializeTask> deserialize_task =
2489           std::move(source->consume_cache_task->impl_);
2490       maybe_function_info =
2491           i::Compiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
2492               isolate, str, script_details, deserialize_task.get(), options,
2493               no_cache_reason, i::NOT_NATIVES_CODE);
2494       source->cached_data->rejected = deserialize_task->rejected();
2495     } else {
2496       DCHECK(source->cached_data);
2497       // AlignedCachedData takes care of pointer-aligning the data.
2498       auto cached_data = std::make_unique<i::AlignedCachedData>(
2499           source->cached_data->data, source->cached_data->length);
2500       maybe_function_info =
2501           i::Compiler::GetSharedFunctionInfoForScriptWithCachedData(
2502               isolate, str, script_details, cached_data.get(), options,
2503               no_cache_reason, i::NOT_NATIVES_CODE);
2504       source->cached_data->rejected = cached_data->rejected();
2505     }
2506   } else {
2507     // Compile without any cache.
2508     maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript(
2509         isolate, str, script_details, options, no_cache_reason,
2510         i::NOT_NATIVES_CODE);
2511   }
2512 
2513   has_pending_exception = !maybe_function_info.ToHandle(&result);
2514   RETURN_ON_FAILED_EXECUTION(UnboundScript);
2515   RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2516 }
2517 
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2518 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2519     Isolate* v8_isolate, Source* source, CompileOptions options,
2520     NoCacheReason no_cache_reason) {
2521   Utils::ApiCheck(
2522       !source->GetResourceOptions().IsModule(),
2523       "v8::ScriptCompiler::CompileUnboundScript",
2524       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2525   return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2526 }
2527 
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2528 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2529                                            Source* source,
2530                                            CompileOptions options,
2531                                            NoCacheReason no_cache_reason) {
2532   Utils::ApiCheck(
2533       !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2534       "v8::ScriptCompiler::CompileModule must be used to compile modules");
2535   auto isolate = context->GetIsolate();
2536   MaybeLocal<UnboundScript> maybe =
2537       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2538   Local<UnboundScript> result;
2539   if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2540   v8::Context::Scope scope(context);
2541   return result->BindToCurrentContext();
2542 }
2543 
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2544 MaybeLocal<Module> ScriptCompiler::CompileModule(
2545     Isolate* isolate, Source* source, CompileOptions options,
2546     NoCacheReason no_cache_reason) {
2547   Utils::ApiCheck(options == kNoCompileOptions || options == kConsumeCodeCache,
2548                   "v8::ScriptCompiler::CompileModule",
2549                   "Invalid CompileOptions");
2550   Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2551                   "v8::ScriptCompiler::CompileModule",
2552                   "Invalid ScriptOrigin: is_module must be true");
2553   MaybeLocal<UnboundScript> maybe =
2554       CompileUnboundInternal(isolate, source, options, no_cache_reason);
2555   Local<UnboundScript> unbound;
2556   if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2557   i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2558   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2559   return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2560 }
2561 
2562 namespace {
IsIdentifier(i::Isolate * isolate,i::Handle<i::String> string)2563 bool IsIdentifier(i::Isolate* isolate, i::Handle<i::String> string) {
2564   string = i::String::Flatten(isolate, string);
2565   const int length = string->length();
2566   if (length == 0) return false;
2567   if (!i::IsIdentifierStart(string->Get(0))) return false;
2568   i::DisallowGarbageCollection no_gc;
2569   i::String::FlatContent flat = string->GetFlatContent(no_gc);
2570   if (flat.IsOneByte()) {
2571     auto vector = flat.ToOneByteVector();
2572     for (int i = 1; i < length; i++) {
2573       if (!i::IsIdentifierPart(vector[i])) return false;
2574     }
2575   } else {
2576     auto vector = flat.ToUC16Vector();
2577     for (int i = 1; i < length; i++) {
2578       if (!i::IsIdentifierPart(vector[i])) return false;
2579     }
2580   }
2581   return true;
2582 }
2583 }  // anonymous namespace
2584 
CompileFunctionInContext(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)2585 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2586     Local<Context> v8_context, Source* source, size_t arguments_count,
2587     Local<String> arguments[], size_t context_extension_count,
2588     Local<Object> context_extensions[], CompileOptions options,
2589     NoCacheReason no_cache_reason,
2590     Local<ScriptOrModule>* script_or_module_out) {
2591   Local<Function> result;
2592 
2593   {
2594     PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2595                           Function);
2596     TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2597 
2598     DCHECK(options == CompileOptions::kConsumeCodeCache ||
2599            options == CompileOptions::kEagerCompile ||
2600            options == CompileOptions::kNoCompileOptions);
2601 
2602     i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2603 
2604     DCHECK(context->IsNativeContext());
2605 
2606     i::Handle<i::FixedArray> arguments_list =
2607         isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2608     for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2609       i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2610       if (!IsIdentifier(isolate, argument)) return Local<Function>();
2611       arguments_list->set(i, *argument);
2612     }
2613 
2614     for (size_t i = 0; i < context_extension_count; ++i) {
2615       i::Handle<i::JSReceiver> extension =
2616           Utils::OpenHandle(*context_extensions[i]);
2617       if (!extension->IsJSObject()) return Local<Function>();
2618       context = isolate->factory()->NewWithContext(
2619           context,
2620           i::ScopeInfo::CreateForWithScope(
2621               isolate,
2622               context->IsNativeContext()
2623                   ? i::Handle<i::ScopeInfo>::null()
2624                   : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2625           extension);
2626     }
2627 
2628     i::ScriptDetails script_details = GetScriptDetails(
2629         isolate, source->resource_name, source->resource_line_offset,
2630         source->resource_column_offset, source->source_map_url,
2631         source->host_defined_options, source->resource_options);
2632 
2633     std::unique_ptr<i::AlignedCachedData> cached_data;
2634     if (options == kConsumeCodeCache) {
2635       DCHECK(source->cached_data);
2636       // ScriptData takes care of pointer-aligning the data.
2637       cached_data.reset(new i::AlignedCachedData(source->cached_data->data,
2638                                                  source->cached_data->length));
2639     }
2640 
2641     i::Handle<i::JSFunction> scoped_result;
2642     has_pending_exception =
2643         !i::Compiler::GetWrappedFunction(
2644              Utils::OpenHandle(*source->source_string), arguments_list, context,
2645              script_details, cached_data.get(), options, no_cache_reason)
2646              .ToHandle(&scoped_result);
2647     if (options == kConsumeCodeCache) {
2648       source->cached_data->rejected = cached_data->rejected();
2649     }
2650     RETURN_ON_FAILED_EXECUTION(Function);
2651     result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2652   }
2653 
2654   if (script_or_module_out != nullptr) {
2655     i::Handle<i::JSFunction> function =
2656         i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2657     i::Isolate* isolate = function->GetIsolate();
2658     i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2659     i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2660     *script_or_module_out = v8::Utils::ScriptOrModuleToLocal(script);
2661   }
2662 
2663   return result;
2664 }
2665 
Run()2666 void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2667 
StartStreaming(Isolate * v8_isolate,StreamedSource * source,v8::ScriptType type)2668 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2669     Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) {
2670   if (!i::FLAG_script_streaming) return nullptr;
2671   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2672   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2673   i::ScriptStreamingData* data = source->impl();
2674   std::unique_ptr<i::BackgroundCompileTask> task =
2675       std::make_unique<i::BackgroundCompileTask>(data, isolate, type);
2676   data->task = std::move(task);
2677   return new ScriptCompiler::ScriptStreamingTask(data);
2678 }
2679 
ConsumeCodeCacheTask(std::unique_ptr<i::BackgroundDeserializeTask> impl)2680 ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2681     std::unique_ptr<i::BackgroundDeserializeTask> impl)
2682     : impl_(std::move(impl)) {}
2683 
2684 ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2685 
Run()2686 void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2687 
StartConsumingCodeCache(Isolate * v8_isolate,std::unique_ptr<CachedData> cached_data)2688 ScriptCompiler::ConsumeCodeCacheTask* ScriptCompiler::StartConsumingCodeCache(
2689     Isolate* v8_isolate, std::unique_ptr<CachedData> cached_data) {
2690   if (!i::FLAG_concurrent_cache_deserialization) return nullptr;
2691   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2692   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2693   return new ScriptCompiler::ConsumeCodeCacheTask(
2694       std::make_unique<i::BackgroundDeserializeTask>(isolate,
2695                                                      std::move(cached_data)));
2696 }
2697 
2698 namespace {
CompileStreamedSource(i::Isolate * isolate,ScriptCompiler::StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2699 i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
2700     i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source,
2701     Local<String> full_source_string, const ScriptOrigin& origin) {
2702   i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2703   i::ScriptDetails script_details =
2704       GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
2705                        origin.ColumnOffset(), origin.SourceMapUrl(),
2706                        origin.HostDefinedOptions(), origin.Options());
2707   i::ScriptStreamingData* data = v8_source->impl();
2708   return i::Compiler::GetSharedFunctionInfoForStreamedScript(
2709       isolate, str, script_details, data);
2710 }
2711 
2712 }  // namespace
2713 
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2714 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2715                                            StreamedSource* v8_source,
2716                                            Local<String> full_source_string,
2717                                            const ScriptOrigin& origin) {
2718   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2719   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2720   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2721                "V8.CompileStreamedScript");
2722   i::Handle<i::SharedFunctionInfo> sfi;
2723   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2724       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2725   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2726   if (has_pending_exception) isolate->ReportPendingMessages();
2727   RETURN_ON_FAILED_EXECUTION(Script);
2728   Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi);
2729   if (generic.IsEmpty()) return Local<Script>();
2730   Local<Script> bound = generic->BindToCurrentContext();
2731   if (bound.IsEmpty()) return Local<Script>();
2732   RETURN_ESCAPED(bound);
2733 }
2734 
CompileModule(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2735 MaybeLocal<Module> ScriptCompiler::CompileModule(
2736     Local<Context> context, StreamedSource* v8_source,
2737     Local<String> full_source_string, const ScriptOrigin& origin) {
2738   PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module);
2739   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2740   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2741                "V8.CompileStreamedModule");
2742   i::Handle<i::SharedFunctionInfo> sfi;
2743   i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2744       CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2745   has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2746   if (has_pending_exception) isolate->ReportPendingMessages();
2747   RETURN_ON_FAILED_EXECUTION(Module);
2748   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2749   RETURN_ESCAPED(
2750       ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi)));
2751 }
2752 
CachedDataVersionTag()2753 uint32_t ScriptCompiler::CachedDataVersionTag() {
2754   return static_cast<uint32_t>(base::hash_combine(
2755       internal::Version::Hash(), internal::FlagList::Hash(),
2756       static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2757 }
2758 
CreateCodeCache(Local<UnboundScript> unbound_script)2759 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2760     Local<UnboundScript> unbound_script) {
2761   i::Handle<i::SharedFunctionInfo> shared =
2762       i::Handle<i::SharedFunctionInfo>::cast(
2763           Utils::OpenHandle(*unbound_script));
2764   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2765   DCHECK(shared->is_toplevel());
2766   return i::CodeSerializer::Serialize(shared);
2767 }
2768 
2769 // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2770 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2771     Local<UnboundModuleScript> unbound_module_script) {
2772   i::Handle<i::SharedFunctionInfo> shared =
2773       i::Handle<i::SharedFunctionInfo>::cast(
2774           Utils::OpenHandle(*unbound_module_script));
2775   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2776   DCHECK(shared->is_toplevel());
2777   return i::CodeSerializer::Serialize(shared);
2778 }
2779 
CreateCodeCacheForFunction(Local<Function> function)2780 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2781     Local<Function> function) {
2782   auto js_function =
2783       i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2784   i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2785                                           js_function->GetIsolate());
2786   ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2787   Utils::ApiCheck(shared->is_wrapped(),
2788                   "v8::ScriptCompiler::CreateCodeCacheForFunction",
2789                   "Expected SharedFunctionInfo with wrapped source code.");
2790   return i::CodeSerializer::Serialize(shared);
2791 }
2792 
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2793 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2794                                    ScriptOrigin* origin) {
2795   if (origin) {
2796     ScriptCompiler::Source script_source(source, *origin);
2797     return ScriptCompiler::Compile(context, &script_source);
2798   }
2799   ScriptCompiler::Source script_source(source);
2800   return ScriptCompiler::Compile(context, &script_source);
2801 }
2802 
2803 // --- E x c e p t i o n s ---
2804 
TryCatch(v8::Isolate * isolate)2805 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2806     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2807       next_(isolate_->try_catch_handler()),
2808       is_verbose_(false),
2809       can_continue_(true),
2810       capture_message_(true),
2811       rethrow_(false),
2812       has_terminated_(false) {
2813   ResetInternal();
2814   // Special handling for simulators which have a separate JS stack.
2815   js_stack_comparable_address_ = static_cast<internal::Address>(
2816       i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2817   isolate_->RegisterTryCatchHandler(this);
2818 }
2819 
~TryCatch()2820 v8::TryCatch::~TryCatch() {
2821   if (rethrow_) {
2822     v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2823     v8::HandleScope scope(isolate);
2824     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2825     if (HasCaught() && capture_message_) {
2826       // If an exception was caught and rethrow_ is indicated, the saved
2827       // message, script, and location need to be restored to Isolate TLS
2828       // for reuse.  capture_message_ needs to be disabled so that Throw()
2829       // does not create a new message.
2830       isolate_->thread_local_top()->rethrowing_message_ = true;
2831       isolate_->RestorePendingMessageFromTryCatch(this);
2832     }
2833     isolate_->UnregisterTryCatchHandler(this);
2834     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2835     reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2836     DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2837   } else {
2838     if (HasCaught() && isolate_->has_scheduled_exception()) {
2839       // If an exception was caught but is still scheduled because no API call
2840       // promoted it, then it is canceled to prevent it from being propagated.
2841       // Note that this will not cancel termination exceptions.
2842       isolate_->CancelScheduledExceptionFromTryCatch(this);
2843     }
2844     isolate_->UnregisterTryCatchHandler(this);
2845     i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2846   }
2847 }
2848 
operator new(size_t)2849 void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2850 void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2851 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2852 void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2853 
HasCaught() const2854 bool v8::TryCatch::HasCaught() const {
2855   return !i::Object(reinterpret_cast<i::Address>(exception_))
2856               .IsTheHole(isolate_);
2857 }
2858 
CanContinue() const2859 bool v8::TryCatch::CanContinue() const { return can_continue_; }
2860 
HasTerminated() const2861 bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2862 
ReThrow()2863 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2864   if (!HasCaught()) return v8::Local<v8::Value>();
2865   rethrow_ = true;
2866   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2867 }
2868 
Exception() const2869 v8::Local<Value> v8::TryCatch::Exception() const {
2870   if (HasCaught()) {
2871     // Check for out of memory exception.
2872     i::Object exception(reinterpret_cast<i::Address>(exception_));
2873     return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2874   } else {
2875     return v8::Local<Value>();
2876   }
2877 }
2878 
StackTrace(Local<Context> context,Local<Value> exception)2879 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2880                                            Local<Value> exception) {
2881   i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2882   if (!i_exception->IsJSObject()) return v8::Local<Value>();
2883   PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2884   auto obj = i::Handle<i::JSObject>::cast(i_exception);
2885   i::Handle<i::String> name = isolate->factory()->stack_string();
2886   Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2887   has_pending_exception = maybe.IsNothing();
2888   RETURN_ON_FAILED_EXECUTION(Value);
2889   if (!maybe.FromJust()) return v8::Local<Value>();
2890   Local<Value> result;
2891   has_pending_exception =
2892       !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2893   RETURN_ON_FAILED_EXECUTION(Value);
2894   RETURN_ESCAPED(result);
2895 }
2896 
StackTrace(Local<Context> context) const2897 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2898   if (!HasCaught()) return v8::Local<Value>();
2899   return StackTrace(context, Exception());
2900 }
2901 
Message() const2902 v8::Local<v8::Message> v8::TryCatch::Message() const {
2903   i::Object message(reinterpret_cast<i::Address>(message_obj_));
2904   DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2905   if (HasCaught() && !message.IsTheHole(isolate_)) {
2906     return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2907   } else {
2908     return v8::Local<v8::Message>();
2909   }
2910 }
2911 
Reset()2912 void v8::TryCatch::Reset() {
2913   if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2914     // If an exception was caught but is still scheduled because no API call
2915     // promoted it, then it is canceled to prevent it from being propagated.
2916     // Note that this will not cancel termination exceptions.
2917     isolate_->CancelScheduledExceptionFromTryCatch(this);
2918   }
2919   ResetInternal();
2920 }
2921 
ResetInternal()2922 void v8::TryCatch::ResetInternal() {
2923   i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2924   exception_ = reinterpret_cast<void*>(the_hole.ptr());
2925   message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2926 }
2927 
SetVerbose(bool value)2928 void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2929 
IsVerbose() const2930 bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2931 
SetCaptureMessage(bool value)2932 void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2933 
2934 // --- M e s s a g e ---
2935 
Get() const2936 Local<String> Message::Get() const {
2937   auto self = Utils::OpenHandle(this);
2938   i::Isolate* isolate = self->GetIsolate();
2939   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2940   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2941   i::Handle<i::String> raw_result =
2942       i::MessageHandler::GetMessage(isolate, self);
2943   Local<String> result = Utils::ToLocal(raw_result);
2944   return scope.Escape(result);
2945 }
2946 
GetIsolate() const2947 v8::Isolate* Message::GetIsolate() const {
2948   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2949   return reinterpret_cast<Isolate*>(isolate);
2950 }
2951 
GetScriptOrigin() const2952 ScriptOrigin Message::GetScriptOrigin() const {
2953   auto self = Utils::OpenHandle(this);
2954   i::Isolate* isolate = self->GetIsolate();
2955   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2956   i::Handle<i::Script> script(self->script(), isolate);
2957   return GetScriptOriginForScript(isolate, script);
2958 }
2959 
GetScriptResourceName() const2960 v8::Local<Value> Message::GetScriptResourceName() const {
2961   ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
2962   return GetScriptOrigin().ResourceName();
2963 }
2964 
GetStackTrace() const2965 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
2966   auto self = Utils::OpenHandle(this);
2967   i::Isolate* isolate = self->GetIsolate();
2968   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2969   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2970   i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
2971   if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
2972   auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
2973   return scope.Escape(Utils::StackTraceToLocal(stackTrace));
2974 }
2975 
GetLineNumber(Local<Context> context) const2976 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2977   auto self = Utils::OpenHandle(this);
2978   i::Isolate* isolate = self->GetIsolate();
2979   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2980   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2981   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2982   return Just(self->GetLineNumber());
2983 }
2984 
GetStartPosition() const2985 int Message::GetStartPosition() const {
2986   auto self = Utils::OpenHandle(this);
2987   i::Isolate* isolate = self->GetIsolate();
2988   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2989   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2990   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2991   return self->GetStartPosition();
2992 }
2993 
GetEndPosition() const2994 int Message::GetEndPosition() const {
2995   auto self = Utils::OpenHandle(this);
2996   i::Isolate* isolate = self->GetIsolate();
2997   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2998   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2999   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3000   return self->GetEndPosition();
3001 }
3002 
ErrorLevel() const3003 int Message::ErrorLevel() const {
3004   auto self = Utils::OpenHandle(this);
3005   ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3006   return self->error_level();
3007 }
3008 
GetStartColumn() const3009 int Message::GetStartColumn() const {
3010   auto self = Utils::OpenHandle(this);
3011   i::Isolate* isolate = self->GetIsolate();
3012   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3013   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3014   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3015   return self->GetColumnNumber();
3016 }
3017 
GetWasmFunctionIndex() const3018 int Message::GetWasmFunctionIndex() const {
3019 #if V8_ENABLE_WEBASSEMBLY
3020   auto self = Utils::OpenHandle(this);
3021   i::Isolate* isolate = self->GetIsolate();
3022   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3023   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3024   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3025   int start_position = self->GetColumnNumber();
3026   if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
3027 
3028   i::Handle<i::Script> script(self->script(), isolate);
3029 
3030   if (script->type() != i::Script::TYPE_WASM) {
3031     return Message::kNoWasmFunctionIndexInfo;
3032   }
3033 
3034   auto debug_script = ToApiHandle<debug::Script>(script);
3035   return Local<debug::WasmScript>::Cast(debug_script)
3036       ->GetContainingFunction(start_position);
3037 #else
3038   return Message::kNoWasmFunctionIndexInfo;
3039 #endif  // V8_ENABLE_WEBASSEMBLY
3040 }
3041 
GetStartColumn(Local<Context> context) const3042 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3043   return Just(GetStartColumn());
3044 }
3045 
GetEndColumn() const3046 int Message::GetEndColumn() const {
3047   auto self = Utils::OpenHandle(this);
3048   i::Isolate* isolate = self->GetIsolate();
3049   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3050   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3051   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3052   const int column_number = self->GetColumnNumber();
3053   if (column_number == -1) return -1;
3054   const int start = self->GetStartPosition();
3055   const int end = self->GetEndPosition();
3056   return column_number + (end - start);
3057 }
3058 
GetEndColumn(Local<Context> context) const3059 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3060   return Just(GetEndColumn());
3061 }
3062 
IsSharedCrossOrigin() const3063 bool Message::IsSharedCrossOrigin() const {
3064   auto self = Utils::OpenHandle(this);
3065   i::Isolate* isolate = self->GetIsolate();
3066   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3067   return self->script().origin_options().IsSharedCrossOrigin();
3068 }
3069 
IsOpaque() const3070 bool Message::IsOpaque() const {
3071   auto self = Utils::OpenHandle(this);
3072   i::Isolate* isolate = self->GetIsolate();
3073   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3074   return self->script().origin_options().IsOpaque();
3075 }
3076 
GetSource(Local<Context> context) const3077 MaybeLocal<String> Message::GetSource(Local<Context> context) const {
3078   auto self = Utils::OpenHandle(this);
3079   i::Isolate* isolate = self->GetIsolate();
3080   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3081   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3082   i::Handle<i::String> source(self->GetSource(), isolate);
3083   RETURN_ESCAPED(Utils::ToLocal(source));
3084 }
3085 
GetSourceLine(Local<Context> context) const3086 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3087   auto self = Utils::OpenHandle(this);
3088   i::Isolate* isolate = self->GetIsolate();
3089   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3090   EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3091   i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3092   RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3093 }
3094 
PrintCurrentStackTrace(Isolate * isolate,FILE * out)3095 void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
3096   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3097   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3098   std::ostringstream stack_trace_stream;
3099   i_isolate->PrintCurrentStackTrace(stack_trace_stream);
3100   i::PrintF(out, "%s", stack_trace_stream.str().c_str());
3101 }
3102 
PrintCurrentStackTrace(Isolate * isolate,std::ostream & out)3103 void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) {
3104   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3105   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3106   i_isolate->PrintCurrentStackTrace(out);
3107 }
3108 
3109 // --- S t a c k T r a c e ---
3110 
GetFrame(Isolate * v8_isolate,uint32_t index) const3111 Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3112                                        uint32_t index) const {
3113   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3114   i::Handle<i::StackFrameInfo> frame(
3115       i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate);
3116   return Utils::StackFrameToLocal(frame);
3117 }
3118 
GetFrameCount() const3119 int StackTrace::GetFrameCount() const {
3120   return Utils::OpenHandle(this)->length();
3121 }
3122 
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3123 Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3124                                                 int frame_limit,
3125                                                 StackTraceOptions options) {
3126   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3127   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3128   i::Handle<i::FixedArray> stackTrace =
3129       i_isolate->CaptureCurrentStackTrace(frame_limit, options);
3130   return Utils::StackTraceToLocal(stackTrace);
3131 }
3132 
3133 // --- S t a c k F r a m e ---
3134 
GetLineNumber() const3135 int StackFrame::GetLineNumber() const {
3136   return i::StackFrameInfo::GetLineNumber(Utils::OpenHandle(this));
3137 }
3138 
GetColumn() const3139 int StackFrame::GetColumn() const {
3140   return i::StackFrameInfo::GetColumnNumber(Utils::OpenHandle(this));
3141 }
3142 
GetScriptId() const3143 int StackFrame::GetScriptId() const {
3144   return Utils::OpenHandle(this)->GetScriptId();
3145 }
3146 
GetScriptName() const3147 Local<String> StackFrame::GetScriptName() const {
3148   auto self = Utils::OpenHandle(this);
3149   auto isolate = self->GetIsolate();
3150   i::Handle<i::Object> name(self->GetScriptName(), isolate);
3151   if (!name->IsString()) return {};
3152   return Local<String>::Cast(Utils::ToLocal(name));
3153 }
3154 
GetScriptNameOrSourceURL() const3155 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3156   auto self = Utils::OpenHandle(this);
3157   auto isolate = self->GetIsolate();
3158   i::Handle<i::Object> name_or_url(self->GetScriptNameOrSourceURL(), isolate);
3159   if (!name_or_url->IsString()) return {};
3160   return Local<String>::Cast(Utils::ToLocal(name_or_url));
3161 }
3162 
GetScriptSource() const3163 Local<String> StackFrame::GetScriptSource() const {
3164   auto self = Utils::OpenHandle(this);
3165   auto isolate = self->GetIsolate();
3166   i::Handle<i::Object> source(self->GetScriptSource(), isolate);
3167   if (!source->IsString()) return {};
3168   return Local<String>::Cast(Utils::ToLocal(source));
3169 }
3170 
GetScriptSourceMappingURL() const3171 Local<String> StackFrame::GetScriptSourceMappingURL() const {
3172   auto self = Utils::OpenHandle(this);
3173   auto isolate = self->GetIsolate();
3174   i::Handle<i::Object> sourceMappingURL(self->GetScriptSourceMappingURL(),
3175                                         isolate);
3176   if (!sourceMappingURL->IsString()) return {};
3177   return Local<String>::Cast(Utils::ToLocal(sourceMappingURL));
3178 }
3179 
GetFunctionName() const3180 Local<String> StackFrame::GetFunctionName() const {
3181   auto self = Utils::OpenHandle(this);
3182   auto name = i::StackFrameInfo::GetFunctionName(self);
3183   if (!name->IsString()) return {};
3184   return Local<String>::Cast(Utils::ToLocal(name));
3185 }
3186 
IsEval() const3187 bool StackFrame::IsEval() const { return Utils::OpenHandle(this)->IsEval(); }
3188 
IsConstructor() const3189 bool StackFrame::IsConstructor() const {
3190   return Utils::OpenHandle(this)->IsConstructor();
3191 }
3192 
IsWasm() const3193 bool StackFrame::IsWasm() const {
3194 #if V8_ENABLE_WEBASSEMBLY
3195   return Utils::OpenHandle(this)->IsWasm();
3196 #else
3197   return false;
3198 #endif  // V8_ENABLE_WEBASSEMBLY
3199 }
3200 
IsUserJavaScript() const3201 bool StackFrame::IsUserJavaScript() const {
3202   return Utils::OpenHandle(this)->IsUserJavaScript();
3203 }
3204 
3205 // --- J S O N ---
3206 
Parse(Local<Context> context,Local<String> json_string)3207 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3208                               Local<String> json_string) {
3209   PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3210   i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3211   i::Handle<i::String> source = i::String::Flatten(isolate, string);
3212   i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3213   auto maybe = source->IsOneByteRepresentation()
3214                    ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3215                    : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3216   Local<Value> result;
3217   has_pending_exception = !ToLocal<Value>(maybe, &result);
3218   RETURN_ON_FAILED_EXECUTION(Value);
3219   RETURN_ESCAPED(result);
3220 }
3221 
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3222 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3223                                    Local<Value> json_object,
3224                                    Local<String> gap) {
3225   PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3226   i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3227   i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3228   i::Handle<i::String> gap_string = gap.IsEmpty()
3229                                         ? isolate->factory()->empty_string()
3230                                         : Utils::OpenHandle(*gap);
3231   i::Handle<i::Object> maybe;
3232   has_pending_exception =
3233       !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3234   RETURN_ON_FAILED_EXECUTION(String);
3235   Local<String> result;
3236   has_pending_exception =
3237       !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3238   RETURN_ON_FAILED_EXECUTION(String);
3239   RETURN_ESCAPED(result);
3240 }
3241 
3242 // --- V a l u e   S e r i a l i z a t i o n ---
3243 
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3244 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3245                                                        Local<Object> object) {
3246   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3247   isolate->ScheduleThrow(*isolate->factory()->NewError(
3248       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3249       Utils::OpenHandle(*object)));
3250   return Nothing<bool>();
3251 }
3252 
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3253 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3254     Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3255   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3256   isolate->ScheduleThrow(*isolate->factory()->NewError(
3257       isolate->error_function(), i::MessageTemplate::kDataCloneError,
3258       Utils::OpenHandle(*shared_array_buffer)));
3259   return Nothing<uint32_t>();
3260 }
3261 
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3262 Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3263     Isolate* v8_isolate, Local<WasmModuleObject> module) {
3264   return Nothing<uint32_t>();
3265 }
3266 
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3267 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3268                                                         size_t size,
3269                                                         size_t* actual_size) {
3270   *actual_size = size;
3271   return base::Realloc(old_buffer, size);
3272 }
3273 
FreeBufferMemory(void * buffer)3274 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3275   return base::Free(buffer);
3276 }
3277 
3278 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3279   explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3280       : isolate(i), serializer(i, delegate) {}
3281   i::Isolate* isolate;
3282   i::ValueSerializer serializer;
3283 };
3284 
ValueSerializer(Isolate * isolate)3285 ValueSerializer::ValueSerializer(Isolate* isolate)
3286     : ValueSerializer(isolate, nullptr) {}
3287 
ValueSerializer(Isolate * isolate,Delegate * delegate)3288 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3289     : private_(
3290           new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3291 
~ValueSerializer()3292 ValueSerializer::~ValueSerializer() { delete private_; }
3293 
WriteHeader()3294 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3295 
SetTreatArrayBufferViewsAsHostObjects(bool mode)3296 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3297   private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3298 }
3299 
WriteValue(Local<Context> context,Local<Value> value)3300 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3301                                         Local<Value> value) {
3302   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3303   ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3304            i::HandleScope);
3305   i::Handle<i::Object> object = Utils::OpenHandle(*value);
3306   Maybe<bool> result = private_->serializer.WriteObject(object);
3307   has_pending_exception = result.IsNothing();
3308   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3309   return result;
3310 }
3311 
Release()3312 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3313   return private_->serializer.Release();
3314 }
3315 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3316 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3317                                           Local<ArrayBuffer> array_buffer) {
3318   private_->serializer.TransferArrayBuffer(transfer_id,
3319                                            Utils::OpenHandle(*array_buffer));
3320 }
3321 
WriteUint32(uint32_t value)3322 void ValueSerializer::WriteUint32(uint32_t value) {
3323   private_->serializer.WriteUint32(value);
3324 }
3325 
WriteUint64(uint64_t value)3326 void ValueSerializer::WriteUint64(uint64_t value) {
3327   private_->serializer.WriteUint64(value);
3328 }
3329 
WriteDouble(double value)3330 void ValueSerializer::WriteDouble(double value) {
3331   private_->serializer.WriteDouble(value);
3332 }
3333 
WriteRawBytes(const void * source,size_t length)3334 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3335   private_->serializer.WriteRawBytes(source, length);
3336 }
3337 
ReadHostObject(Isolate * v8_isolate)3338 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3339     Isolate* v8_isolate) {
3340   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3341   isolate->ScheduleThrow(*isolate->factory()->NewError(
3342       isolate->error_function(),
3343       i::MessageTemplate::kDataCloneDeserializationError));
3344   return MaybeLocal<Object>();
3345 }
3346 
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3347 MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3348     Isolate* v8_isolate, uint32_t id) {
3349   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3350   isolate->ScheduleThrow(*isolate->factory()->NewError(
3351       isolate->error_function(),
3352       i::MessageTemplate::kDataCloneDeserializationError));
3353   return MaybeLocal<WasmModuleObject>();
3354 }
3355 
3356 MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3357 ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3358                                                         uint32_t id) {
3359   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3360   isolate->ScheduleThrow(*isolate->factory()->NewError(
3361       isolate->error_function(),
3362       i::MessageTemplate::kDataCloneDeserializationError));
3363   return MaybeLocal<SharedArrayBuffer>();
3364 }
3365 
3366 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3367   PrivateData(i::Isolate* i, base::Vector<const uint8_t> data,
3368               Delegate* delegate)
3369       : isolate(i), deserializer(i, data, delegate) {}
3370   i::Isolate* isolate;
3371   i::ValueDeserializer deserializer;
3372   bool supports_legacy_wire_format = false;
3373 };
3374 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3375 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3376                                      size_t size)
3377     : ValueDeserializer(isolate, data, size, nullptr) {}
3378 
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3379 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3380                                      size_t size, Delegate* delegate) {
3381   private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3382                              base::Vector<const uint8_t>(data, size), delegate);
3383 }
3384 
~ValueDeserializer()3385 ValueDeserializer::~ValueDeserializer() { delete private_; }
3386 
ReadHeader(Local<Context> context)3387 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3388   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3389   ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3390                      Nothing<bool>(), i::HandleScope);
3391 
3392   bool read_header = false;
3393   has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3394   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3395   DCHECK(read_header);
3396 
3397   static const uint32_t kMinimumNonLegacyVersion = 13;
3398   if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3399       !private_->supports_legacy_wire_format) {
3400     isolate->Throw(*isolate->factory()->NewError(
3401         i::MessageTemplate::kDataCloneDeserializationVersionError));
3402     has_pending_exception = true;
3403     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3404   }
3405 
3406   return Just(true);
3407 }
3408 
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3409 void ValueDeserializer::SetSupportsLegacyWireFormat(
3410     bool supports_legacy_wire_format) {
3411   private_->supports_legacy_wire_format = supports_legacy_wire_format;
3412 }
3413 
GetWireFormatVersion() const3414 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3415   return private_->deserializer.GetWireFormatVersion();
3416 }
3417 
ReadValue(Local<Context> context)3418 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3419   PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3420   i::MaybeHandle<i::Object> result;
3421   if (GetWireFormatVersion() > 0) {
3422     result = private_->deserializer.ReadObject();
3423   } else {
3424     result =
3425         private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3426   }
3427   Local<Value> value;
3428   has_pending_exception = !ToLocal(result, &value);
3429   RETURN_ON_FAILED_EXECUTION(Value);
3430   RETURN_ESCAPED(value);
3431 }
3432 
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3433 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3434                                             Local<ArrayBuffer> array_buffer) {
3435   private_->deserializer.TransferArrayBuffer(transfer_id,
3436                                              Utils::OpenHandle(*array_buffer));
3437 }
3438 
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3439 void ValueDeserializer::TransferSharedArrayBuffer(
3440     uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3441   private_->deserializer.TransferArrayBuffer(
3442       transfer_id, Utils::OpenHandle(*shared_array_buffer));
3443 }
3444 
ReadUint32(uint32_t * value)3445 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3446   return private_->deserializer.ReadUint32(value);
3447 }
3448 
ReadUint64(uint64_t * value)3449 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3450   return private_->deserializer.ReadUint64(value);
3451 }
3452 
ReadDouble(double * value)3453 bool ValueDeserializer::ReadDouble(double* value) {
3454   return private_->deserializer.ReadDouble(value);
3455 }
3456 
ReadRawBytes(size_t length,const void ** data)3457 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3458   return private_->deserializer.ReadRawBytes(length, data);
3459 }
3460 
3461 // --- D a t a ---
3462 
FullIsUndefined() const3463 bool Value::FullIsUndefined() const {
3464   i::Handle<i::Object> object = Utils::OpenHandle(this);
3465   bool result = object->IsUndefined();
3466   DCHECK_EQ(result, QuickIsUndefined());
3467   return result;
3468 }
3469 
FullIsNull() const3470 bool Value::FullIsNull() const {
3471   i::Handle<i::Object> object = Utils::OpenHandle(this);
3472   bool result = object->IsNull();
3473   DCHECK_EQ(result, QuickIsNull());
3474   return result;
3475 }
3476 
IsTrue() const3477 bool Value::IsTrue() const {
3478   i::Object object = *Utils::OpenHandle(this);
3479   if (object.IsSmi()) return false;
3480   return object.IsTrue();
3481 }
3482 
IsFalse() const3483 bool Value::IsFalse() const {
3484   i::Object object = *Utils::OpenHandle(this);
3485   if (object.IsSmi()) return false;
3486   return object.IsFalse();
3487 }
3488 
IsFunction() const3489 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3490 
IsName() const3491 bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3492 
FullIsString() const3493 bool Value::FullIsString() const {
3494   bool result = Utils::OpenHandle(this)->IsString();
3495   DCHECK_EQ(result, QuickIsString());
3496   return result;
3497 }
3498 
IsSymbol() const3499 bool Value::IsSymbol() const {
3500   return Utils::OpenHandle(this)->IsPublicSymbol();
3501 }
3502 
IsArray() const3503 bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3504 
IsArrayBuffer() const3505 bool Value::IsArrayBuffer() const {
3506   i::Object obj = *Utils::OpenHandle(this);
3507   if (!obj.IsJSArrayBuffer()) return false;
3508   return !i::JSArrayBuffer::cast(obj).is_shared();
3509 }
3510 
IsArrayBufferView() const3511 bool Value::IsArrayBufferView() const {
3512   return Utils::OpenHandle(this)->IsJSArrayBufferView();
3513 }
3514 
IsTypedArray() const3515 bool Value::IsTypedArray() const {
3516   return Utils::OpenHandle(this)->IsJSTypedArray();
3517 }
3518 
3519 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype)                   \
3520   bool Value::Is##Type##Array() const {                                     \
3521     i::Handle<i::Object> obj = Utils::OpenHandle(this);                     \
3522     return obj->IsJSTypedArray() &&                                         \
3523            i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3524   }
3525 
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3526 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3527 
3528 #undef VALUE_IS_TYPED_ARRAY
3529 
3530 bool Value::IsDataView() const {
3531   return Utils::OpenHandle(this)->IsJSDataView();
3532 }
3533 
IsSharedArrayBuffer() const3534 bool Value::IsSharedArrayBuffer() const {
3535   i::Object obj = *Utils::OpenHandle(this);
3536   if (!obj.IsJSArrayBuffer()) return false;
3537   return i::JSArrayBuffer::cast(obj).is_shared();
3538 }
3539 
IsObject() const3540 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3541 
IsNumber() const3542 bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3543 
IsBigInt() const3544 bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3545 
IsProxy() const3546 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3547 
3548 #define VALUE_IS_SPECIFIC_TYPE(Type, Check)             \
3549   bool Value::Is##Type() const {                        \
3550     i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3551     return obj->Is##Check();                            \
3552   }
3553 
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3554 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3555 VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3556 VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3557 VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3558 VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3559 VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3560 VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3561 VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3562 VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3563 #if V8_ENABLE_WEBASSEMBLY
3564 VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3565 VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3566 #else
3567 bool Value::IsWasmMemoryObject() const { return false; }
3568 bool Value::IsWasmModuleObject() const { return false; }
3569 #endif  // V8_ENABLE_WEBASSEMBLY
3570 VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3571 VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3572 
3573 #undef VALUE_IS_SPECIFIC_TYPE
3574 
3575 bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3576 
IsExternal() const3577 bool Value::IsExternal() const {
3578   i::Object obj = *Utils::OpenHandle(this);
3579   if (!obj.IsHeapObject()) return false;
3580   i::HeapObject heap_obj = i::HeapObject::cast(obj);
3581   // Check the instance type is JS_OBJECT (instance type of Externals) before
3582   // attempting to get the Isolate since that guarantees the object is writable
3583   // and GetIsolate will work.
3584   if (heap_obj.map().instance_type() != i::JS_OBJECT_TYPE) return false;
3585   i::Isolate* isolate = i::JSObject::cast(heap_obj).GetIsolate();
3586   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3587   return heap_obj.IsExternal(isolate);
3588 }
3589 
IsInt32() const3590 bool Value::IsInt32() const {
3591   i::Object obj = *Utils::OpenHandle(this);
3592   if (obj.IsSmi()) return true;
3593   if (obj.IsNumber()) {
3594     return i::IsInt32Double(obj.Number());
3595   }
3596   return false;
3597 }
3598 
IsUint32() const3599 bool Value::IsUint32() const {
3600   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3601   if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3602   if (obj->IsNumber()) {
3603     double value = obj->Number();
3604     return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3605            value == i::FastUI2D(i::FastD2UI(value));
3606   }
3607   return false;
3608 }
3609 
IsNativeError() const3610 bool Value::IsNativeError() const {
3611   return Utils::OpenHandle(this)->IsJSError();
3612 }
3613 
IsRegExp() const3614 bool Value::IsRegExp() const {
3615   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3616   return obj->IsJSRegExp();
3617 }
3618 
IsAsyncFunction() const3619 bool Value::IsAsyncFunction() const {
3620   i::Object obj = *Utils::OpenHandle(this);
3621   if (!obj.IsJSFunction()) return false;
3622   i::JSFunction func = i::JSFunction::cast(obj);
3623   return i::IsAsyncFunction(func.shared().kind());
3624 }
3625 
IsGeneratorFunction() const3626 bool Value::IsGeneratorFunction() const {
3627   i::Object obj = *Utils::OpenHandle(this);
3628   if (!obj.IsJSFunction()) return false;
3629   i::JSFunction func = i::JSFunction::cast(obj);
3630   ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
3631   return i::IsGeneratorFunction(func.shared().kind());
3632 }
3633 
IsGeneratorObject() const3634 bool Value::IsGeneratorObject() const {
3635   return Utils::OpenHandle(this)->IsJSGeneratorObject();
3636 }
3637 
IsMapIterator() const3638 bool Value::IsMapIterator() const {
3639   return Utils::OpenHandle(this)->IsJSMapIterator();
3640 }
3641 
IsSetIterator() const3642 bool Value::IsSetIterator() const {
3643   return Utils::OpenHandle(this)->IsJSSetIterator();
3644 }
3645 
IsPromise() const3646 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3647 
IsModuleNamespaceObject() const3648 bool Value::IsModuleNamespaceObject() const {
3649   return Utils::OpenHandle(this)->IsJSModuleNamespace();
3650 }
3651 
ToString(Local<Context> context) const3652 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3653   auto obj = Utils::OpenHandle(this);
3654   if (obj->IsString()) return ToApiHandle<String>(obj);
3655   PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3656   Local<String> result;
3657   has_pending_exception =
3658       !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3659   RETURN_ON_FAILED_EXECUTION(String);
3660   RETURN_ESCAPED(result);
3661 }
3662 
ToDetailString(Local<Context> context) const3663 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3664   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3665   if (obj->IsString()) return ToApiHandle<String>(obj);
3666   PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3667   Local<String> result =
3668       Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3669   RETURN_ON_FAILED_EXECUTION(String);
3670   RETURN_ESCAPED(result);
3671 }
3672 
ToObject(Local<Context> context) const3673 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3674   auto obj = Utils::OpenHandle(this);
3675   if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3676   PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3677   Local<Object> result;
3678   has_pending_exception =
3679       !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3680   RETURN_ON_FAILED_EXECUTION(Object);
3681   RETURN_ESCAPED(result);
3682 }
3683 
ToBigInt(Local<Context> context) const3684 MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3685   i::Handle<i::Object> obj = Utils::OpenHandle(this);
3686   if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3687   PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3688   Local<BigInt> result;
3689   has_pending_exception =
3690       !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3691   RETURN_ON_FAILED_EXECUTION(BigInt);
3692   RETURN_ESCAPED(result);
3693 }
3694 
BooleanValue(Isolate * v8_isolate) const3695 bool Value::BooleanValue(Isolate* v8_isolate) const {
3696   return Utils::OpenHandle(this)->BooleanValue(
3697       reinterpret_cast<i::Isolate*>(v8_isolate));
3698 }
3699 
ToBoolean(Isolate * v8_isolate) const3700 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3701   auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3702   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3703   return ToApiHandle<Boolean>(
3704       isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3705 }
3706 
ToNumber(Local<Context> context) const3707 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3708   auto obj = Utils::OpenHandle(this);
3709   if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3710   PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3711   Local<Number> result;
3712   has_pending_exception =
3713       !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3714   RETURN_ON_FAILED_EXECUTION(Number);
3715   RETURN_ESCAPED(result);
3716 }
3717 
ToInteger(Local<Context> context) const3718 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3719   auto obj = Utils::OpenHandle(this);
3720   if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3721   PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3722   Local<Integer> result;
3723   has_pending_exception =
3724       !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3725   RETURN_ON_FAILED_EXECUTION(Integer);
3726   RETURN_ESCAPED(result);
3727 }
3728 
ToInt32(Local<Context> context) const3729 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3730   auto obj = Utils::OpenHandle(this);
3731   if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3732   Local<Int32> result;
3733   PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3734   has_pending_exception =
3735       !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3736   RETURN_ON_FAILED_EXECUTION(Int32);
3737   RETURN_ESCAPED(result);
3738 }
3739 
ToUint32(Local<Context> context) const3740 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3741   auto obj = Utils::OpenHandle(this);
3742   if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3743   Local<Uint32> result;
3744   PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3745   has_pending_exception =
3746       !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3747   RETURN_ON_FAILED_EXECUTION(Uint32);
3748   RETURN_ESCAPED(result);
3749 }
3750 
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3751 i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3752                                         i::ExternalPointer_t encoded_pointer,
3753                                         ExternalPointerTag tag) {
3754   return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3755 }
3756 
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3757 i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3758   return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3759 }
3760 
ShouldThrowOnError(i::Isolate * isolate)3761 bool i::ShouldThrowOnError(i::Isolate* isolate) {
3762   return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3763          i::ShouldThrow::kThrowOnError;
3764 }
3765 
CanHaveInternalField(int instance_type)3766 bool i::CanHaveInternalField(int instance_type) {
3767   return instance_type == i::Internals::kJSObjectType ||
3768          instance_type == i::Internals::kJSSpecialApiObjectType ||
3769          v8::internal::InstanceTypeChecker::IsJSApiObject(
3770              static_cast<v8::internal::InstanceType>(instance_type));
3771 }
3772 
CheckInitializedImpl(v8::Isolate * external_isolate)3773 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3774   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3775   Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3776                   "v8::internal::Internals::CheckInitialized",
3777                   "Isolate is not initialized or V8 has died");
3778 }
3779 
CheckCast(Data * that)3780 void v8::Value::CheckCast(Data* that) {
3781   Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3782 }
3783 
CheckCast(v8::Value * that)3784 void External::CheckCast(v8::Value* that) {
3785   Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3786                   "Value is not an External");
3787 }
3788 
CheckCast(Value * that)3789 void v8::Object::CheckCast(Value* that) {
3790   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3791   Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3792                   "Value is not an Object");
3793 }
3794 
CheckCast(Value * that)3795 void v8::Function::CheckCast(Value* that) {
3796   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3797   Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3798                   "Value is not a Function");
3799 }
3800 
CheckCast(v8::Data * that)3801 void v8::Boolean::CheckCast(v8::Data* that) {
3802   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3803   Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3804                   "Value is not a Boolean");
3805 }
3806 
CheckCast(v8::Data * that)3807 void v8::Name::CheckCast(v8::Data* that) {
3808   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3809   Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3810 }
3811 
CheckCast(v8::Data * that)3812 void v8::String::CheckCast(v8::Data* that) {
3813   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3814   Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3815 }
3816 
CheckCast(v8::Data * that)3817 void v8::Symbol::CheckCast(v8::Data* that) {
3818   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3819   Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3820 }
3821 
CheckCast(v8::Data * that)3822 void v8::Private::CheckCast(v8::Data* that) {
3823   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3824   Utils::ApiCheck(
3825       obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3826       "v8::Private::Cast", "Value is not a Private");
3827 }
3828 
CheckCast(v8::Data * that)3829 void v8::ModuleRequest::CheckCast(v8::Data* that) {
3830   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3831   Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast",
3832                   "Value is not a ModuleRequest");
3833 }
3834 
CheckCast(v8::Data * that)3835 void v8::Module::CheckCast(v8::Data* that) {
3836   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3837   Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3838 }
3839 
CheckCast(v8::Data * that)3840 void v8::Number::CheckCast(v8::Data* that) {
3841   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3842   Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3843                   "Value is not a Number");
3844 }
3845 
CheckCast(v8::Data * that)3846 void v8::Integer::CheckCast(v8::Data* that) {
3847   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3848   Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3849                   "Value is not an Integer");
3850 }
3851 
CheckCast(v8::Data * that)3852 void v8::Int32::CheckCast(v8::Data* that) {
3853   Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast",
3854                   "Value is not a 32-bit signed integer");
3855 }
3856 
CheckCast(v8::Data * that)3857 void v8::Uint32::CheckCast(v8::Data* that) {
3858   Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast",
3859                   "Value is not a 32-bit unsigned integer");
3860 }
3861 
CheckCast(v8::Data * that)3862 void v8::BigInt::CheckCast(v8::Data* that) {
3863   Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3864                   "Value is not a BigInt");
3865 }
3866 
CheckCast(v8::Data * that)3867 void v8::Context::CheckCast(v8::Data* that) {
3868   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3869   Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast",
3870                   "Value is not a Context");
3871 }
3872 
CheckCast(Value * that)3873 void v8::Array::CheckCast(Value* that) {
3874   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3875   Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3876 }
3877 
CheckCast(Value * that)3878 void v8::Map::CheckCast(Value* that) {
3879   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3880   Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3881 }
3882 
CheckCast(Value * that)3883 void v8::Set::CheckCast(Value* that) {
3884   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3885   Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3886 }
3887 
CheckCast(Value * that)3888 void v8::Promise::CheckCast(Value* that) {
3889   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3890                   "Value is not a Promise");
3891 }
3892 
CheckCast(Value * that)3893 void v8::Promise::Resolver::CheckCast(Value* that) {
3894   Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3895                   "Value is not a Promise::Resolver");
3896 }
3897 
CheckCast(Value * that)3898 void v8::Proxy::CheckCast(Value* that) {
3899   Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3900 }
3901 
CheckCast(Value * that)3902 void v8::WasmMemoryObject::CheckCast(Value* that) {
3903   Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3904                   "Value is not a WasmMemoryObject");
3905 }
3906 
CheckCast(Value * that)3907 void v8::WasmModuleObject::CheckCast(Value* that) {
3908   Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3909                   "Value is not a WasmModuleObject");
3910 }
3911 
~BackingStore()3912 v8::BackingStore::~BackingStore() {
3913   auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3914   i_this->~BackingStore();  // manually call internal destructor
3915 }
3916 
Data() const3917 void* v8::BackingStore::Data() const {
3918   return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3919 }
3920 
ByteLength() const3921 size_t v8::BackingStore::ByteLength() const {
3922   return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
3923 }
3924 
IsShared() const3925 bool v8::BackingStore::IsShared() const {
3926   return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
3927 }
3928 
3929 // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)3930 std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
3931     v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
3932     size_t byte_length) {
3933   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3934   LOG_API(i_isolate, ArrayBuffer, BackingStore_Reallocate);
3935   Utils::ApiCheck(byte_length <= i::JSArrayBuffer::kMaxByteLength,
3936                   "v8::BackingStore::Reallocate", "byte_lenght is too large");
3937   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3938   i::BackingStore* i_backing_store =
3939       reinterpret_cast<i::BackingStore*>(backing_store.get());
3940   if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
3941     i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
3942   }
3943   return backing_store;
3944 }
3945 
3946 // static
EmptyDeleter(void * data,size_t length,void * deleter_data)3947 void v8::BackingStore::EmptyDeleter(void* data, size_t length,
3948                                     void* deleter_data) {
3949   DCHECK_NULL(deleter_data);
3950 }
3951 
GetBackingStore()3952 std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
3953   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
3954   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
3955   if (!backing_store) {
3956     backing_store =
3957         i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
3958   }
3959   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
3960   return std::static_pointer_cast<v8::BackingStore>(bs_base);
3961 }
3962 
GetBackingStore()3963 std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
3964   i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
3965   std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
3966   if (!backing_store) {
3967     backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
3968   }
3969   std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
3970   return std::static_pointer_cast<v8::BackingStore>(bs_base);
3971 }
3972 
CheckCast(Value * that)3973 void v8::ArrayBuffer::CheckCast(Value* that) {
3974   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3975   Utils::ApiCheck(
3976       obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
3977       "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
3978 }
3979 
CheckCast(Value * that)3980 void v8::ArrayBufferView::CheckCast(Value* that) {
3981   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3982   Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
3983                   "Value is not an ArrayBufferView");
3984 }
3985 
3986 constexpr size_t v8::TypedArray::kMaxLength;
3987 
CheckCast(Value * that)3988 void v8::TypedArray::CheckCast(Value* that) {
3989   i::Handle<i::Object> obj = Utils::OpenHandle(that);
3990   Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
3991                   "Value is not a TypedArray");
3992 }
3993 
3994 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype)                  \
3995   void v8::Type##Array::CheckCast(Value* that) {                             \
3996     i::Handle<i::Object> obj = Utils::OpenHandle(that);                      \
3997     Utils::ApiCheck(                                                         \
3998         obj->IsJSTypedArray() &&                                             \
3999             i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
4000         "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array");      \
4001   }
4002 
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)4003 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4004 
4005 #undef CHECK_TYPED_ARRAY_CAST
4006 
4007 void v8::DataView::CheckCast(Value* that) {
4008   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4009   Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
4010                   "Value is not a DataView");
4011 }
4012 
CheckCast(Value * that)4013 void v8::SharedArrayBuffer::CheckCast(Value* that) {
4014   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4015   Utils::ApiCheck(
4016       obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
4017       "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
4018 }
4019 
CheckCast(v8::Value * that)4020 void v8::Date::CheckCast(v8::Value* that) {
4021   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4022   Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
4023 }
4024 
CheckCast(v8::Value * that)4025 void v8::StringObject::CheckCast(v8::Value* that) {
4026   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4027   Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
4028                   "Value is not a StringObject");
4029 }
4030 
CheckCast(v8::Value * that)4031 void v8::SymbolObject::CheckCast(v8::Value* that) {
4032   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4033   Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
4034                   "Value is not a SymbolObject");
4035 }
4036 
CheckCast(v8::Value * that)4037 void v8::NumberObject::CheckCast(v8::Value* that) {
4038   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4039   Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
4040                   "Value is not a NumberObject");
4041 }
4042 
CheckCast(v8::Value * that)4043 void v8::BigIntObject::CheckCast(v8::Value* that) {
4044   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4045   Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
4046                   "Value is not a BigIntObject");
4047 }
4048 
CheckCast(v8::Value * that)4049 void v8::BooleanObject::CheckCast(v8::Value* that) {
4050   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4051   Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
4052                   "Value is not a BooleanObject");
4053 }
4054 
CheckCast(v8::Value * that)4055 void v8::RegExp::CheckCast(v8::Value* that) {
4056   i::Handle<i::Object> obj = Utils::OpenHandle(that);
4057   Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
4058                   "Value is not a RegExp");
4059 }
4060 
NumberValue(Local<Context> context) const4061 Maybe<double> Value::NumberValue(Local<Context> context) const {
4062   auto obj = Utils::OpenHandle(this);
4063   if (obj->IsNumber()) return Just(obj->Number());
4064   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4065   ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4066            i::HandleScope);
4067   i::Handle<i::Object> num;
4068   has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
4069   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4070   return Just(num->Number());
4071 }
4072 
IntegerValue(Local<Context> context) const4073 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4074   auto obj = Utils::OpenHandle(this);
4075   if (obj->IsNumber()) {
4076     return Just(NumberToInt64(*obj));
4077   }
4078   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4079   ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4080            i::HandleScope);
4081   i::Handle<i::Object> num;
4082   has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4083   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4084   return Just(NumberToInt64(*num));
4085 }
4086 
Int32Value(Local<Context> context) const4087 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4088   auto obj = Utils::OpenHandle(this);
4089   if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4090   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4091   ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4092            i::HandleScope);
4093   i::Handle<i::Object> num;
4094   has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4095   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4096   return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4097                            : static_cast<int32_t>(num->Number()));
4098 }
4099 
Uint32Value(Local<Context> context) const4100 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4101   auto obj = Utils::OpenHandle(this);
4102   if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4103   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4104   ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4105            i::HandleScope);
4106   i::Handle<i::Object> num;
4107   has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4108   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4109   return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4110                            : static_cast<uint32_t>(num->Number()));
4111 }
4112 
ToArrayIndex(Local<Context> context) const4113 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4114   auto self = Utils::OpenHandle(this);
4115   if (self->IsSmi()) {
4116     if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4117     return Local<Uint32>();
4118   }
4119   PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4120   i::Handle<i::Object> string_obj;
4121   has_pending_exception =
4122       !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4123   RETURN_ON_FAILED_EXECUTION(Uint32);
4124   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4125   uint32_t index;
4126   if (str->AsArrayIndex(&index)) {
4127     i::Handle<i::Object> value;
4128     if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4129       value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4130     } else {
4131       value = isolate->factory()->NewNumber(index);
4132     }
4133     RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4134   }
4135   return Local<Uint32>();
4136 }
4137 
Equals(Local<Context> context,Local<Value> that) const4138 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4139   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4140   ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope);
4141   auto self = Utils::OpenHandle(this);
4142   auto other = Utils::OpenHandle(*that);
4143   Maybe<bool> result = i::Object::Equals(isolate, self, other);
4144   has_pending_exception = result.IsNothing();
4145   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4146   return result;
4147 }
4148 
StrictEquals(Local<Value> that) const4149 bool Value::StrictEquals(Local<Value> that) const {
4150   auto self = Utils::OpenHandle(this);
4151   auto other = Utils::OpenHandle(*that);
4152   return self->StrictEquals(*other);
4153 }
4154 
SameValue(Local<Value> that) const4155 bool Value::SameValue(Local<Value> that) const {
4156   auto self = Utils::OpenHandle(this);
4157   auto other = Utils::OpenHandle(*that);
4158   return self->SameValue(*other);
4159 }
4160 
TypeOf(v8::Isolate * external_isolate)4161 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4162   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4163   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4164   LOG_API(isolate, Value, TypeOf);
4165   return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4166 }
4167 
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4168 Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4169                               v8::Local<v8::Object> object) {
4170   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4171   ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4172            i::HandleScope);
4173   auto left = Utils::OpenHandle(this);
4174   auto right = Utils::OpenHandle(*object);
4175   i::Handle<i::Object> result;
4176   has_pending_exception =
4177       !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4178   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4179   return Just(result->IsTrue(isolate));
4180 }
4181 
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4182 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4183                             v8::Local<Value> key, v8::Local<Value> value) {
4184   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4185   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4186   auto self = Utils::OpenHandle(this);
4187   auto key_obj = Utils::OpenHandle(*key);
4188   auto value_obj = Utils::OpenHandle(*value);
4189   has_pending_exception =
4190       i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4191                                     i::StoreOrigin::kMaybeKeyed,
4192                                     Just(i::ShouldThrow::kDontThrow))
4193           .is_null();
4194   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4195   return Just(true);
4196 }
4197 
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4198 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4199                             v8::Local<Value> value) {
4200   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4201   ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4202   auto self = Utils::OpenHandle(this);
4203   auto value_obj = Utils::OpenHandle(*value);
4204   has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4205                                                 i::ShouldThrow::kDontThrow)
4206                               .is_null();
4207   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4208   return Just(true);
4209 }
4210 
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4211 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4212                                            v8::Local<Name> key,
4213                                            v8::Local<Value> value) {
4214   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4215   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4216   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4217   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4218 
4219   i::PropertyKey lookup_key(isolate, key_obj);
4220   i::LookupIterator it(isolate, self, lookup_key, i::LookupIterator::OWN);
4221   if (self->IsJSProxy()) {
4222     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4223              i::HandleScope);
4224     Maybe<bool> result =
4225         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4226     has_pending_exception = result.IsNothing();
4227     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4228     return result;
4229   } else {
4230     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4231                        Nothing<bool>(), i::HandleScope);
4232     Maybe<bool> result =
4233         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4234     has_pending_exception = result.IsNothing();
4235     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4236     return result;
4237   }
4238 }
4239 
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4240 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4241                                            uint32_t index,
4242                                            v8::Local<Value> value) {
4243   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4244   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4245   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4246 
4247   i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4248   if (self->IsJSProxy()) {
4249     ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4250              i::HandleScope);
4251     Maybe<bool> result =
4252         i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4253     has_pending_exception = result.IsNothing();
4254     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4255     return result;
4256   } else {
4257     ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4258                        Nothing<bool>(), i::HandleScope);
4259     Maybe<bool> result =
4260         i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4261     has_pending_exception = result.IsNothing();
4262     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4263     return result;
4264   }
4265 }
4266 
4267 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4268   PrivateData() : desc() {}
4269   i::PropertyDescriptor desc;
4270 };
4271 
PropertyDescriptor()4272 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4273 
4274 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4275 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4276     : private_(new PrivateData()) {
4277   private_->desc.set_value(Utils::OpenHandle(*value, true));
4278 }
4279 
4280 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4281 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4282                                            bool writable)
4283     : private_(new PrivateData()) {
4284   private_->desc.set_value(Utils::OpenHandle(*value, true));
4285   private_->desc.set_writable(writable);
4286 }
4287 
4288 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4289 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4290                                            v8::Local<v8::Value> set)
4291     : private_(new PrivateData()) {
4292   DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4293   DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4294   private_->desc.set_get(Utils::OpenHandle(*get, true));
4295   private_->desc.set_set(Utils::OpenHandle(*set, true));
4296 }
4297 
~PropertyDescriptor()4298 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4299 
value() const4300 v8::Local<Value> v8::PropertyDescriptor::value() const {
4301   DCHECK(private_->desc.has_value());
4302   return Utils::ToLocal(private_->desc.value());
4303 }
4304 
get() const4305 v8::Local<Value> v8::PropertyDescriptor::get() const {
4306   DCHECK(private_->desc.has_get());
4307   return Utils::ToLocal(private_->desc.get());
4308 }
4309 
set() const4310 v8::Local<Value> v8::PropertyDescriptor::set() const {
4311   DCHECK(private_->desc.has_set());
4312   return Utils::ToLocal(private_->desc.set());
4313 }
4314 
has_value() const4315 bool v8::PropertyDescriptor::has_value() const {
4316   return private_->desc.has_value();
4317 }
has_get() const4318 bool v8::PropertyDescriptor::has_get() const {
4319   return private_->desc.has_get();
4320 }
has_set() const4321 bool v8::PropertyDescriptor::has_set() const {
4322   return private_->desc.has_set();
4323 }
4324 
writable() const4325 bool v8::PropertyDescriptor::writable() const {
4326   DCHECK(private_->desc.has_writable());
4327   return private_->desc.writable();
4328 }
4329 
has_writable() const4330 bool v8::PropertyDescriptor::has_writable() const {
4331   return private_->desc.has_writable();
4332 }
4333 
set_enumerable(bool enumerable)4334 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4335   private_->desc.set_enumerable(enumerable);
4336 }
4337 
enumerable() const4338 bool v8::PropertyDescriptor::enumerable() const {
4339   DCHECK(private_->desc.has_enumerable());
4340   return private_->desc.enumerable();
4341 }
4342 
has_enumerable() const4343 bool v8::PropertyDescriptor::has_enumerable() const {
4344   return private_->desc.has_enumerable();
4345 }
4346 
set_configurable(bool configurable)4347 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4348   private_->desc.set_configurable(configurable);
4349 }
4350 
configurable() const4351 bool v8::PropertyDescriptor::configurable() const {
4352   DCHECK(private_->desc.has_configurable());
4353   return private_->desc.configurable();
4354 }
4355 
has_configurable() const4356 bool v8::PropertyDescriptor::has_configurable() const {
4357   return private_->desc.has_configurable();
4358 }
4359 
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4360 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4361                                           v8::Local<Name> key,
4362                                           v8::Local<Value> value,
4363                                           v8::PropertyAttribute attributes) {
4364   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4365   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4366   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4367   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4368 
4369   i::PropertyDescriptor desc;
4370   desc.set_writable(!(attributes & v8::ReadOnly));
4371   desc.set_enumerable(!(attributes & v8::DontEnum));
4372   desc.set_configurable(!(attributes & v8::DontDelete));
4373   desc.set_value(value_obj);
4374 
4375   if (self->IsJSProxy()) {
4376     ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4377              i::HandleScope);
4378     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4379         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4380     // Even though we said kDontThrow, there might be accessors that do throw.
4381     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4382     return success;
4383   } else {
4384     // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4385     // a script.
4386     ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4387                        Nothing<bool>(), i::HandleScope);
4388     Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4389         isolate, self, key_obj, &desc, Just(i::kDontThrow));
4390     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4391     return success;
4392   }
4393 }
4394 
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4395 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4396                                        v8::Local<Name> key,
4397                                        PropertyDescriptor& descriptor) {
4398   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4399   ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4400            i::HandleScope);
4401   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4402   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4403 
4404   Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4405       isolate, self, key_obj, &descriptor.get_private()->desc,
4406       Just(i::kDontThrow));
4407   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4408   return success;
4409 }
4410 
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4411 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4412                                    Local<Value> value) {
4413   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4414   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4415                      i::HandleScope);
4416   auto self = Utils::OpenHandle(this);
4417   auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4418   auto value_obj = Utils::OpenHandle(*value);
4419   if (self->IsJSProxy()) {
4420     i::PropertyDescriptor desc;
4421     desc.set_writable(true);
4422     desc.set_enumerable(false);
4423     desc.set_configurable(true);
4424     desc.set_value(value_obj);
4425     return i::JSProxy::SetPrivateSymbol(
4426         isolate, i::Handle<i::JSProxy>::cast(self),
4427         i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4428   }
4429   auto js_object = i::Handle<i::JSObject>::cast(self);
4430   i::LookupIterator it(isolate, js_object, key_obj, js_object);
4431   has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4432                               &it, value_obj, i::DONT_ENUM)
4433                               .is_null();
4434   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4435   return Just(true);
4436 }
4437 
Get(Local<v8::Context> context,Local<Value> key)4438 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4439                                   Local<Value> key) {
4440   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4441   auto self = Utils::OpenHandle(this);
4442   auto key_obj = Utils::OpenHandle(*key);
4443   i::Handle<i::Object> result;
4444   has_pending_exception =
4445       !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4446   RETURN_ON_FAILED_EXECUTION(Value);
4447   RETURN_ESCAPED(Utils::ToLocal(result));
4448 }
4449 
Get(Local<Context> context,uint32_t index)4450 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4451   PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4452   auto self = Utils::OpenHandle(this);
4453   i::Handle<i::Object> result;
4454   has_pending_exception =
4455       !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4456   RETURN_ON_FAILED_EXECUTION(Value);
4457   RETURN_ESCAPED(Utils::ToLocal(result));
4458 }
4459 
GetPrivate(Local<Context> context,Local<Private> key)4460 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4461                                          Local<Private> key) {
4462   return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4463 }
4464 
GetPropertyAttributes(Local<Context> context,Local<Value> key)4465 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4466     Local<Context> context, Local<Value> key) {
4467   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4468   ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4469            Nothing<PropertyAttribute>(), i::HandleScope);
4470   auto self = Utils::OpenHandle(this);
4471   auto key_obj = Utils::OpenHandle(*key);
4472   if (!key_obj->IsName()) {
4473     has_pending_exception =
4474         !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4475     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4476   }
4477   auto key_name = i::Handle<i::Name>::cast(key_obj);
4478   auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4479   has_pending_exception = result.IsNothing();
4480   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4481   if (result.FromJust() == i::ABSENT) {
4482     return Just(static_cast<PropertyAttribute>(i::NONE));
4483   }
4484   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4485 }
4486 
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4487 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4488                                                        Local<Name> key) {
4489   PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4490   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4491   i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4492 
4493   i::PropertyDescriptor desc;
4494   Maybe<bool> found =
4495       i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4496   has_pending_exception = found.IsNothing();
4497   RETURN_ON_FAILED_EXECUTION(Value);
4498   if (!found.FromJust()) {
4499     return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4500   }
4501   RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4502 }
4503 
GetPrototype()4504 Local<Value> v8::Object::GetPrototype() {
4505   auto self = Utils::OpenHandle(this);
4506   auto isolate = self->GetIsolate();
4507   i::PrototypeIterator iter(isolate, self);
4508   return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4509 }
4510 
SetPrototype(Local<Context> context,Local<Value> value)4511 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4512                                      Local<Value> value) {
4513   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4514   auto self = Utils::OpenHandle(this);
4515   auto value_obj = Utils::OpenHandle(*value);
4516   if (self->IsJSProxy()) {
4517     ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4518              i::HandleScope);
4519     // We do not allow exceptions thrown while setting the prototype
4520     // to propagate outside.
4521     TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4522     auto result = i::JSProxy::SetPrototype(i::Handle<i::JSProxy>::cast(self),
4523                                            value_obj, false, i::kThrowOnError);
4524     has_pending_exception = result.IsNothing();
4525     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4526   } else {
4527     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4528     auto result = i::JSObject::SetPrototype(i::Handle<i::JSObject>::cast(self),
4529                                             value_obj, false, i::kThrowOnError);
4530     if (result.IsNothing()) {
4531       isolate->clear_pending_exception();
4532       return Nothing<bool>();
4533     }
4534   }
4535   return Just(true);
4536 }
4537 
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4538 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4539     v8::Local<FunctionTemplate> tmpl) {
4540   auto self = Utils::OpenHandle(this);
4541   auto isolate = self->GetIsolate();
4542   i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4543   auto tmpl_info = *Utils::OpenHandle(*tmpl);
4544   while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4545     iter.Advance();
4546     if (iter.IsAtEnd()) return Local<Object>();
4547     if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4548   }
4549   // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4550   return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4551 }
4552 
GetPropertyNames(Local<Context> context)4553 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4554   return GetPropertyNames(
4555       context, v8::KeyCollectionMode::kIncludePrototypes,
4556       static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4557       v8::IndexFilter::kIncludeIndices);
4558 }
4559 
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4560 MaybeLocal<Array> v8::Object::GetPropertyNames(
4561     Local<Context> context, KeyCollectionMode mode,
4562     PropertyFilter property_filter, IndexFilter index_filter,
4563     KeyConversionMode key_conversion) {
4564   PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4565   auto self = Utils::OpenHandle(this);
4566   i::Handle<i::FixedArray> value;
4567   i::KeyAccumulator accumulator(
4568       isolate, static_cast<i::KeyCollectionMode>(mode),
4569       static_cast<i::PropertyFilter>(property_filter));
4570   accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4571   has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4572   RETURN_ON_FAILED_EXECUTION(Array);
4573   value =
4574       accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4575   DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4576          self->map().EnumLength() == 0 ||
4577          self->map().instance_descriptors(isolate).enum_cache().keys() !=
4578              *value);
4579   auto result = isolate->factory()->NewJSArrayWithElements(value);
4580   RETURN_ESCAPED(Utils::ToLocal(result));
4581 }
4582 
GetOwnPropertyNames(Local<Context> context)4583 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4584   return GetOwnPropertyNames(
4585       context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4586 }
4587 
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4588 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4589     Local<Context> context, PropertyFilter filter,
4590     KeyConversionMode key_conversion) {
4591   return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4592                           v8::IndexFilter::kIncludeIndices, key_conversion);
4593 }
4594 
ObjectProtoToString(Local<Context> context)4595 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4596   PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4597   auto self = Utils::OpenHandle(this);
4598   Local<Value> result;
4599   has_pending_exception = !ToLocal<Value>(
4600       i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4601                                 nullptr),
4602       &result);
4603   RETURN_ON_FAILED_EXECUTION(String);
4604   RETURN_ESCAPED(Local<String>::Cast(result));
4605 }
4606 
GetConstructorName()4607 Local<String> v8::Object::GetConstructorName() {
4608   auto self = Utils::OpenHandle(this);
4609   i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
4610   return Utils::ToLocal(name);
4611 }
4612 
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4613 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4614                                           IntegrityLevel level) {
4615   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4616   ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4617            i::HandleScope);
4618   auto self = Utils::OpenHandle(this);
4619   i::JSReceiver::IntegrityLevel i_level =
4620       level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4621   Maybe<bool> result =
4622       i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4623   has_pending_exception = result.IsNothing();
4624   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4625   return result;
4626 }
4627 
Delete(Local<Context> context,Local<Value> key)4628 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4629   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4630   auto self = Utils::OpenHandle(this);
4631   auto key_obj = Utils::OpenHandle(*key);
4632   if (self->IsJSProxy()) {
4633     ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4634     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4635         isolate, self, key_obj, i::LanguageMode::kSloppy);
4636     has_pending_exception = result.IsNothing();
4637     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4638     return result;
4639   } else {
4640     // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4641     // a script.
4642     ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4643                        i::HandleScope);
4644     Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4645         isolate, self, key_obj, i::LanguageMode::kSloppy);
4646     has_pending_exception = result.IsNothing();
4647     RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4648     return result;
4649   }
4650 }
4651 
DeletePrivate(Local<Context> context,Local<Private> key)4652 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4653                                       Local<Private> key) {
4654   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4655   // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4656   // any author script.
4657   ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4658                      i::HandleScope);
4659   auto self = Utils::OpenHandle(this);
4660   auto key_obj = Utils::OpenHandle(*key);
4661   Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4662       isolate, self, key_obj, i::LanguageMode::kSloppy);
4663   has_pending_exception = result.IsNothing();
4664   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4665   return result;
4666 }
4667 
Has(Local<Context> context,Local<Value> key)4668 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4669   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4670   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4671   auto self = Utils::OpenHandle(this);
4672   auto key_obj = Utils::OpenHandle(*key);
4673   Maybe<bool> maybe = Nothing<bool>();
4674   // Check if the given key is an array index.
4675   uint32_t index = 0;
4676   if (key_obj->ToArrayIndex(&index)) {
4677     maybe = i::JSReceiver::HasElement(self, index);
4678   } else {
4679     // Convert the key to a name - possibly by calling back into JavaScript.
4680     i::Handle<i::Name> name;
4681     if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4682       maybe = i::JSReceiver::HasProperty(self, name);
4683     }
4684   }
4685   has_pending_exception = maybe.IsNothing();
4686   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4687   return maybe;
4688 }
4689 
HasPrivate(Local<Context> context,Local<Private> key)4690 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4691   return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4692 }
4693 
Delete(Local<Context> context,uint32_t index)4694 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4695   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4696   ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4697   auto self = Utils::OpenHandle(this);
4698   Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4699   has_pending_exception = result.IsNothing();
4700   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4701   return result;
4702 }
4703 
Has(Local<Context> context,uint32_t index)4704 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4705   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4706   ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4707   auto self = Utils::OpenHandle(this);
4708   auto maybe = i::JSReceiver::HasElement(self, index);
4709   has_pending_exception = maybe.IsNothing();
4710   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4711   return maybe;
4712 }
4713 
4714 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)4715 static Maybe<bool> ObjectSetAccessor(
4716     Local<Context> context, Object* self, Local<Name> name, Getter getter,
4717     Setter setter, Data data, AccessControl settings,
4718     PropertyAttribute attributes, bool is_special_data_property,
4719     bool replace_on_access, SideEffectType getter_side_effect_type,
4720     SideEffectType setter_side_effect_type) {
4721   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4722   ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4723                      i::HandleScope);
4724   if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4725   i::Handle<i::JSObject> obj =
4726       i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4727   v8::Local<AccessorSignature> signature;
4728   i::Handle<i::AccessorInfo> info =
4729       MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4730                        is_special_data_property, replace_on_access);
4731   info->set_getter_side_effect_type(getter_side_effect_type);
4732   info->set_setter_side_effect_type(setter_side_effect_type);
4733   if (info.is_null()) return Nothing<bool>();
4734   bool fast = obj->HasFastProperties();
4735   i::Handle<i::Object> result;
4736 
4737   i::Handle<i::Name> accessor_name(info->name(), isolate);
4738   i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4739   has_pending_exception =
4740       !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4741            .ToHandle(&result);
4742   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4743   if (result->IsUndefined(isolate)) return Just(false);
4744   if (fast) {
4745     i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4746   }
4747   return Just(true);
4748 }
4749 
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)4750 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4751                                 AccessorNameGetterCallback getter,
4752                                 AccessorNameSetterCallback setter,
4753                                 MaybeLocal<Value> data, AccessControl settings,
4754                                 PropertyAttribute attribute,
4755                                 SideEffectType getter_side_effect_type,
4756                                 SideEffectType setter_side_effect_type) {
4757   return ObjectSetAccessor(context, this, name, getter, setter,
4758                            data.FromMaybe(Local<Value>()), settings, attribute,
4759                            i::FLAG_disable_old_api_accessors, false,
4760                            getter_side_effect_type, setter_side_effect_type);
4761 }
4762 
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4763 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4764                                  Local<Function> setter,
4765                                  PropertyAttribute attribute,
4766                                  AccessControl settings) {
4767   // TODO(verwaest): Remove |settings|.
4768   DCHECK_EQ(v8::DEFAULT, settings);
4769   auto self = Utils::OpenHandle(this);
4770   i::Isolate* isolate = self->GetIsolate();
4771   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4772   i::HandleScope scope(isolate);
4773   if (!self->IsJSObject()) return;
4774   i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4775   i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4776   if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4777   i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4778                               v8::Utils::OpenHandle(*name), getter_i, setter_i,
4779                               static_cast<i::PropertyAttributes>(attribute));
4780 }
4781 
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)4782 Maybe<bool> Object::SetNativeDataProperty(
4783     v8::Local<v8::Context> context, v8::Local<Name> name,
4784     AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4785     v8::Local<Value> data, PropertyAttribute attributes,
4786     SideEffectType getter_side_effect_type,
4787     SideEffectType setter_side_effect_type) {
4788   return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4789                            attributes, true, false, getter_side_effect_type,
4790                            setter_side_effect_type);
4791 }
4792 
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)4793 Maybe<bool> Object::SetLazyDataProperty(
4794     v8::Local<v8::Context> context, v8::Local<Name> name,
4795     AccessorNameGetterCallback getter, v8::Local<Value> data,
4796     PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4797     SideEffectType setter_side_effect_type) {
4798   return ObjectSetAccessor(context, this, name, getter,
4799                            static_cast<AccessorNameSetterCallback>(nullptr),
4800                            data, DEFAULT, attributes, true, true,
4801                            getter_side_effect_type, setter_side_effect_type);
4802 }
4803 
HasOwnProperty(Local<Context> context,Local<Name> key)4804 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4805                                        Local<Name> key) {
4806   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4807   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4808            i::HandleScope);
4809   auto self = Utils::OpenHandle(this);
4810   auto key_val = Utils::OpenHandle(*key);
4811   auto result = i::JSReceiver::HasOwnProperty(self, key_val);
4812   has_pending_exception = result.IsNothing();
4813   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4814   return result;
4815 }
4816 
HasOwnProperty(Local<Context> context,uint32_t index)4817 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4818   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4819   ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4820            i::HandleScope);
4821   auto self = Utils::OpenHandle(this);
4822   auto result = i::JSReceiver::HasOwnProperty(self, index);
4823   has_pending_exception = result.IsNothing();
4824   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4825   return result;
4826 }
4827 
HasRealNamedProperty(Local<Context> context,Local<Name> key)4828 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4829                                              Local<Name> key) {
4830   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4831   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4832                      Nothing<bool>(), i::HandleScope);
4833   auto self = Utils::OpenHandle(this);
4834   if (!self->IsJSObject()) return Just(false);
4835   auto key_val = Utils::OpenHandle(*key);
4836   auto result = i::JSObject::HasRealNamedProperty(
4837       i::Handle<i::JSObject>::cast(self), key_val);
4838   has_pending_exception = result.IsNothing();
4839   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4840   return result;
4841 }
4842 
HasRealIndexedProperty(Local<Context> context,uint32_t index)4843 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4844                                                uint32_t index) {
4845   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4846   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4847                      Nothing<bool>(), i::HandleScope);
4848   auto self = Utils::OpenHandle(this);
4849   if (!self->IsJSObject()) return Just(false);
4850   auto result = i::JSObject::HasRealElementProperty(
4851       i::Handle<i::JSObject>::cast(self), index);
4852   has_pending_exception = result.IsNothing();
4853   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4854   return result;
4855 }
4856 
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4857 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4858                                                      Local<Name> key) {
4859   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4860   ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
4861                      Nothing<bool>(), i::HandleScope);
4862   auto self = Utils::OpenHandle(this);
4863   if (!self->IsJSObject()) return Just(false);
4864   auto key_val = Utils::OpenHandle(*key);
4865   auto result = i::JSObject::HasRealNamedCallbackProperty(
4866       i::Handle<i::JSObject>::cast(self), key_val);
4867   has_pending_exception = result.IsNothing();
4868   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4869   return result;
4870 }
4871 
HasNamedLookupInterceptor() const4872 bool v8::Object::HasNamedLookupInterceptor() const {
4873   auto self = *Utils::OpenHandle(this);
4874   if (self.IsJSObject()) return false;
4875   return i::JSObject::cast(self).HasNamedInterceptor();
4876 }
4877 
HasIndexedLookupInterceptor() const4878 bool v8::Object::HasIndexedLookupInterceptor() const {
4879   auto self = *Utils::OpenHandle(this);
4880   if (self.IsJSObject()) return false;
4881   return i::JSObject::cast(self).HasIndexedInterceptor();
4882 }
4883 
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4884 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4885     Local<Context> context, Local<Name> key) {
4886   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4887                         Value);
4888   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4889   if (!self->IsJSObject()) return MaybeLocal<Value>();
4890   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4891   i::PrototypeIterator iter(isolate, self);
4892   if (iter.IsAtEnd()) return MaybeLocal<Value>();
4893   i::Handle<i::JSReceiver> proto =
4894       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4895   i::PropertyKey lookup_key(isolate, key_obj);
4896   i::LookupIterator it(isolate, self, lookup_key, proto,
4897                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4898   Local<Value> result;
4899   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4900   RETURN_ON_FAILED_EXECUTION(Value);
4901   if (!it.IsFound()) return MaybeLocal<Value>();
4902   RETURN_ESCAPED(result);
4903 }
4904 
4905 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4906 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
4907     Local<Context> context, Local<Name> key) {
4908   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4909   ENTER_V8(isolate, context, Object,
4910            GetRealNamedPropertyAttributesInPrototypeChain,
4911            Nothing<PropertyAttribute>(), i::HandleScope);
4912   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4913   if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
4914   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4915   i::PrototypeIterator iter(isolate, self);
4916   if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
4917   i::Handle<i::JSReceiver> proto =
4918       i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4919   i::PropertyKey lookup_key(isolate, key_obj);
4920   i::LookupIterator it(isolate, self, lookup_key, proto,
4921                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4922   Maybe<i::PropertyAttributes> result =
4923       i::JSReceiver::GetPropertyAttributes(&it);
4924   has_pending_exception = result.IsNothing();
4925   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4926   if (!it.IsFound()) return Nothing<PropertyAttribute>();
4927   if (result.FromJust() == i::ABSENT) return Just(None);
4928   return Just(static_cast<PropertyAttribute>(result.FromJust()));
4929 }
4930 
GetRealNamedProperty(Local<Context> context,Local<Name> key)4931 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
4932                                                    Local<Name> key) {
4933   PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
4934   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4935   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4936   i::PropertyKey lookup_key(isolate, key_obj);
4937   i::LookupIterator it(isolate, self, lookup_key, self,
4938                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4939   Local<Value> result;
4940   has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4941   RETURN_ON_FAILED_EXECUTION(Value);
4942   if (!it.IsFound()) return MaybeLocal<Value>();
4943   RETURN_ESCAPED(result);
4944 }
4945 
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)4946 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4947     Local<Context> context, Local<Name> key) {
4948   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4949   ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
4950            Nothing<PropertyAttribute>(), i::HandleScope);
4951   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4952   i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4953   i::PropertyKey lookup_key(isolate, key_obj);
4954   i::LookupIterator it(isolate, self, lookup_key, self,
4955                        i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4956   auto result = i::JSReceiver::GetPropertyAttributes(&it);
4957   has_pending_exception = result.IsNothing();
4958   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4959   if (!it.IsFound()) return Nothing<PropertyAttribute>();
4960   if (result.FromJust() == i::ABSENT) {
4961     return Just(static_cast<PropertyAttribute>(i::NONE));
4962   }
4963   return Just<PropertyAttribute>(
4964       static_cast<PropertyAttribute>(result.FromJust()));
4965 }
4966 
Clone()4967 Local<v8::Object> v8::Object::Clone() {
4968   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4969   auto isolate = self->GetIsolate();
4970   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4971   i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
4972   return Utils::ToLocal(result);
4973 }
4974 
4975 namespace {
CreationContextImpl(i::Handle<i::JSReceiver> self)4976 Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) {
4977   i::Handle<i::Context> context;
4978   if (self->GetCreationContext().ToHandle(&context)) {
4979     return Utils::ToLocal(context);
4980   }
4981 
4982   return Local<v8::Context>();
4983 }
4984 }  // namespace
4985 
CreationContext()4986 Local<v8::Context> v8::Object::CreationContext() {
4987   auto self = Utils::OpenHandle(this);
4988   return CreationContextImpl(self);
4989 }
4990 
CreationContext(const PersistentBase<Object> & object)4991 Local<v8::Context> v8::Object::CreationContext(
4992     const PersistentBase<Object>& object) {
4993   auto self = Utils::OpenHandle(object.val_);
4994   return CreationContextImpl(self);
4995 }
4996 
GetCreationContext()4997 MaybeLocal<v8::Context> v8::Object::GetCreationContext() {
4998   auto self = Utils::OpenHandle(this);
4999   i::Handle<i::Context> context;
5000   if (self->GetCreationContext().ToHandle(&context)) {
5001     return Utils::ToLocal(context);
5002   }
5003 
5004   return MaybeLocal<v8::Context>();
5005 }
5006 
GetIdentityHash()5007 int v8::Object::GetIdentityHash() {
5008   i::DisallowGarbageCollection no_gc;
5009   auto self = Utils::OpenHandle(this);
5010   auto isolate = self->GetIsolate();
5011   ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
5012   i::HandleScope scope(isolate);
5013   return self->GetOrCreateIdentityHash(isolate).value();
5014 }
5015 
IsCallable() const5016 bool v8::Object::IsCallable() const {
5017   auto self = Utils::OpenHandle(this);
5018   return self->IsCallable();
5019 }
5020 
IsConstructor() const5021 bool v8::Object::IsConstructor() const {
5022   auto self = Utils::OpenHandle(this);
5023   return self->IsConstructor();
5024 }
5025 
IsApiWrapper() const5026 bool v8::Object::IsApiWrapper() const {
5027   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5028   return self->IsApiWrapper();
5029 }
5030 
IsUndetectable() const5031 bool v8::Object::IsUndetectable() const {
5032   auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5033   return self->IsUndetectable();
5034 }
5035 
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5036 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5037                                          Local<Value> recv, int argc,
5038                                          Local<Value> argv[]) {
5039   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5040   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5041   ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5042            InternalEscapableScope);
5043   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5044   i::NestedTimedHistogramScope execute_timer(
5045       isolate->counters()->execute_precise());
5046   auto self = Utils::OpenHandle(this);
5047   auto recv_obj = Utils::OpenHandle(*recv);
5048   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5049   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5050   Local<Value> result;
5051   has_pending_exception = !ToLocal<Value>(
5052       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5053   RETURN_ON_FAILED_EXECUTION(Value);
5054   RETURN_ESCAPED(result);
5055 }
5056 
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5057 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5058                                             Local<Value> argv[]) {
5059   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5060   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5061   ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5062            InternalEscapableScope);
5063   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5064   i::NestedTimedHistogramScope execute_timer(
5065       isolate->counters()->execute_precise());
5066   auto self = Utils::OpenHandle(this);
5067   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5068   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5069   Local<Value> result;
5070   has_pending_exception = !ToLocal<Value>(
5071       i::Execution::New(isolate, self, self, argc, args), &result);
5072   RETURN_ON_FAILED_EXECUTION(Value);
5073   RETURN_ESCAPED(result);
5074 }
5075 
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)5076 MaybeLocal<Function> Function::New(Local<Context> context,
5077                                    FunctionCallback callback, Local<Value> data,
5078                                    int length, ConstructorBehavior behavior,
5079                                    SideEffectType side_effect_type) {
5080   i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5081   LOG_API(isolate, Function, New);
5082   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5083   auto templ =
5084       FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
5085                           behavior, true, Local<Private>(), side_effect_type);
5086   return templ->GetFunction(context);
5087 }
5088 
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5089 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5090                                          v8::Local<v8::Value> argv[]) const {
5091   return NewInstanceWithSideEffectType(context, argc, argv,
5092                                        SideEffectType::kHasSideEffect);
5093 }
5094 
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const5095 MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
5096     Local<Context> context, int argc, v8::Local<v8::Value> argv[],
5097     SideEffectType side_effect_type) const {
5098   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5099   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5100   ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5101            InternalEscapableScope);
5102   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5103   i::NestedTimedHistogramScope execute_timer(
5104       isolate->counters()->execute_precise());
5105   auto self = Utils::OpenHandle(this);
5106   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5107   bool should_set_has_no_side_effect =
5108       side_effect_type == SideEffectType::kHasNoSideEffect &&
5109       isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
5110   if (should_set_has_no_side_effect) {
5111     CHECK(self->IsJSFunction() &&
5112           i::JSFunction::cast(*self).shared().IsApiFunction());
5113     i::Object obj =
5114         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5115             kAcquireLoad);
5116     if (obj.IsCallHandlerInfo()) {
5117       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5118       if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
5119         handler_info.SetNextCallHasNoSideEffect();
5120       }
5121     }
5122   }
5123   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5124   Local<Object> result;
5125   has_pending_exception = !ToLocal<Object>(
5126       i::Execution::New(isolate, self, self, argc, args), &result);
5127   if (should_set_has_no_side_effect) {
5128     i::Object obj =
5129         i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5130             kAcquireLoad);
5131     if (obj.IsCallHandlerInfo()) {
5132       i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5133       if (has_pending_exception) {
5134         // Restore the map if an exception prevented restoration.
5135         handler_info.NextCallHasNoSideEffect();
5136       } else {
5137         DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
5138                handler_info.IsSideEffectFreeCallHandlerInfo());
5139       }
5140     }
5141   }
5142   RETURN_ON_FAILED_EXECUTION(Object);
5143   RETURN_ESCAPED(result);
5144 }
5145 
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5146 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5147                                      v8::Local<v8::Value> recv, int argc,
5148                                      v8::Local<v8::Value> argv[]) {
5149   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5150   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5151   ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5152            InternalEscapableScope);
5153   i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5154   i::NestedTimedHistogramScope execute_timer(
5155       isolate->counters()->execute_precise());
5156   auto self = Utils::OpenHandle(this);
5157   Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
5158                   "Function to be called is a null pointer");
5159   i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5160   STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5161   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5162   Local<Value> result;
5163   has_pending_exception = !ToLocal<Value>(
5164       i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5165   RETURN_ON_FAILED_EXECUTION(Value);
5166   RETURN_ESCAPED(result);
5167 }
5168 
SetName(v8::Local<v8::String> name)5169 void Function::SetName(v8::Local<v8::String> name) {
5170   auto self = Utils::OpenHandle(this);
5171   if (!self->IsJSFunction()) return;
5172   auto func = i::Handle<i::JSFunction>::cast(self);
5173   ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
5174   func->shared().SetName(*Utils::OpenHandle(*name));
5175 }
5176 
GetName() const5177 Local<Value> Function::GetName() const {
5178   auto self = Utils::OpenHandle(this);
5179   i::Isolate* isolate = self->GetIsolate();
5180   if (self->IsJSBoundFunction()) {
5181     auto func = i::Handle<i::JSBoundFunction>::cast(self);
5182     i::Handle<i::Object> name;
5183     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5184                                      i::JSBoundFunction::GetName(isolate, func),
5185                                      Local<Value>());
5186     return Utils::ToLocal(name);
5187   }
5188   if (self->IsJSFunction()) {
5189     auto func = i::Handle<i::JSFunction>::cast(self);
5190     return Utils::ToLocal(handle(func->shared().Name(), isolate));
5191   }
5192   return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5193 }
5194 
GetInferredName() const5195 Local<Value> Function::GetInferredName() const {
5196   auto self = Utils::OpenHandle(this);
5197   if (!self->IsJSFunction()) {
5198     return ToApiHandle<Primitive>(
5199         self->GetIsolate()->factory()->undefined_value());
5200   }
5201   auto func = i::Handle<i::JSFunction>::cast(self);
5202   return Utils::ToLocal(
5203       i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5204 }
5205 
GetDebugName() const5206 Local<Value> Function::GetDebugName() const {
5207   auto self = Utils::OpenHandle(this);
5208   if (!self->IsJSFunction()) {
5209     return ToApiHandle<Primitive>(
5210         self->GetIsolate()->factory()->undefined_value());
5211   }
5212   auto func = i::Handle<i::JSFunction>::cast(self);
5213   i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5214   return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5215 }
5216 
GetScriptOrigin() const5217 ScriptOrigin Function::GetScriptOrigin() const {
5218   auto self = Utils::OpenHandle(this);
5219   auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate());
5220   if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>());
5221   auto func = i::Handle<i::JSFunction>::cast(self);
5222   if (func->shared().script().IsScript()) {
5223     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5224                                 func->GetIsolate());
5225     return GetScriptOriginForScript(func->GetIsolate(), script);
5226   }
5227   return v8::ScriptOrigin(isolate, Local<Value>());
5228 }
5229 
5230 const int Function::kLineOffsetNotFound = -1;
5231 
GetScriptLineNumber() const5232 int Function::GetScriptLineNumber() const {
5233   auto self = Utils::OpenHandle(this);
5234   if (!self->IsJSFunction()) {
5235     return kLineOffsetNotFound;
5236   }
5237   auto func = i::Handle<i::JSFunction>::cast(self);
5238   if (func->shared().script().IsScript()) {
5239     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5240                                 func->GetIsolate());
5241     return i::Script::GetLineNumber(script, func->shared().StartPosition());
5242   }
5243   return kLineOffsetNotFound;
5244 }
5245 
GetScriptColumnNumber() const5246 int Function::GetScriptColumnNumber() const {
5247   auto self = Utils::OpenHandle(this);
5248   if (!self->IsJSFunction()) {
5249     return kLineOffsetNotFound;
5250   }
5251   auto func = i::Handle<i::JSFunction>::cast(self);
5252   if (func->shared().script().IsScript()) {
5253     i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5254                                 func->GetIsolate());
5255     return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5256   }
5257   return kLineOffsetNotFound;
5258 }
5259 
ScriptId() const5260 int Function::ScriptId() const {
5261   i::JSReceiver self = *Utils::OpenHandle(this);
5262   if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
5263   auto func = i::JSFunction::cast(self);
5264   if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
5265   return i::Script::cast(func.shared().script()).id();
5266 }
5267 
GetBoundFunction() const5268 Local<v8::Value> Function::GetBoundFunction() const {
5269   auto self = Utils::OpenHandle(this);
5270   if (self->IsJSBoundFunction()) {
5271     auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5272     auto bound_target_function = i::handle(
5273         bound_function->bound_target_function(), bound_function->GetIsolate());
5274     return Utils::CallableToLocal(bound_target_function);
5275   }
5276   return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5277 }
5278 
FunctionProtoToString(Local<Context> context)5279 MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5280   PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5281   auto self = Utils::OpenHandle(this);
5282   Local<Value> result;
5283   has_pending_exception = !ToLocal<Value>(
5284       i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5285                                 nullptr),
5286       &result);
5287   RETURN_ON_FAILED_EXECUTION(String);
5288   RETURN_ESCAPED(Local<String>::Cast(result));
5289 }
5290 
GetIdentityHash()5291 int Name::GetIdentityHash() {
5292   auto self = Utils::OpenHandle(this);
5293   return static_cast<int>(self->EnsureHash());
5294 }
5295 
Length() const5296 int String::Length() const {
5297   i::Handle<i::String> str = Utils::OpenHandle(this);
5298   return str->length();
5299 }
5300 
IsOneByte() const5301 bool String::IsOneByte() const {
5302   i::Handle<i::String> str = Utils::OpenHandle(this);
5303   return str->IsOneByteRepresentation();
5304 }
5305 
5306 // Helpers for ContainsOnlyOneByteHelper
5307 template <size_t size>
5308 struct OneByteMask;
5309 template <>
5310 struct OneByteMask<4> {
5311   static const uint32_t value = 0xFF00FF00;
5312 };
5313 template <>
5314 struct OneByteMask<8> {
5315   static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5316 };
5317 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5318 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5319 static inline bool Unaligned(const uint16_t* chars) {
5320   return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5321 }
5322 
Align(const uint16_t * chars)5323 static inline const uint16_t* Align(const uint16_t* chars) {
5324   return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5325                                      ~kAlignmentMask);
5326 }
5327 
5328 class ContainsOnlyOneByteHelper {
5329  public:
ContainsOnlyOneByteHelper()5330   ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5331   ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5332   ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5333       delete;
Check(i::String string)5334   bool Check(i::String string) {
5335     i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5336     if (cons_string.is_null()) return is_one_byte_;
5337     return CheckCons(cons_string);
5338   }
VisitOneByteString(const uint8_t * chars,int length)5339   void VisitOneByteString(const uint8_t* chars, int length) {
5340     // Nothing to do.
5341   }
VisitTwoByteString(const uint16_t * chars,int length)5342   void VisitTwoByteString(const uint16_t* chars, int length) {
5343     // Accumulated bits.
5344     uintptr_t acc = 0;
5345     // Align to uintptr_t.
5346     const uint16_t* end = chars + length;
5347     while (Unaligned(chars) && chars != end) {
5348       acc |= *chars++;
5349     }
5350     // Read word aligned in blocks,
5351     // checking the return value at the end of each block.
5352     const uint16_t* aligned_end = Align(end);
5353     const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5354     const int inner_loops = 16;
5355     while (chars + inner_loops * increment < aligned_end) {
5356       for (int i = 0; i < inner_loops; i++) {
5357         acc |= *reinterpret_cast<const uintptr_t*>(chars);
5358         chars += increment;
5359       }
5360       // Check for early return.
5361       if ((acc & kOneByteMask) != 0) {
5362         is_one_byte_ = false;
5363         return;
5364       }
5365     }
5366     // Read the rest.
5367     while (chars != end) {
5368       acc |= *chars++;
5369     }
5370     // Check result.
5371     if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5372   }
5373 
5374  private:
CheckCons(i::ConsString cons_string)5375   bool CheckCons(i::ConsString cons_string) {
5376     while (true) {
5377       // Check left side if flat.
5378       i::String left = cons_string.first();
5379       i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5380       if (!is_one_byte_) return false;
5381       // Check right side if flat.
5382       i::String right = cons_string.second();
5383       i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5384       if (!is_one_byte_) return false;
5385       // Standard recurse/iterate trick.
5386       if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5387         if (left.length() < right.length()) {
5388           CheckCons(left_as_cons);
5389           cons_string = right_as_cons;
5390         } else {
5391           CheckCons(right_as_cons);
5392           cons_string = left_as_cons;
5393         }
5394         // Check fast return.
5395         if (!is_one_byte_) return false;
5396         continue;
5397       }
5398       // Descend left in place.
5399       if (!left_as_cons.is_null()) {
5400         cons_string = left_as_cons;
5401         continue;
5402       }
5403       // Descend right in place.
5404       if (!right_as_cons.is_null()) {
5405         cons_string = right_as_cons;
5406         continue;
5407       }
5408       // Terminate.
5409       break;
5410     }
5411     return is_one_byte_;
5412   }
5413   bool is_one_byte_;
5414 };
5415 
ContainsOnlyOneByte() const5416 bool String::ContainsOnlyOneByte() const {
5417   i::Handle<i::String> str = Utils::OpenHandle(this);
5418   if (str->IsOneByteRepresentation()) return true;
5419   ContainsOnlyOneByteHelper helper;
5420   return helper.Check(*str);
5421 }
5422 
Utf8Length(Isolate * isolate) const5423 int String::Utf8Length(Isolate* isolate) const {
5424   i::Handle<i::String> str = Utils::OpenHandle(this);
5425   str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5426   int length = str->length();
5427   if (length == 0) return 0;
5428   i::DisallowGarbageCollection no_gc;
5429   i::String::FlatContent flat = str->GetFlatContent(no_gc);
5430   DCHECK(flat.IsFlat());
5431   int utf8_length = 0;
5432   if (flat.IsOneByte()) {
5433     for (uint8_t c : flat.ToOneByteVector()) {
5434       utf8_length += c >> 7;
5435     }
5436     utf8_length += length;
5437   } else {
5438     int last_character = unibrow::Utf16::kNoPreviousCharacter;
5439     for (uint16_t c : flat.ToUC16Vector()) {
5440       utf8_length += unibrow::Utf8::Length(c, last_character);
5441       last_character = c;
5442     }
5443   }
5444   return utf8_length;
5445 }
5446 
5447 namespace {
5448 // Writes the flat content of a string to a buffer. This is done in two phases.
5449 // The first phase calculates a pessimistic estimate (writable_length) on how
5450 // many code units can be safely written without exceeding the buffer capacity
5451 // and without leaving at a lone surrogate. The estimated number of code units
5452 // is then written out in one go, and the reported byte usage is used to
5453 // correct the estimate. This is repeated until the estimate becomes <= 0 or
5454 // all code units have been written out. The second phase writes out code
5455 // units until the buffer capacity is reached, would be exceeded by the next
5456 // unit, or all code units have been written out.
5457 template <typename Char>
WriteUtf8Impl(base::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5458 static int WriteUtf8Impl(base::Vector<const Char> string, char* write_start,
5459                          int write_capacity, int options,
5460                          int* utf16_chars_read_out) {
5461   bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5462   bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5463   char* current_write = write_start;
5464   const Char* read_start = string.begin();
5465   int read_index = 0;
5466   int read_length = string.length();
5467   int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5468   // Do a fast loop where there is no exit capacity check.
5469   // Need enough space to write everything but one character.
5470   STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5471   static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5472   while (read_index < read_length) {
5473     int up_to = read_length;
5474     if (write_capacity != -1) {
5475       int remaining_capacity =
5476           write_capacity - static_cast<int>(current_write - write_start);
5477       int writable_length =
5478           (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5479       // Need to drop into slow loop.
5480       if (writable_length <= 0) break;
5481       up_to = std::min(up_to, read_index + writable_length);
5482     }
5483     // Write the characters to the stream.
5484     if (sizeof(Char) == 1) {
5485       // Simply memcpy if we only have ASCII characters.
5486       uint8_t char_mask = 0;
5487       for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5488       if ((char_mask & 0x80) == 0) {
5489         int copy_length = up_to - read_index;
5490         memcpy(current_write, read_start + read_index, copy_length);
5491         current_write += copy_length;
5492         read_index = up_to;
5493       } else {
5494         for (; read_index < up_to; read_index++) {
5495           current_write += unibrow::Utf8::EncodeOneByte(
5496               current_write, static_cast<uint8_t>(read_start[read_index]));
5497           DCHECK(write_capacity == -1 ||
5498                  (current_write - write_start) <= write_capacity);
5499         }
5500       }
5501     } else {
5502       for (; read_index < up_to; read_index++) {
5503         uint16_t character = read_start[read_index];
5504         current_write += unibrow::Utf8::Encode(current_write, character,
5505                                                prev_char, replace_invalid_utf8);
5506         prev_char = character;
5507         DCHECK(write_capacity == -1 ||
5508                (current_write - write_start) <= write_capacity);
5509       }
5510     }
5511   }
5512   if (read_index < read_length) {
5513     DCHECK_NE(-1, write_capacity);
5514     // Aborted due to limited capacity. Check capacity on each iteration.
5515     int remaining_capacity =
5516         write_capacity - static_cast<int>(current_write - write_start);
5517     DCHECK_GE(remaining_capacity, 0);
5518     for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5519       uint32_t character = read_start[read_index];
5520       int written = 0;
5521       // We can't use a local buffer here because Encode needs to modify
5522       // previous characters in the stream.  We know, however, that
5523       // exactly one character will be advanced.
5524       if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5525         written = unibrow::Utf8::Encode(current_write, character, prev_char,
5526                                         replace_invalid_utf8);
5527         DCHECK_EQ(written, 1);
5528       } else {
5529         // Use a scratch buffer to check the required characters.
5530         char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5531         // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5532         static const int kSurrogatePairEncodedSize =
5533             static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5534         // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5535         // middle of a surrogate pair. Abort before encoding the pair instead.
5536         if (replace_invalid_utf8 &&
5537             remaining_capacity < kSurrogatePairEncodedSize &&
5538             unibrow::Utf16::IsLeadSurrogate(character) &&
5539             read_index + 1 < read_length &&
5540             unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5541           write_null = false;
5542           break;
5543         }
5544         // Can't encode using prev_char as gcc has array bounds issues.
5545         written = unibrow::Utf8::Encode(temp_buffer, character,
5546                                         unibrow::Utf16::kNoPreviousCharacter,
5547                                         replace_invalid_utf8);
5548         if (written > remaining_capacity) {
5549           // Won't fit. Abort and do not null-terminate the result.
5550           write_null = false;
5551           break;
5552         }
5553         // Copy over the character from temp_buffer.
5554         for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5555       }
5556 
5557       current_write += written;
5558       remaining_capacity -= written;
5559       prev_char = character;
5560     }
5561   }
5562 
5563   // Write out number of utf16 characters written to the stream.
5564   if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5565 
5566   // Only null-terminate if there's space.
5567   if (write_null && (write_capacity == -1 ||
5568                      (current_write - write_start) < write_capacity)) {
5569     *current_write++ = '\0';
5570   }
5571   return static_cast<int>(current_write - write_start);
5572 }
5573 }  // anonymous namespace
5574 
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5575 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5576                       int* nchars_ref, int options) const {
5577   i::Handle<i::String> str = Utils::OpenHandle(this);
5578   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5579   LOG_API(isolate, String, WriteUtf8);
5580   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5581   str = i::String::Flatten(isolate, str);
5582   i::DisallowGarbageCollection no_gc;
5583   i::String::FlatContent content = str->GetFlatContent(no_gc);
5584   if (content.IsOneByte()) {
5585     return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5586                                   options, nchars_ref);
5587   } else {
5588     return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5589                                    options, nchars_ref);
5590   }
5591 }
5592 
5593 template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5594 static inline int WriteHelper(i::Isolate* isolate, const String* string,
5595                               CharType* buffer, int start, int length,
5596                               int options) {
5597   LOG_API(isolate, String, Write);
5598   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5599   DCHECK(start >= 0 && length >= -1);
5600   i::Handle<i::String> str = Utils::OpenHandle(string);
5601   str = i::String::Flatten(isolate, str);
5602   int end = start + length;
5603   if ((length == -1) || (length > str->length() - start)) end = str->length();
5604   if (end < 0) return 0;
5605   int write_length = end - start;
5606   if (start < end) i::String::WriteToFlat(*str, buffer, start, write_length);
5607   if (!(options & String::NO_NULL_TERMINATION) &&
5608       (length == -1 || write_length < length)) {
5609     buffer[write_length] = '\0';
5610   }
5611   return write_length;
5612 }
5613 
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5614 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5615                          int length, int options) const {
5616   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5617                      start, length, options);
5618 }
5619 
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5620 int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5621                   int options) const {
5622   return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5623                      start, length, options);
5624 }
5625 
IsExternal() const5626 bool v8::String::IsExternal() const {
5627   i::Handle<i::String> str = Utils::OpenHandle(this);
5628   return i::StringShape(*str).IsExternal();
5629 }
5630 
IsExternalTwoByte() const5631 bool v8::String::IsExternalTwoByte() const {
5632   i::Handle<i::String> str = Utils::OpenHandle(this);
5633   return i::StringShape(*str).IsExternalTwoByte();
5634 }
5635 
IsExternalOneByte() const5636 bool v8::String::IsExternalOneByte() const {
5637   i::Handle<i::String> str = Utils::OpenHandle(this);
5638   return i::StringShape(*str).IsExternalOneByte();
5639 }
5640 
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5641 void v8::String::VerifyExternalStringResource(
5642     v8::String::ExternalStringResource* value) const {
5643   i::DisallowGarbageCollection no_gc;
5644   i::String str = *Utils::OpenHandle(this);
5645   const v8::String::ExternalStringResource* expected;
5646 
5647   if (str.IsThinString()) {
5648     str = i::ThinString::cast(str).actual();
5649   }
5650 
5651   if (i::StringShape(str).IsExternalTwoByte()) {
5652     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5653     expected = reinterpret_cast<const ExternalStringResource*>(resource);
5654   } else {
5655     expected = nullptr;
5656   }
5657   CHECK_EQ(expected, value);
5658 }
5659 
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5660 void v8::String::VerifyExternalStringResourceBase(
5661     v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5662   i::DisallowGarbageCollection no_gc;
5663   i::String str = *Utils::OpenHandle(this);
5664   const v8::String::ExternalStringResourceBase* expected;
5665   Encoding expectedEncoding;
5666 
5667   if (str.IsThinString()) {
5668     str = i::ThinString::cast(str).actual();
5669   }
5670 
5671   if (i::StringShape(str).IsExternalOneByte()) {
5672     const void* resource = i::ExternalOneByteString::cast(str).resource();
5673     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5674     expectedEncoding = ONE_BYTE_ENCODING;
5675   } else if (i::StringShape(str).IsExternalTwoByte()) {
5676     const void* resource = i::ExternalTwoByteString::cast(str).resource();
5677     expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5678     expectedEncoding = TWO_BYTE_ENCODING;
5679   } else {
5680     expected = nullptr;
5681     expectedEncoding =
5682         str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5683   }
5684   CHECK_EQ(expected, value);
5685   CHECK_EQ(expectedEncoding, encoding);
5686 }
5687 
GetExternalStringResourceSlow() const5688 String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5689   i::DisallowGarbageCollection no_gc;
5690   using I = internal::Internals;
5691   i::String str = *Utils::OpenHandle(this);
5692 
5693   if (str.IsThinString()) {
5694     str = i::ThinString::cast(str).actual();
5695   }
5696 
5697   if (i::StringShape(str).IsExternalTwoByte()) {
5698     internal::Isolate* isolate = I::GetIsolateForHeapSandbox(str.ptr());
5699     internal::Address value = I::ReadExternalPointerField(
5700         isolate, str.ptr(), I::kStringResourceOffset,
5701         internal::kExternalStringResourceTag);
5702     return reinterpret_cast<String::ExternalStringResource*>(value);
5703   }
5704   return nullptr;
5705 }
5706 
UpdateDataCache()5707 void String::ExternalStringResource::UpdateDataCache() {
5708   DCHECK(IsCacheable());
5709   cached_data_ = data();
5710 }
5711 
CheckCachedDataInvariants() const5712 void String::ExternalStringResource::CheckCachedDataInvariants() const {
5713   DCHECK(IsCacheable() && cached_data_ != nullptr);
5714 }
5715 
UpdateDataCache()5716 void String::ExternalOneByteStringResource::UpdateDataCache() {
5717   DCHECK(IsCacheable());
5718   cached_data_ = data();
5719 }
5720 
CheckCachedDataInvariants() const5721 void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5722   DCHECK(IsCacheable() && cached_data_ != nullptr);
5723 }
5724 
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5725 String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5726     String::Encoding* encoding_out) const {
5727   i::DisallowGarbageCollection no_gc;
5728   using I = internal::Internals;
5729   ExternalStringResourceBase* resource = nullptr;
5730   i::String str = *Utils::OpenHandle(this);
5731 
5732   if (str.IsThinString()) {
5733     str = i::ThinString::cast(str).actual();
5734   }
5735 
5736   internal::Address string = str.ptr();
5737   int type = I::GetInstanceType(string) & I::kFullStringRepresentationMask;
5738   *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5739   if (i::StringShape(str).IsExternalOneByte() ||
5740       i::StringShape(str).IsExternalTwoByte()) {
5741     internal::Isolate* isolate = I::GetIsolateForHeapSandbox(string);
5742     internal::Address value =
5743         I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5744                                     internal::kExternalStringResourceTag);
5745     resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5746   }
5747   return resource;
5748 }
5749 
5750 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5751 v8::String::GetExternalOneByteStringResource() const {
5752   i::DisallowGarbageCollection no_gc;
5753   i::String str = *Utils::OpenHandle(this);
5754   if (i::StringShape(str).IsExternalOneByte()) {
5755     return i::ExternalOneByteString::cast(str).resource();
5756   } else if (str.IsThinString()) {
5757     str = i::ThinString::cast(str).actual();
5758     if (i::StringShape(str).IsExternalOneByte()) {
5759       return i::ExternalOneByteString::cast(str).resource();
5760     }
5761   }
5762   return nullptr;
5763 }
5764 
Description() const5765 Local<Value> Symbol::Description() const {
5766   i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5767 
5768   i::Isolate* isolate;
5769   if (!i::GetIsolateFromHeapObject(*sym, &isolate)) {
5770     // Symbol is in RO_SPACE, which means that its description is also in
5771     // RO_SPACE. Since RO_SPACE objects are immovable we can use the
5772     // Handle(Address*) constructor with the address of the description
5773     // field in the Symbol object without needing an isolate.
5774     DCHECK(!COMPRESS_POINTERS_IN_ISOLATE_CAGE_BOOL);
5775 #ifndef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
5776     i::Handle<i::HeapObject> ro_description(reinterpret_cast<i::Address*>(
5777         sym->GetFieldAddress(i::Symbol::kDescriptionOffset)));
5778     return Utils::ToLocal(ro_description);
5779 #else
5780     isolate = reinterpret_cast<i::Isolate*>(Isolate::GetCurrent());
5781 #endif
5782   }
5783 
5784   return Description(reinterpret_cast<Isolate*>(isolate));
5785 }
5786 
Description(Isolate * isolate) const5787 Local<Value> Symbol::Description(Isolate* isolate) const {
5788   i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5789   i::Handle<i::Object> description(sym->description(),
5790                                    reinterpret_cast<i::Isolate*>(isolate));
5791   return Utils::ToLocal(description);
5792 }
5793 
Name() const5794 Local<Value> Private::Name() const {
5795   const Symbol* sym = reinterpret_cast<const Symbol*>(this);
5796   i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym);
5797   // v8::Private symbols are created by API and are therefore writable, so we
5798   // can always recover an Isolate.
5799   i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym);
5800   return sym->Description(reinterpret_cast<Isolate*>(isolate));
5801 }
5802 
Value() const5803 double Number::Value() const {
5804   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5805   return obj->Number();
5806 }
5807 
Value() const5808 bool Boolean::Value() const {
5809   i::Handle<i::Object> obj = Utils::OpenHandle(this);
5810   return obj->IsTrue();
5811 }
5812 
Value() const5813 int64_t Integer::Value() const {
5814   i::Object obj = *Utils::OpenHandle(this);
5815   if (obj.IsSmi()) {
5816     return i::Smi::ToInt(obj);
5817   } else {
5818     return static_cast<int64_t>(obj.Number());
5819   }
5820 }
5821 
Value() const5822 int32_t Int32::Value() const {
5823   i::Object obj = *Utils::OpenHandle(this);
5824   if (obj.IsSmi()) {
5825     return i::Smi::ToInt(obj);
5826   } else {
5827     return static_cast<int32_t>(obj.Number());
5828   }
5829 }
5830 
Value() const5831 uint32_t Uint32::Value() const {
5832   i::Object obj = *Utils::OpenHandle(this);
5833   if (obj.IsSmi()) {
5834     return i::Smi::ToInt(obj);
5835   } else {
5836     return static_cast<uint32_t>(obj.Number());
5837   }
5838 }
5839 
InternalFieldCount() const5840 int v8::Object::InternalFieldCount() const {
5841   i::JSReceiver self = *Utils::OpenHandle(this);
5842   if (!self.IsJSObject()) return 0;
5843   return i::JSObject::cast(self).GetEmbedderFieldCount();
5844 }
5845 
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5846 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5847                             const char* location) {
5848   return Utils::ApiCheck(
5849       obj->IsJSObject() &&
5850           (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5851       location, "Internal field out of bounds");
5852 }
5853 
SlowGetInternalField(int index)5854 Local<Value> v8::Object::SlowGetInternalField(int index) {
5855   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5856   const char* location = "v8::Object::GetInternalField()";
5857   if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5858   i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
5859                              obj->GetIsolate());
5860   return Utils::ToLocal(value);
5861 }
5862 
SetInternalField(int index,v8::Local<Value> value)5863 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5864   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5865   const char* location = "v8::Object::SetInternalField()";
5866   if (!InternalFieldOK(obj, index, location)) return;
5867   i::Handle<i::Object> val = Utils::OpenHandle(*value);
5868   i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
5869 }
5870 
SlowGetAlignedPointerFromInternalField(int index)5871 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5872   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5873   const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5874   if (!InternalFieldOK(obj, index, location)) return nullptr;
5875   void* result;
5876   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5877                       .ToAlignedPointer(obj->GetIsolate(), &result),
5878                   location, "Unaligned pointer");
5879   return result;
5880 }
5881 
SetAlignedPointerInInternalField(int index,void * value)5882 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5883   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5884   const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5885   if (!InternalFieldOK(obj, index, location)) return;
5886   Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5887                       .store_aligned_pointer(obj->GetIsolate(), value),
5888                   location, "Unaligned pointer");
5889   DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5890 }
5891 
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])5892 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
5893                                                    void* values[]) {
5894   i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5895   const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
5896   i::DisallowGarbageCollection no_gc;
5897   i::JSObject js_obj = i::JSObject::cast(*obj);
5898   int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
5899   for (int i = 0; i < argc; i++) {
5900     int index = indices[i];
5901     if (!Utils::ApiCheck(index < nof_embedder_fields, location,
5902                          "Internal field out of bounds")) {
5903       return;
5904     }
5905     void* value = values[i];
5906     Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
5907                         .store_aligned_pointer(obj->GetIsolate(), value),
5908                     location, "Unaligned pointer");
5909     DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5910   }
5911 }
5912 
ExternalValue(i::Object obj)5913 static void* ExternalValue(i::Object obj) {
5914   // Obscure semantics for undefined, but somehow checked in our unit tests...
5915   if (obj.IsUndefined()) {
5916     return nullptr;
5917   }
5918   i::Object foreign = i::JSObject::cast(obj).GetEmbedderField(0);
5919   return reinterpret_cast<void*>(i::Foreign::cast(foreign).foreign_address());
5920 }
5921 
5922 // --- E n v i r o n m e n t ---
5923 
InitializePlatform(Platform * platform)5924 void v8::V8::InitializePlatform(Platform* platform) {
5925   i::V8::InitializePlatform(platform);
5926 }
5927 
5928 #ifdef V8_VIRTUAL_MEMORY_CAGE
InitializeVirtualMemoryCage()5929 bool v8::V8::InitializeVirtualMemoryCage() {
5930   return i::V8::InitializeVirtualMemoryCage();
5931 }
5932 #endif
5933 
ShutdownPlatform()5934 void v8::V8::ShutdownPlatform() { i::V8::ShutdownPlatform(); }
5935 
Initialize(const int build_config)5936 bool v8::V8::Initialize(const int build_config) {
5937   const bool kEmbedderPointerCompression =
5938       (build_config & kPointerCompression) != 0;
5939   if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
5940     FATAL(
5941         "Embedder-vs-V8 build configuration mismatch. On embedder side "
5942         "pointer compression is %s while on V8 side it's %s.",
5943         kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
5944         COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
5945   }
5946 
5947   const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
5948   if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
5949     FATAL(
5950         "Embedder-vs-V8 build configuration mismatch. On embedder side "
5951         "Smi value size is %d while on V8 side it's %d.",
5952         kEmbedderSmiValueSize, internal::kSmiValueSize);
5953   }
5954 
5955   const bool kEmbedderHeapSandbox = (build_config & kHeapSandbox) != 0;
5956   if (kEmbedderHeapSandbox != V8_HEAP_SANDBOX_BOOL) {
5957     FATAL(
5958         "Embedder-vs-V8 build configuration mismatch. On embedder side "
5959         "heap sandbox is %s while on V8 side it's %s.",
5960         kEmbedderHeapSandbox ? "ENABLED" : "DISABLED",
5961         V8_HEAP_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
5962   }
5963 
5964   const bool kEmbedderVirtualMemoryCage =
5965       (build_config & kVirtualMemoryCage) != 0;
5966   if (kEmbedderVirtualMemoryCage != V8_VIRTUAL_MEMORY_CAGE_BOOL) {
5967     FATAL(
5968         "Embedder-vs-V8 build configuration mismatch. On embedder side "
5969         "virtual memory cage is %s while on V8 side it's %s.",
5970         kEmbedderVirtualMemoryCage ? "ENABLED" : "DISABLED",
5971         V8_VIRTUAL_MEMORY_CAGE_BOOL ? "ENABLED" : "DISABLED");
5972   }
5973 
5974   i::V8::Initialize();
5975   return true;
5976 }
5977 
5978 #if V8_OS_LINUX || V8_OS_MACOSX || V8_OS_OPENBSD || V8_OS_FREEBSD
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)5979 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
5980                                    void* context) {
5981 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
5982   return i::trap_handler::TryHandleSignal(sig_code, info, context);
5983 #else
5984   return false;
5985 #endif
5986 }
5987 #endif
5988 
5989 #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)5990 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
5991 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
5992   return i::trap_handler::TryHandleWasmTrap(exception);
5993 #else
5994   return false;
5995 #endif
5996 }
5997 #endif
5998 
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)5999 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6000 #if V8_ENABLE_WEBASSEMBLY
6001   return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
6002 #else
6003   return false;
6004 #endif
6005 }
6006 
6007 #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6008 void V8::SetUnhandledExceptionCallback(
6009     UnhandledExceptionCallback unhandled_exception_callback) {
6010 #if defined(V8_OS_WIN64)
6011   v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
6012       unhandled_exception_callback);
6013 #else
6014   // Not implemented, port needed.
6015 #endif  // V8_OS_WIN64
6016 }
6017 #endif  // V8_OS_WIN
6018 
SetEntropySource(EntropySource entropy_source)6019 void v8::V8::SetEntropySource(EntropySource entropy_source) {
6020   base::RandomNumberGenerator::SetEntropySource(entropy_source);
6021 }
6022 
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6023 void v8::V8::SetReturnAddressLocationResolver(
6024     ReturnAddressLocationResolver return_address_resolver) {
6025   i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6026 }
6027 
Dispose()6028 bool v8::V8::Dispose() {
6029   i::V8::TearDown();
6030   return true;
6031 }
6032 
SharedMemoryStatistics()6033 SharedMemoryStatistics::SharedMemoryStatistics()
6034     : read_only_space_size_(0),
6035       read_only_space_used_size_(0),
6036       read_only_space_physical_size_(0) {}
6037 
HeapStatistics()6038 HeapStatistics::HeapStatistics()
6039     : total_heap_size_(0),
6040       total_heap_size_executable_(0),
6041       total_physical_size_(0),
6042       total_available_size_(0),
6043       used_heap_size_(0),
6044       heap_size_limit_(0),
6045       malloced_memory_(0),
6046       external_memory_(0),
6047       peak_malloced_memory_(0),
6048       does_zap_garbage_(false),
6049       number_of_native_contexts_(0),
6050       number_of_detached_contexts_(0) {}
6051 
HeapSpaceStatistics()6052 HeapSpaceStatistics::HeapSpaceStatistics()
6053     : space_name_(nullptr),
6054       space_size_(0),
6055       space_used_size_(0),
6056       space_available_size_(0),
6057       physical_space_size_(0) {}
6058 
HeapObjectStatistics()6059 HeapObjectStatistics::HeapObjectStatistics()
6060     : object_type_(nullptr),
6061       object_sub_type_(nullptr),
6062       object_count_(0),
6063       object_size_(0) {}
6064 
HeapCodeStatistics()6065 HeapCodeStatistics::HeapCodeStatistics()
6066     : code_and_metadata_size_(0),
6067       bytecode_and_metadata_size_(0),
6068       external_script_source_size_(0) {}
6069 
InitializeICU(const char * icu_data_file)6070 bool v8::V8::InitializeICU(const char* icu_data_file) {
6071   return i::InitializeICU(icu_data_file);
6072 }
6073 
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6074 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6075                                           const char* icu_data_file) {
6076   return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6077 }
6078 
InitializeExternalStartupData(const char * directory_path)6079 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6080   i::InitializeExternalStartupData(directory_path);
6081 }
6082 
6083 // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)6084 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6085   i::InitializeExternalStartupDataFromFile(snapshot_blob);
6086 }
6087 
GetVersion()6088 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6089 
6090 #ifdef V8_VIRTUAL_MEMORY_CAGE
GetVirtualMemoryCagePageAllocator()6091 PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() {
6092   CHECK(i::GetProcessWideVirtualMemoryCage()->is_initialized());
6093   return i::GetProcessWideVirtualMemoryCage()->page_allocator();
6094 }
6095 
GetVirtualMemoryCageSizeInBytes()6096 size_t v8::V8::GetVirtualMemoryCageSizeInBytes() {
6097   if (!i::GetProcessWideVirtualMemoryCage()->is_initialized()) {
6098     return 0;
6099   } else {
6100     return i::GetProcessWideVirtualMemoryCage()->size();
6101   }
6102 }
6103 #endif
6104 
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6105 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6106   i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6107 }
6108 
6109 template <typename ObjectType>
6110 struct InvokeBootstrapper;
6111 
6112 template <>
6113 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6114   i::Handle<i::Context> Invoke(
6115       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6116       v8::Local<v8::ObjectTemplate> global_proxy_template,
6117       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6118       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6119       v8::MicrotaskQueue* microtask_queue) {
6120     return isolate->bootstrapper()->CreateEnvironment(
6121         maybe_global_proxy, global_proxy_template, extensions,
6122         context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6123   }
6124 };
6125 
6126 template <>
6127 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6128   i::Handle<i::JSGlobalProxy> Invoke(
6129       i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6130       v8::Local<v8::ObjectTemplate> global_proxy_template,
6131       v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6132       v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6133       v8::MicrotaskQueue* microtask_queue) {
6134     USE(extensions);
6135     USE(context_snapshot_index);
6136     return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6137                                                      global_proxy_template);
6138   }
6139 };
6140 
6141 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)6142 static i::Handle<ObjectType> CreateEnvironment(
6143     i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6144     v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6145     v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6146     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6147     v8::MicrotaskQueue* microtask_queue) {
6148   i::Handle<ObjectType> result;
6149 
6150   {
6151     ENTER_V8_FOR_NEW_CONTEXT(isolate);
6152     v8::Local<ObjectTemplate> proxy_template;
6153     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6154     i::Handle<i::FunctionTemplateInfo> global_constructor;
6155     i::Handle<i::HeapObject> named_interceptor(
6156         isolate->factory()->undefined_value());
6157     i::Handle<i::HeapObject> indexed_interceptor(
6158         isolate->factory()->undefined_value());
6159 
6160     if (!maybe_global_template.IsEmpty()) {
6161       v8::Local<v8::ObjectTemplate> global_template =
6162           maybe_global_template.ToLocalChecked();
6163       // Make sure that the global_template has a constructor.
6164       global_constructor = EnsureConstructor(isolate, *global_template);
6165 
6166       // Create a fresh template for the global proxy object.
6167       proxy_template =
6168           ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
6169       proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6170 
6171       // Set the global template to be the prototype template of
6172       // global proxy template.
6173       i::FunctionTemplateInfo::SetPrototypeTemplate(
6174           isolate, proxy_constructor, Utils::OpenHandle(*global_template));
6175 
6176       proxy_template->SetInternalFieldCount(
6177           global_template->InternalFieldCount());
6178 
6179       // Migrate security handlers from global_template to
6180       // proxy_template.  Temporarily removing access check
6181       // information from the global template.
6182       if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
6183         i::FunctionTemplateInfo::SetAccessCheckInfo(
6184             isolate, proxy_constructor,
6185             i::handle(global_constructor->GetAccessCheckInfo(), isolate));
6186         proxy_constructor->set_needs_access_check(
6187             global_constructor->needs_access_check());
6188         global_constructor->set_needs_access_check(false);
6189         i::FunctionTemplateInfo::SetAccessCheckInfo(
6190             isolate, global_constructor,
6191             i::ReadOnlyRoots(isolate).undefined_value_handle());
6192       }
6193 
6194       // Same for other interceptors. If the global constructor has
6195       // interceptors, we need to replace them temporarily with noop
6196       // interceptors, so the map is correctly marked as having interceptors,
6197       // but we don't invoke any.
6198       if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
6199         named_interceptor =
6200             handle(global_constructor->GetNamedPropertyHandler(), isolate);
6201         i::FunctionTemplateInfo::SetNamedPropertyHandler(
6202             isolate, global_constructor,
6203             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6204       }
6205       if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
6206               isolate)) {
6207         indexed_interceptor =
6208             handle(global_constructor->GetIndexedPropertyHandler(), isolate);
6209         i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6210             isolate, global_constructor,
6211             i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6212       }
6213     }
6214 
6215     i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6216     if (!maybe_global_proxy.IsEmpty()) {
6217       maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6218           Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6219     }
6220     // Create the environment.
6221     InvokeBootstrapper<ObjectType> invoke;
6222     result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6223                            context_snapshot_index, embedder_fields_deserializer,
6224                            microtask_queue);
6225 
6226     // Restore the access check info and interceptors on the global template.
6227     if (!maybe_global_template.IsEmpty()) {
6228       DCHECK(!global_constructor.is_null());
6229       DCHECK(!proxy_constructor.is_null());
6230       i::FunctionTemplateInfo::SetAccessCheckInfo(
6231           isolate, global_constructor,
6232           i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6233       global_constructor->set_needs_access_check(
6234           proxy_constructor->needs_access_check());
6235       i::FunctionTemplateInfo::SetNamedPropertyHandler(
6236           isolate, global_constructor, named_interceptor);
6237       i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6238           isolate, global_constructor, indexed_interceptor);
6239     }
6240   }
6241   // Leave V8.
6242 
6243   return result;
6244 }
6245 
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)6246 Local<Context> NewContext(
6247     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6248     v8::MaybeLocal<ObjectTemplate> global_template,
6249     v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6250     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6251     v8::MicrotaskQueue* microtask_queue) {
6252   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6253   // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6254   // fail.
6255   // Sanity-check that the isolate is initialized and usable.
6256   CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCode());
6257 
6258   TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6259   LOG_API(isolate, Context, New);
6260   i::HandleScope scope(isolate);
6261   ExtensionConfiguration no_extensions;
6262   if (extensions == nullptr) extensions = &no_extensions;
6263   i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6264       isolate, extensions, global_template, global_object,
6265       context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6266   if (env.is_null()) {
6267     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6268     return Local<Context>();
6269   }
6270   return Utils::ToLocal(scope.CloseAndEscape(env));
6271 }
6272 
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)6273 Local<Context> v8::Context::New(
6274     v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6275     v8::MaybeLocal<ObjectTemplate> global_template,
6276     v8::MaybeLocal<Value> global_object,
6277     DeserializeInternalFieldsCallback internal_fields_deserializer,
6278     v8::MicrotaskQueue* microtask_queue) {
6279   return NewContext(external_isolate, extensions, global_template,
6280                     global_object, 0, internal_fields_deserializer,
6281                     microtask_queue);
6282 }
6283 
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)6284 MaybeLocal<Context> v8::Context::FromSnapshot(
6285     v8::Isolate* external_isolate, size_t context_snapshot_index,
6286     v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6287     v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6288     v8::MicrotaskQueue* microtask_queue) {
6289   size_t index_including_default_context = context_snapshot_index + 1;
6290   if (!i::Snapshot::HasContextSnapshot(
6291           reinterpret_cast<i::Isolate*>(external_isolate),
6292           index_including_default_context)) {
6293     return MaybeLocal<Context>();
6294   }
6295   return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6296                     global_object, index_including_default_context,
6297                     embedder_fields_deserializer, microtask_queue);
6298 }
6299 
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6300 MaybeLocal<Object> v8::Context::NewRemoteContext(
6301     v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6302     v8::MaybeLocal<v8::Value> global_object) {
6303   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6304   LOG_API(isolate, Context, NewRemoteContext);
6305   i::HandleScope scope(isolate);
6306   i::Handle<i::FunctionTemplateInfo> global_constructor =
6307       EnsureConstructor(isolate, *global_template);
6308   Utils::ApiCheck(global_constructor->needs_access_check(),
6309                   "v8::Context::NewRemoteContext",
6310                   "Global template needs to have access checks enabled.");
6311   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6312       i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6313       isolate);
6314   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6315                   "v8::Context::NewRemoteContext",
6316                   "Global template needs to have access check handlers.");
6317   i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6318       isolate, nullptr, global_template, global_object, 0,
6319       DeserializeInternalFieldsCallback(), nullptr);
6320   if (global_proxy.is_null()) {
6321     if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6322     return MaybeLocal<Object>();
6323   }
6324   return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6325 }
6326 
SetSecurityToken(Local<Value> token)6327 void v8::Context::SetSecurityToken(Local<Value> token) {
6328   i::Handle<i::Context> env = Utils::OpenHandle(this);
6329   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6330   env->set_security_token(*token_handle);
6331 }
6332 
UseDefaultSecurityToken()6333 void v8::Context::UseDefaultSecurityToken() {
6334   i::Handle<i::Context> env = Utils::OpenHandle(this);
6335   env->set_security_token(env->global_object());
6336 }
6337 
GetSecurityToken()6338 Local<Value> v8::Context::GetSecurityToken() {
6339   i::Handle<i::Context> env = Utils::OpenHandle(this);
6340   i::Isolate* isolate = env->GetIsolate();
6341   i::Object security_token = env->security_token();
6342   i::Handle<i::Object> token_handle(security_token, isolate);
6343   return Utils::ToLocal(token_handle);
6344 }
6345 
GetIsolate()6346 v8::Isolate* Context::GetIsolate() {
6347   i::Handle<i::Context> env = Utils::OpenHandle(this);
6348   return reinterpret_cast<Isolate*>(env->GetIsolate());
6349 }
6350 
GetMicrotaskQueue()6351 v8::MicrotaskQueue* Context::GetMicrotaskQueue() {
6352   i::Handle<i::Context> env = Utils::OpenHandle(this);
6353   Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue",
6354                   "Must be calld on a native context");
6355   return i::Handle<i::NativeContext>::cast(env)->microtask_queue();
6356 }
6357 
Global()6358 v8::Local<v8::Object> Context::Global() {
6359   i::Handle<i::Context> context = Utils::OpenHandle(this);
6360   i::Isolate* isolate = context->GetIsolate();
6361   i::Handle<i::Object> global(context->global_proxy(), isolate);
6362   // TODO(chromium:324812): This should always return the global proxy
6363   // but can't presently as calls to GetProtoype will return the wrong result.
6364   if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6365           context->global_object())) {
6366     global = i::Handle<i::Object>(context->global_object(), isolate);
6367   }
6368   return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6369 }
6370 
DetachGlobal()6371 void Context::DetachGlobal() {
6372   i::Handle<i::Context> context = Utils::OpenHandle(this);
6373   i::Isolate* isolate = context->GetIsolate();
6374   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6375   isolate->DetachGlobal(context);
6376 }
6377 
GetExtrasBindingObject()6378 Local<v8::Object> Context::GetExtrasBindingObject() {
6379   i::Handle<i::Context> context = Utils::OpenHandle(this);
6380   i::Isolate* isolate = context->GetIsolate();
6381   i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6382   return Utils::ToLocal(binding);
6383 }
6384 
AllowCodeGenerationFromStrings(bool allow)6385 void Context::AllowCodeGenerationFromStrings(bool allow) {
6386   i::Handle<i::Context> context = Utils::OpenHandle(this);
6387   i::Isolate* isolate = context->GetIsolate();
6388   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6389   context->set_allow_code_gen_from_strings(
6390       allow ? i::ReadOnlyRoots(isolate).true_value()
6391             : i::ReadOnlyRoots(isolate).false_value());
6392 }
6393 
IsCodeGenerationFromStringsAllowed() const6394 bool Context::IsCodeGenerationFromStringsAllowed() const {
6395   i::Context context = *Utils::OpenHandle(this);
6396   return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6397 }
6398 
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6399 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6400   i::Handle<i::Context> context = Utils::OpenHandle(this);
6401   i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6402   context->set_error_message_for_code_gen_from_strings(*error_handle);
6403 }
6404 
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6405 void Context::SetAbortScriptExecution(
6406     Context::AbortScriptExecutionCallback callback) {
6407   i::Handle<i::Context> context = Utils::OpenHandle(this);
6408   i::Isolate* isolate = context->GetIsolate();
6409   if (callback == nullptr) {
6410     context->set_script_execution_callback(
6411         i::ReadOnlyRoots(isolate).undefined_value());
6412   } else {
6413     SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6414                       callback);
6415   }
6416 }
6417 
GetContinuationPreservedEmbedderData() const6418 Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6419   i::Handle<i::Context> context = Utils::OpenHandle(this);
6420   i::Isolate* isolate = context->GetIsolate();
6421   i::Handle<i::Object> data(
6422       context->native_context().continuation_preserved_embedder_data(),
6423       isolate);
6424   return ToApiHandle<Object>(data);
6425 }
6426 
SetContinuationPreservedEmbedderData(Local<Value> data)6427 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6428   i::Handle<i::Context> context = Utils::OpenHandle(this);
6429   i::Isolate* isolate = context->GetIsolate();
6430   if (data.IsEmpty())
6431     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6432   context->native_context().set_continuation_preserved_embedder_data(
6433       *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6434 }
6435 
SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6436 void v8::Context::SetPromiseHooks(Local<Function> init_hook,
6437                                   Local<Function> before_hook,
6438                                   Local<Function> after_hook,
6439                                   Local<Function> resolve_hook) {
6440   i::Handle<i::Context> context = Utils::OpenHandle(this);
6441   i::Isolate* isolate = context->GetIsolate();
6442 
6443   i::Handle<i::Object> init = isolate->factory()->undefined_value();
6444   i::Handle<i::Object> before = isolate->factory()->undefined_value();
6445   i::Handle<i::Object> after = isolate->factory()->undefined_value();
6446   i::Handle<i::Object> resolve = isolate->factory()->undefined_value();
6447 
6448   bool has_hook = false;
6449 
6450   if (!init_hook.IsEmpty()) {
6451     init = Utils::OpenHandle(*init_hook);
6452     has_hook = true;
6453   }
6454   if (!before_hook.IsEmpty()) {
6455     before = Utils::OpenHandle(*before_hook);
6456     has_hook = true;
6457   }
6458   if (!after_hook.IsEmpty()) {
6459     after = Utils::OpenHandle(*after_hook);
6460     has_hook = true;
6461   }
6462   if (!resolve_hook.IsEmpty()) {
6463     resolve = Utils::OpenHandle(*resolve_hook);
6464     has_hook = true;
6465   }
6466 
6467   isolate->SetHasContextPromiseHooks(has_hook);
6468 
6469   context->native_context().set_promise_hook_init_function(*init);
6470   context->native_context().set_promise_hook_before_function(*before);
6471   context->native_context().set_promise_hook_after_function(*after);
6472   context->native_context().set_promise_hook_resolve_function(*resolve);
6473 }
6474 
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6475 MaybeLocal<Context> metrics::Recorder::GetContext(
6476     Isolate* isolate, metrics::Recorder::ContextId id) {
6477   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6478   return i_isolate->GetContextFromRecorderContextId(id);
6479 }
6480 
GetContextId(Local<Context> context)6481 metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6482     Local<Context> context) {
6483   i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6484   i::Isolate* isolate = i_context->GetIsolate();
6485   return isolate->GetOrRegisterRecorderContextId(
6486       handle(i_context->native_context(), isolate));
6487 }
6488 
Get(v8::Isolate * isolate)6489 metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6490   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6491   return *i_isolate->GetCurrentLongTaskStats();
6492 }
6493 
6494 namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6495 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6496                                             i::FixedArray list, size_t index) {
6497   if (index < static_cast<size_t>(list.length())) {
6498     int int_index = static_cast<int>(index);
6499     i::Object object = list.get(int_index);
6500     if (!object.IsTheHole(isolate)) {
6501       list.set_the_hole(isolate, int_index);
6502       // Shrink the list so that the last element is not the hole (unless it's
6503       // the first element, because we don't want to end up with a non-canonical
6504       // empty FixedArray).
6505       int last = list.length() - 1;
6506       while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6507       if (last != -1) list.Shrink(isolate, last + 1);
6508       return i::Handle<i::Object>(object, isolate).location();
6509     }
6510   }
6511   return nullptr;
6512 }
6513 }  // anonymous namespace
6514 
GetDataFromSnapshotOnce(size_t index)6515 i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6516   auto context = Utils::OpenHandle(this);
6517   i::Isolate* i_isolate = context->GetIsolate();
6518   i::FixedArray list = context->serialized_objects();
6519   return GetSerializedDataFromFixedArray(i_isolate, list, index);
6520 }
6521 
NewInstance(Local<Context> context)6522 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6523   PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6524   auto self = Utils::OpenHandle(this);
6525   Local<Object> result;
6526   has_pending_exception = !ToLocal<Object>(
6527       i::ApiNatives::InstantiateObject(isolate, self), &result);
6528   RETURN_ON_FAILED_EXECUTION(Object);
6529   RETURN_ESCAPED(result);
6530 }
6531 
CheckCast(Data * that)6532 void v8::ObjectTemplate::CheckCast(Data* that) {
6533   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6534   Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6535                   "Value is not an ObjectTemplate");
6536 }
6537 
CheckCast(Data * that)6538 void v8::FunctionTemplate::CheckCast(Data* that) {
6539   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6540   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6541                   "Value is not a FunctionTemplate");
6542 }
6543 
CheckCast(Data * that)6544 void v8::Signature::CheckCast(Data* that) {
6545   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6546   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6547                   "Value is not a Signature");
6548 }
6549 
CheckCast(Data * that)6550 void v8::AccessorSignature::CheckCast(Data* that) {
6551   i::Handle<i::Object> obj = Utils::OpenHandle(that);
6552   Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6553                   "Value is not an AccessorSignature");
6554 }
6555 
GetFunction(Local<Context> context)6556 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6557   PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6558   auto self = Utils::OpenHandle(this);
6559   Local<Function> result;
6560   has_pending_exception =
6561       !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6562   RETURN_ON_FAILED_EXECUTION(Function);
6563   RETURN_ESCAPED(result);
6564 }
6565 
NewRemoteInstance()6566 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6567   auto self = Utils::OpenHandle(this);
6568   i::Isolate* isolate = self->GetIsolate();
6569   LOG_API(isolate, FunctionTemplate, NewRemoteInstance);
6570   i::HandleScope scope(isolate);
6571   i::Handle<i::FunctionTemplateInfo> constructor =
6572       EnsureConstructor(isolate, *InstanceTemplate());
6573   Utils::ApiCheck(constructor->needs_access_check(),
6574                   "v8::FunctionTemplate::NewRemoteInstance",
6575                   "InstanceTemplate needs to have access checks enabled.");
6576   i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6577       i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6578   Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6579                   "v8::FunctionTemplate::NewRemoteInstance",
6580                   "InstanceTemplate needs to have access check handlers.");
6581   i::Handle<i::JSObject> object;
6582   if (!i::ApiNatives::InstantiateRemoteObject(
6583            Utils::OpenHandle(*InstanceTemplate()))
6584            .ToHandle(&object)) {
6585     if (isolate->has_pending_exception()) {
6586       isolate->OptionalRescheduleException(true);
6587     }
6588     return MaybeLocal<Object>();
6589   }
6590   return Utils::ToLocal(scope.CloseAndEscape(object));
6591 }
6592 
HasInstance(v8::Local<v8::Value> value)6593 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6594   auto self = Utils::OpenHandle(this);
6595   auto obj = Utils::OpenHandle(*value);
6596   if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6597     return true;
6598   }
6599   if (obj->IsJSGlobalProxy()) {
6600     // If it's a global proxy, then test with the global object. Note that the
6601     // inner global object may not necessarily be a JSGlobalObject.
6602     i::PrototypeIterator iter(self->GetIsolate(),
6603                               i::JSObject::cast(*obj).map());
6604     // The global proxy should always have a prototype, as it is a bug to call
6605     // this on a detached JSGlobalProxy.
6606     DCHECK(!iter.IsAtEnd());
6607     return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6608   }
6609   return false;
6610 }
6611 
IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6612 bool FunctionTemplate::IsLeafTemplateForApiObject(
6613     v8::Local<v8::Value> value) const {
6614   i::DisallowGarbageCollection no_gc;
6615 
6616   i::Object object = *Utils::OpenHandle(*value);
6617 
6618   auto self = Utils::OpenHandle(this);
6619   return self->IsLeafTemplateForApiObject(object);
6620 }
6621 
New(Isolate * isolate,void * value)6622 Local<External> v8::External::New(Isolate* isolate, void* value) {
6623   STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6624   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6625   LOG_API(i_isolate, External, New);
6626   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6627   i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6628   return Utils::ExternalToLocal(external);
6629 }
6630 
Value() const6631 void* External::Value() const {
6632   return ExternalValue(*Utils::OpenHandle(this));
6633 }
6634 
6635 // anonymous namespace for string creation helper functions
6636 namespace {
6637 
StringLength(const char * string)6638 inline int StringLength(const char* string) {
6639   size_t len = strlen(string);
6640   CHECK_GE(i::kMaxInt, len);
6641   return static_cast<int>(len);
6642 }
6643 
StringLength(const uint8_t * string)6644 inline int StringLength(const uint8_t* string) {
6645   return StringLength(reinterpret_cast<const char*>(string));
6646 }
6647 
StringLength(const uint16_t * string)6648 inline int StringLength(const uint16_t* string) {
6649   size_t length = 0;
6650   while (string[length] != '\0') length++;
6651   CHECK_GE(i::kMaxInt, length);
6652   return static_cast<int>(length);
6653 }
6654 
6655 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6656 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6657                                            NewStringType type,
6658                                            base::Vector<const char> string) {
6659   if (type == NewStringType::kInternalized) {
6660     return factory->InternalizeUtf8String(string);
6661   }
6662   return factory->NewStringFromUtf8(string);
6663 }
6664 
6665 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6666 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6667                                            NewStringType type,
6668                                            base::Vector<const uint8_t> string) {
6669   if (type == NewStringType::kInternalized) {
6670     return factory->InternalizeString(string);
6671   }
6672   return factory->NewStringFromOneByte(string);
6673 }
6674 
6675 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6676 inline i::MaybeHandle<i::String> NewString(
6677     i::Factory* factory, NewStringType type,
6678     base::Vector<const uint16_t> string) {
6679   if (type == NewStringType::kInternalized) {
6680     return factory->InternalizeString(string);
6681   }
6682   return factory->NewStringFromTwoByte(string);
6683 }
6684 
6685 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6686 
6687 }  // anonymous namespace
6688 
6689 // TODO(dcarney): throw a context free exception.
6690 #define NEW_STRING(isolate, class_name, function_name, Char, data, type,   \
6691                    length)                                                 \
6692   MaybeLocal<String> result;                                               \
6693   if (length == 0) {                                                       \
6694     result = String::Empty(isolate);                                       \
6695   } else if (length > i::String::kMaxLength) {                             \
6696     result = MaybeLocal<String>();                                         \
6697   } else {                                                                 \
6698     i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6699     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);                            \
6700     LOG_API(i_isolate, class_name, function_name);                         \
6701     if (length < 0) length = StringLength(data);                           \
6702     i::Handle<i::String> handle_result =                                   \
6703         NewString(i_isolate->factory(), type,                              \
6704                   base::Vector<const Char>(data, length))                  \
6705             .ToHandleChecked();                                            \
6706     result = Utils::ToLocal(handle_result);                                \
6707   }
6708 
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6709 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6710                                          NewStringType type, int length) {
6711   DCHECK_LE(length, i::String::kMaxLength);
6712   i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6713   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6714   LOG_API(i_isolate, String, NewFromUtf8Literal);
6715   i::Handle<i::String> handle_result =
6716       NewString(i_isolate->factory(), type,
6717                 base::Vector<const char>(literal, length))
6718           .ToHandleChecked();
6719   return Utils::ToLocal(handle_result);
6720 }
6721 
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6722 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6723                                        NewStringType type, int length) {
6724   NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6725   return result;
6726 }
6727 
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6728 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6729                                           NewStringType type, int length) {
6730   NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6731   return result;
6732 }
6733 
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6734 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6735                                           const uint16_t* data,
6736                                           NewStringType type, int length) {
6737   NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6738   return result;
6739 }
6740 
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6741 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6742                                  Local<String> right) {
6743   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6744   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6745   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6746   LOG_API(isolate, String, Concat);
6747   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6748   // If we are steering towards a range error, do not wait for the error to be
6749   // thrown, and return the null handle instead.
6750   if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6751     return Local<String>();
6752   }
6753   i::Handle<i::String> result = isolate->factory()
6754                                     ->NewConsString(left_string, right_string)
6755                                     .ToHandleChecked();
6756   return Utils::ToLocal(result);
6757 }
6758 
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6759 MaybeLocal<String> v8::String::NewExternalTwoByte(
6760     Isolate* isolate, v8::String::ExternalStringResource* resource) {
6761   CHECK(resource && resource->data());
6762   // TODO(dcarney): throw a context free exception.
6763   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6764     return MaybeLocal<String>();
6765   }
6766   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6767   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6768   LOG_API(i_isolate, String, NewExternalTwoByte);
6769   if (resource->length() > 0) {
6770     i::Handle<i::String> string = i_isolate->factory()
6771                                       ->NewExternalStringFromTwoByte(resource)
6772                                       .ToHandleChecked();
6773     return Utils::ToLocal(string);
6774   } else {
6775     // The resource isn't going to be used, free it immediately.
6776     resource->Dispose();
6777     return Utils::ToLocal(i_isolate->factory()->empty_string());
6778   }
6779 }
6780 
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6781 MaybeLocal<String> v8::String::NewExternalOneByte(
6782     Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6783   CHECK_NOT_NULL(resource);
6784   // TODO(dcarney): throw a context free exception.
6785   if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6786     return MaybeLocal<String>();
6787   }
6788   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6789   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6790   LOG_API(i_isolate, String, NewExternalOneByte);
6791   if (resource->length() == 0) {
6792     // The resource isn't going to be used, free it immediately.
6793     resource->Dispose();
6794     return Utils::ToLocal(i_isolate->factory()->empty_string());
6795   }
6796   CHECK_NOT_NULL(resource->data());
6797   i::Handle<i::String> string = i_isolate->factory()
6798                                     ->NewExternalStringFromOneByte(resource)
6799                                     .ToHandleChecked();
6800   return Utils::ToLocal(string);
6801 }
6802 
MakeExternal(v8::String::ExternalStringResource * resource)6803 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6804   i::DisallowGarbageCollection no_gc;
6805 
6806   i::String obj = *Utils::OpenHandle(this);
6807 
6808   if (obj.IsThinString()) {
6809     obj = i::ThinString::cast(obj).actual();
6810   }
6811 
6812   if (!obj.SupportsExternalization()) {
6813     return false;
6814   }
6815 
6816   // It is safe to call GetIsolateFromWritableHeapObject because
6817   // SupportsExternalization already checked that the object is writable.
6818   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6819   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6820 
6821   CHECK(resource && resource->data());
6822 
6823   bool result = obj.MakeExternal(resource);
6824   DCHECK(result);
6825   DCHECK(obj.IsExternalString());
6826   return result;
6827 }
6828 
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6829 bool v8::String::MakeExternal(
6830     v8::String::ExternalOneByteStringResource* resource) {
6831   i::DisallowGarbageCollection no_gc;
6832 
6833   i::String obj = *Utils::OpenHandle(this);
6834 
6835   if (obj.IsThinString()) {
6836     obj = i::ThinString::cast(obj).actual();
6837   }
6838 
6839   if (!obj.SupportsExternalization()) {
6840     return false;
6841   }
6842 
6843   // It is safe to call GetIsolateFromWritableHeapObject because
6844   // SupportsExternalization already checked that the object is writable.
6845   i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6846   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6847 
6848   CHECK(resource && resource->data());
6849 
6850   bool result = obj.MakeExternal(resource);
6851   DCHECK_IMPLIES(result, obj.IsExternalString());
6852   return result;
6853 }
6854 
CanMakeExternal() const6855 bool v8::String::CanMakeExternal() const {
6856   i::String obj = *Utils::OpenHandle(this);
6857 
6858   if (obj.IsThinString()) {
6859     obj = i::ThinString::cast(obj).actual();
6860   }
6861 
6862   if (!obj.SupportsExternalization()) {
6863     return false;
6864   }
6865 
6866   // Only old space strings should be externalized.
6867   return !i::Heap::InYoungGeneration(obj);
6868 }
6869 
StringEquals(Local<String> that) const6870 bool v8::String::StringEquals(Local<String> that) const {
6871   auto self = Utils::OpenHandle(this);
6872   auto other = Utils::OpenHandle(*that);
6873   return self->Equals(*other);
6874 }
6875 
GetIsolate()6876 Isolate* v8::Object::GetIsolate() {
6877   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
6878   return reinterpret_cast<Isolate*>(i_isolate);
6879 }
6880 
New(Isolate * isolate)6881 Local<v8::Object> v8::Object::New(Isolate* isolate) {
6882   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6883   LOG_API(i_isolate, Object, New);
6884   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6885   i::Handle<i::JSObject> obj =
6886       i_isolate->factory()->NewJSObject(i_isolate->object_function());
6887   return Utils::ToLocal(obj);
6888 }
6889 
6890 namespace {
6891 
6892 // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference
6893 // in the return types of the different Add functions:
6894 // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns
6895 // Handle.
6896 template <typename T>
ToHandle(i::Handle<T> h)6897 i::Handle<T> ToHandle(i::Handle<T> h) {
6898   return h;
6899 }
6900 template <typename T>
ToHandle(i::MaybeHandle<T> h)6901 i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
6902   return h.ToHandleChecked();
6903 }
6904 
6905 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)6906 void AddPropertiesAndElementsToObject(i::Isolate* i_isolate,
6907                                       i::Handle<Dictionary>& properties,
6908                                       i::Handle<i::FixedArrayBase>& elements,
6909                                       Local<Name>* names, Local<Value>* values,
6910                                       size_t length) {
6911   for (size_t i = 0; i < length; ++i) {
6912     i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
6913     i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
6914 
6915     // See if the {name} is a valid array index, in which case we need to
6916     // add the {name}/{value} pair to the {elements}, otherwise they end
6917     // up in the {properties} backing store.
6918     uint32_t index;
6919     if (name->AsArrayIndex(&index)) {
6920       // If this is the first element, allocate a proper
6921       // dictionary elements backing store for {elements}.
6922       if (!elements->IsNumberDictionary()) {
6923         elements =
6924             i::NumberDictionary::New(i_isolate, static_cast<int>(length));
6925       }
6926       elements = i::NumberDictionary::Set(
6927           i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
6928           value);
6929     } else {
6930       // Internalize the {name} first.
6931       name = i_isolate->factory()->InternalizeName(name);
6932       i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
6933       if (entry.is_not_found()) {
6934         // Add the {name}/{value} pair as a new entry.
6935         properties = ToHandle(Dictionary::Add(
6936             i_isolate, properties, name, value, i::PropertyDetails::Empty()));
6937       } else {
6938         // Overwrite the {entry} with the {value}.
6939         properties->ValueAtPut(entry, *value);
6940       }
6941     }
6942   }
6943 }
6944 
6945 }  // namespace
6946 
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)6947 Local<v8::Object> v8::Object::New(Isolate* isolate,
6948                                   Local<Value> prototype_or_null,
6949                                   Local<Name>* names, Local<Value>* values,
6950                                   size_t length) {
6951   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6952   i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
6953   if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
6954                        "v8::Object::New", "prototype must be null or object")) {
6955     return Local<v8::Object>();
6956   }
6957   LOG_API(i_isolate, Object, New);
6958   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6959 
6960   i::Handle<i::FixedArrayBase> elements =
6961       i_isolate->factory()->empty_fixed_array();
6962 
6963   // We assume that this API is mostly used to create objects with named
6964   // properties, and so we default to creating a properties backing store
6965   // large enough to hold all of them, while we start with no elements
6966   // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
6967   if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
6968     i::Handle<i::SwissNameDictionary> properties =
6969         i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length));
6970     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
6971                                      values, length);
6972     i::Handle<i::JSObject> obj =
6973         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
6974             i::Handle<i::HeapObject>::cast(proto), properties, elements);
6975     return Utils::ToLocal(obj);
6976   } else {
6977     i::Handle<i::NameDictionary> properties =
6978         i::NameDictionary::New(i_isolate, static_cast<int>(length));
6979     AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
6980                                      values, length);
6981     i::Handle<i::JSObject> obj =
6982         i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
6983             i::Handle<i::HeapObject>::cast(proto), properties, elements);
6984     return Utils::ToLocal(obj);
6985   }
6986 }
6987 
New(Isolate * isolate,double value)6988 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
6989   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6990   LOG_API(i_isolate, NumberObject, New);
6991   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6992   i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
6993   i::Handle<i::Object> obj =
6994       i::Object::ToObject(i_isolate, number).ToHandleChecked();
6995   return Utils::ToLocal(obj);
6996 }
6997 
ValueOf() const6998 double v8::NumberObject::ValueOf() const {
6999   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7000   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7001       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7002   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7003   LOG_API(isolate, NumberObject, NumberValue);
7004   return js_primitive_wrapper->value().Number();
7005 }
7006 
New(Isolate * isolate,int64_t value)7007 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
7008   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7009   LOG_API(i_isolate, BigIntObject, New);
7010   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7011   i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
7012   i::Handle<i::Object> obj =
7013       i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
7014   return Utils::ToLocal(obj);
7015 }
7016 
ValueOf() const7017 Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
7018   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7019   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7020       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7021   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7022   LOG_API(isolate, BigIntObject, BigIntValue);
7023   return Utils::ToLocal(i::Handle<i::BigInt>(
7024       i::BigInt::cast(js_primitive_wrapper->value()), isolate));
7025 }
7026 
New(Isolate * isolate,bool value)7027 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7028   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7029   LOG_API(i_isolate, BooleanObject, New);
7030   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7031   i::Handle<i::Object> boolean(value
7032                                    ? i::ReadOnlyRoots(i_isolate).true_value()
7033                                    : i::ReadOnlyRoots(i_isolate).false_value(),
7034                                i_isolate);
7035   i::Handle<i::Object> obj =
7036       i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7037   return Utils::ToLocal(obj);
7038 }
7039 
ValueOf() const7040 bool v8::BooleanObject::ValueOf() const {
7041   i::Object obj = *Utils::OpenHandle(this);
7042   i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
7043   i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
7044   LOG_API(isolate, BooleanObject, BooleanValue);
7045   return js_primitive_wrapper.value().IsTrue(isolate);
7046 }
7047 
New(Isolate * v8_isolate,Local<String> value)7048 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
7049                                        Local<String> value) {
7050   i::Handle<i::String> string = Utils::OpenHandle(*value);
7051   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7052   LOG_API(isolate, StringObject, New);
7053   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7054   i::Handle<i::Object> obj =
7055       i::Object::ToObject(isolate, string).ToHandleChecked();
7056   return Utils::ToLocal(obj);
7057 }
7058 
ValueOf() const7059 Local<v8::String> v8::StringObject::ValueOf() const {
7060   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7061   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7062       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7063   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7064   LOG_API(isolate, StringObject, StringValue);
7065   return Utils::ToLocal(i::Handle<i::String>(
7066       i::String::cast(js_primitive_wrapper->value()), isolate));
7067 }
7068 
New(Isolate * isolate,Local<Symbol> value)7069 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7070   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7071   LOG_API(i_isolate, SymbolObject, New);
7072   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7073   i::Handle<i::Object> obj =
7074       i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
7075           .ToHandleChecked();
7076   return Utils::ToLocal(obj);
7077 }
7078 
ValueOf() const7079 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7080   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7081   i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7082       i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7083   i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7084   LOG_API(isolate, SymbolObject, SymbolValue);
7085   return Utils::ToLocal(i::Handle<i::Symbol>(
7086       i::Symbol::cast(js_primitive_wrapper->value()), isolate));
7087 }
7088 
New(Local<Context> context,double time)7089 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7090   if (std::isnan(time)) {
7091     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7092     time = std::numeric_limits<double>::quiet_NaN();
7093   }
7094   PREPARE_FOR_EXECUTION(context, Date, New, Value);
7095   Local<Value> result;
7096   has_pending_exception = !ToLocal<Value>(
7097       i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7098       &result);
7099   RETURN_ON_FAILED_EXECUTION(Value);
7100   RETURN_ESCAPED(result);
7101 }
7102 
ValueOf() const7103 double v8::Date::ValueOf() const {
7104   i::Handle<i::Object> obj = Utils::OpenHandle(this);
7105   i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7106   i::Isolate* isolate = jsdate->GetIsolate();
7107   LOG_API(isolate, Date, NumberValue);
7108   return jsdate->value().Number();
7109 }
7110 
7111 // Assert that the static TimeZoneDetection cast in
7112 // DateTimeConfigurationChangeNotification is valid.
7113 #define TIME_ZONE_DETECTION_ASSERT_EQ(value)                     \
7114   STATIC_ASSERT(                                                 \
7115       static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
7116       static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
7117 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7118 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7119 #undef TIME_ZONE_DETECTION_ASSERT_EQ
7120 
7121 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7122                                        Local<String> pattern, Flags flags) {
7123   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7124   Local<v8::RegExp> result;
7125   has_pending_exception =
7126       !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7127                                         static_cast<i::JSRegExp::Flags>(flags)),
7128                        &result);
7129   RETURN_ON_FAILED_EXECUTION(RegExp);
7130   RETURN_ESCAPED(result);
7131 }
7132 
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7133 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
7134     Local<Context> context, Local<String> pattern, Flags flags,
7135     uint32_t backtrack_limit) {
7136   Utils::ApiCheck(i::Smi::IsValid(backtrack_limit),
7137                   "v8::RegExp::NewWithBacktrackLimit",
7138                   "backtrack_limit is too large or too small.");
7139   Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit,
7140                   "v8::RegExp::NewWithBacktrackLimit",
7141                   "Must set backtrack_limit");
7142   PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7143   Local<v8::RegExp> result;
7144   has_pending_exception = !ToLocal<RegExp>(
7145       i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7146                        static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
7147       &result);
7148   RETURN_ON_FAILED_EXECUTION(RegExp);
7149   RETURN_ESCAPED(result);
7150 }
7151 
GetSource() const7152 Local<v8::String> v8::RegExp::GetSource() const {
7153   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7154   return Utils::ToLocal(
7155       i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate()));
7156 }
7157 
7158 // Assert that the static flags cast in GetFlags is valid.
7159 #define REGEXP_FLAG_ASSERT_EQ(flag)                   \
7160   STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7161                 static_cast<int>(i::JSRegExp::flag))
7162 REGEXP_FLAG_ASSERT_EQ(kNone);
7163 REGEXP_FLAG_ASSERT_EQ(kGlobal);
7164 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7165 REGEXP_FLAG_ASSERT_EQ(kMultiline);
7166 REGEXP_FLAG_ASSERT_EQ(kSticky);
7167 REGEXP_FLAG_ASSERT_EQ(kUnicode);
7168 REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7169 REGEXP_FLAG_ASSERT_EQ(kLinear);
7170 #undef REGEXP_FLAG_ASSERT_EQ
7171 
GetFlags() const7172 v8::RegExp::Flags v8::RegExp::GetFlags() const {
7173   i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7174   return RegExp::Flags(static_cast<int>(obj->flags()));
7175 }
7176 
Exec(Local<Context> context,Local<v8::String> subject)7177 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
7178                                         Local<v8::String> subject) {
7179   PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
7180 
7181   i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
7182   i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
7183 
7184   // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
7185   // mind. It fetches the 'exec' property and then calls it through JSEntry.
7186   // Unfortunately, this is currently the only full implementation of
7187   // RegExp.prototype.exec available in C++.
7188   Local<v8::Object> result;
7189   has_pending_exception = !ToLocal<Object>(
7190       i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
7191                                  isolate->factory()->undefined_value()),
7192       &result);
7193 
7194   RETURN_ON_FAILED_EXECUTION(Object);
7195   RETURN_ESCAPED(result);
7196 }
7197 
New(Isolate * isolate,int length)7198 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7199   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7200   LOG_API(i_isolate, Array, New);
7201   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7202   int real_length = length > 0 ? length : 0;
7203   i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7204   i::Handle<i::Object> length_obj =
7205       i_isolate->factory()->NewNumberFromInt(real_length);
7206   obj->set_length(*length_obj);
7207   return Utils::ToLocal(obj);
7208 }
7209 
New(Isolate * isolate,Local<Value> * elements,size_t length)7210 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
7211                                 size_t length) {
7212   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7213   i::Factory* factory = i_isolate->factory();
7214   LOG_API(i_isolate, Array, New);
7215   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7216   int len = static_cast<int>(length);
7217 
7218   i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
7219   for (int i = 0; i < len; i++) {
7220     i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
7221     result->set(i, *element);
7222   }
7223 
7224   return Utils::ToLocal(
7225       factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
7226 }
7227 
Length() const7228 uint32_t v8::Array::Length() const {
7229   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7230   i::Object length = obj->length();
7231   if (length.IsSmi()) {
7232     return i::Smi::ToInt(length);
7233   } else {
7234     return static_cast<uint32_t>(length.Number());
7235   }
7236 }
7237 
New(Isolate * isolate)7238 Local<v8::Map> v8::Map::New(Isolate* isolate) {
7239   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7240   LOG_API(i_isolate, Map, New);
7241   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7242   i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7243   return Utils::ToLocal(obj);
7244 }
7245 
Size() const7246 size_t v8::Map::Size() const {
7247   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7248   return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7249 }
7250 
Clear()7251 void Map::Clear() {
7252   auto self = Utils::OpenHandle(this);
7253   i::Isolate* isolate = self->GetIsolate();
7254   LOG_API(isolate, Map, Clear);
7255   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7256   i::JSMap::Clear(isolate, self);
7257 }
7258 
Get(Local<Context> context,Local<Value> key)7259 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7260   PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7261   auto self = Utils::OpenHandle(this);
7262   Local<Value> result;
7263   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7264   has_pending_exception =
7265       !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
7266                                                 self, arraysize(argv), argv),
7267                       &result);
7268   RETURN_ON_FAILED_EXECUTION(Value);
7269   RETURN_ESCAPED(result);
7270 }
7271 
Set(Local<Context> context,Local<Value> key,Local<Value> value)7272 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7273                          Local<Value> value) {
7274   PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7275   auto self = Utils::OpenHandle(this);
7276   i::Handle<i::Object> result;
7277   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7278                                  Utils::OpenHandle(*value)};
7279   has_pending_exception =
7280       !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
7281                                  arraysize(argv), argv)
7282            .ToHandle(&result);
7283   RETURN_ON_FAILED_EXECUTION(Map);
7284   RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7285 }
7286 
Has(Local<Context> context,Local<Value> key)7287 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7288   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7289   ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7290   auto self = Utils::OpenHandle(this);
7291   i::Handle<i::Object> result;
7292   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7293   has_pending_exception =
7294       !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
7295                                  arraysize(argv), argv)
7296            .ToHandle(&result);
7297   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7298   return Just(result->IsTrue(isolate));
7299 }
7300 
Delete(Local<Context> context,Local<Value> key)7301 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7302   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7303   ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7304   auto self = Utils::OpenHandle(this);
7305   i::Handle<i::Object> result;
7306   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7307   has_pending_exception =
7308       !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
7309                                  arraysize(argv), argv)
7310            .ToHandle(&result);
7311   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7312   return Just(result->IsTrue(isolate));
7313 }
7314 
7315 namespace {
7316 
7317 enum class MapAsArrayKind {
7318   kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7319   kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7320   kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7321 };
7322 
7323 enum class SetAsArrayKind {
7324   kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7325   kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7326 };
7327 
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7328 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7329                                  int offset, MapAsArrayKind kind) {
7330   i::Factory* factory = isolate->factory();
7331   i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7332                                      isolate);
7333   const bool collect_keys =
7334       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7335   const bool collect_values =
7336       kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7337   int capacity = table->UsedCapacity();
7338   int max_length =
7339       (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7340   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7341   int result_index = 0;
7342   {
7343     i::DisallowGarbageCollection no_gc;
7344     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7345     for (int i = offset; i < capacity; ++i) {
7346       i::InternalIndex entry(i);
7347       i::Object key = table->KeyAt(entry);
7348       if (key == the_hole) continue;
7349       if (collect_keys) result->set(result_index++, key);
7350       if (collect_values) result->set(result_index++, table->ValueAt(entry));
7351     }
7352   }
7353   DCHECK_GE(max_length, result_index);
7354   if (result_index == 0) return factory->NewJSArray(0);
7355   result->Shrink(isolate, result_index);
7356   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7357                                          result_index);
7358 }
7359 
7360 }  // namespace
7361 
AsArray() const7362 Local<Array> Map::AsArray() const {
7363   i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7364   i::Isolate* isolate = obj->GetIsolate();
7365   LOG_API(isolate, Map, AsArray);
7366   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7367   return Utils::ToLocal(
7368       MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7369 }
7370 
New(Isolate * isolate)7371 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7372   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7373   LOG_API(i_isolate, Set, New);
7374   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7375   i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7376   return Utils::ToLocal(obj);
7377 }
7378 
Size() const7379 size_t v8::Set::Size() const {
7380   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7381   return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7382 }
7383 
Clear()7384 void Set::Clear() {
7385   auto self = Utils::OpenHandle(this);
7386   i::Isolate* isolate = self->GetIsolate();
7387   LOG_API(isolate, Set, Clear);
7388   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7389   i::JSSet::Clear(isolate, self);
7390 }
7391 
Add(Local<Context> context,Local<Value> key)7392 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7393   PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7394   auto self = Utils::OpenHandle(this);
7395   i::Handle<i::Object> result;
7396   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7397   has_pending_exception =
7398       !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7399                                  arraysize(argv), argv)
7400            .ToHandle(&result);
7401   RETURN_ON_FAILED_EXECUTION(Set);
7402   RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7403 }
7404 
Has(Local<Context> context,Local<Value> key)7405 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7406   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7407   ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7408   auto self = Utils::OpenHandle(this);
7409   i::Handle<i::Object> result;
7410   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7411   has_pending_exception =
7412       !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7413                                  arraysize(argv), argv)
7414            .ToHandle(&result);
7415   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7416   return Just(result->IsTrue(isolate));
7417 }
7418 
Delete(Local<Context> context,Local<Value> key)7419 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7420   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7421   ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7422   auto self = Utils::OpenHandle(this);
7423   i::Handle<i::Object> result;
7424   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7425   has_pending_exception =
7426       !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7427                                  arraysize(argv), argv)
7428            .ToHandle(&result);
7429   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7430   return Just(result->IsTrue(isolate));
7431 }
7432 
7433 namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7434 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7435                                  int offset, SetAsArrayKind kind) {
7436   i::Factory* factory = isolate->factory();
7437   i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7438                                      isolate);
7439   // Elements skipped by |offset| may already be deleted.
7440   int capacity = table->UsedCapacity();
7441   const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7442   int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7443   if (max_length == 0) return factory->NewJSArray(0);
7444   i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7445   int result_index = 0;
7446   {
7447     i::DisallowGarbageCollection no_gc;
7448     i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7449     for (int i = offset; i < capacity; ++i) {
7450       i::InternalIndex entry(i);
7451       i::Object key = table->KeyAt(entry);
7452       if (key == the_hole) continue;
7453       result->set(result_index++, key);
7454       if (collect_key_values) result->set(result_index++, key);
7455     }
7456   }
7457   DCHECK_GE(max_length, result_index);
7458   if (result_index == 0) return factory->NewJSArray(0);
7459   result->Shrink(isolate, result_index);
7460   return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7461                                          result_index);
7462 }
7463 }  // namespace
7464 
AsArray() const7465 Local<Array> Set::AsArray() const {
7466   i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7467   i::Isolate* isolate = obj->GetIsolate();
7468   LOG_API(isolate, Set, AsArray);
7469   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7470   return Utils::ToLocal(
7471       SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7472 }
7473 
New(Local<Context> context)7474 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7475   PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7476   Local<Promise::Resolver> result;
7477   has_pending_exception =
7478       !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7479   RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7480   RETURN_ESCAPED(result);
7481 }
7482 
GetPromise()7483 Local<Promise> Promise::Resolver::GetPromise() {
7484   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7485   return Local<Promise>::Cast(Utils::ToLocal(promise));
7486 }
7487 
Resolve(Local<Context> context,Local<Value> value)7488 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7489                                        Local<Value> value) {
7490   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7491   ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7492            i::HandleScope);
7493   auto self = Utils::OpenHandle(this);
7494   auto promise = i::Handle<i::JSPromise>::cast(self);
7495 
7496   if (promise->status() != Promise::kPending) {
7497     return Just(true);
7498   }
7499 
7500   has_pending_exception =
7501       i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7502   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7503   return Just(true);
7504 }
7505 
Reject(Local<Context> context,Local<Value> value)7506 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7507                                       Local<Value> value) {
7508   auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7509   ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7510            i::HandleScope);
7511   auto self = Utils::OpenHandle(this);
7512   auto promise = i::Handle<i::JSPromise>::cast(self);
7513 
7514   if (promise->status() != Promise::kPending) {
7515     return Just(true);
7516   }
7517 
7518   has_pending_exception =
7519       i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7520   RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7521   return Just(true);
7522 }
7523 
Catch(Local<Context> context,Local<Function> handler)7524 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7525                                    Local<Function> handler) {
7526   PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7527   auto self = Utils::OpenHandle(this);
7528   i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(),
7529                                  Utils::OpenHandle(*handler)};
7530   i::Handle<i::Object> result;
7531   // Do not call the built-in Promise.prototype.catch!
7532   // v8::Promise should not call out to a monkeypatched Promise.prototype.then
7533   // as the implementation of Promise.prototype.catch does.
7534   has_pending_exception =
7535       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7536                                  arraysize(argv), argv)
7537            .ToHandle(&result);
7538   RETURN_ON_FAILED_EXECUTION(Promise);
7539   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7540 }
7541 
Then(Local<Context> context,Local<Function> handler)7542 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7543                                   Local<Function> handler) {
7544   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7545   auto self = Utils::OpenHandle(this);
7546   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7547   i::Handle<i::Object> result;
7548   has_pending_exception =
7549       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7550                                  arraysize(argv), argv)
7551            .ToHandle(&result);
7552   RETURN_ON_FAILED_EXECUTION(Promise);
7553   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7554 }
7555 
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7556 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7557                                   Local<Function> on_fulfilled,
7558                                   Local<Function> on_rejected) {
7559   PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7560   auto self = Utils::OpenHandle(this);
7561   i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7562                                  Utils::OpenHandle(*on_rejected)};
7563   i::Handle<i::Object> result;
7564   has_pending_exception =
7565       !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7566                                  arraysize(argv), argv)
7567            .ToHandle(&result);
7568   RETURN_ON_FAILED_EXECUTION(Promise);
7569   RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7570 }
7571 
HasHandler() const7572 bool Promise::HasHandler() const {
7573   i::JSReceiver promise = *Utils::OpenHandle(this);
7574   i::Isolate* isolate = promise.GetIsolate();
7575   LOG_API(isolate, Promise, HasRejectHandler);
7576   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7577   if (!promise.IsJSPromise()) return false;
7578   return i::JSPromise::cast(promise).has_handler();
7579 }
7580 
Result()7581 Local<Value> Promise::Result() {
7582   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7583   i::Isolate* isolate = promise->GetIsolate();
7584   LOG_API(isolate, Promise, Result);
7585   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7586   Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7587                   "Promise is still pending");
7588   i::Handle<i::Object> result(js_promise->result(), isolate);
7589   return Utils::ToLocal(result);
7590 }
7591 
State()7592 Promise::PromiseState Promise::State() {
7593   i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7594   i::Isolate* isolate = promise->GetIsolate();
7595   LOG_API(isolate, Promise, Status);
7596   i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7597   return static_cast<PromiseState>(js_promise->status());
7598 }
7599 
MarkAsHandled()7600 void Promise::MarkAsHandled() {
7601   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7602   js_promise->set_has_handler(true);
7603 }
7604 
MarkAsSilent()7605 void Promise::MarkAsSilent() {
7606   i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7607   js_promise->set_is_silent(true);
7608 }
7609 
GetTarget()7610 Local<Value> Proxy::GetTarget() {
7611   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7612   i::Handle<i::Object> target(self->target(), self->GetIsolate());
7613   return Utils::ToLocal(target);
7614 }
7615 
GetHandler()7616 Local<Value> Proxy::GetHandler() {
7617   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7618   i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7619   return Utils::ToLocal(handler);
7620 }
7621 
IsRevoked() const7622 bool Proxy::IsRevoked() const {
7623   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7624   return self->IsRevoked();
7625 }
7626 
Revoke()7627 void Proxy::Revoke() {
7628   i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7629   i::JSProxy::Revoke(self);
7630 }
7631 
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7632 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7633                              Local<Object> local_handler) {
7634   PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7635   i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7636   i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7637   Local<Proxy> result;
7638   has_pending_exception =
7639       !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7640   RETURN_ON_FAILED_EXECUTION(Proxy);
7641   RETURN_ESCAPED(result);
7642 }
7643 
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7644 CompiledWasmModule::CompiledWasmModule(
7645     std::shared_ptr<internal::wasm::NativeModule> native_module,
7646     const char* source_url, size_t url_length)
7647     : native_module_(std::move(native_module)),
7648       source_url_(source_url, url_length) {
7649   CHECK_NOT_NULL(native_module_);
7650 }
7651 
Serialize()7652 OwnedBuffer CompiledWasmModule::Serialize() {
7653 #if V8_ENABLE_WEBASSEMBLY
7654   TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7655   i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7656   size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7657   std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7658   if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7659     return {};
7660   return {std::move(buffer), buffer_size};
7661 #else
7662   UNREACHABLE();
7663 #endif  // V8_ENABLE_WEBASSEMBLY
7664 }
7665 
GetWireBytesRef()7666 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7667 #if V8_ENABLE_WEBASSEMBLY
7668   base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7669   return {bytes_vec.begin(), bytes_vec.size()};
7670 #else
7671   UNREACHABLE();
7672 #endif  // V8_ENABLE_WEBASSEMBLY
7673 }
7674 
Buffer()7675 Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() {
7676 #if V8_ENABLE_WEBASSEMBLY
7677   i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this);
7678   i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate());
7679   return Utils::ToLocal(buffer);
7680 #else
7681   UNREACHABLE();
7682 #endif  // V8_ENABLE_WEBASSEMBLY
7683 }
7684 
GetCompiledModule()7685 CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7686 #if V8_ENABLE_WEBASSEMBLY
7687   auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7688   auto url =
7689       i::handle(i::String::cast(obj->script().name()), obj->GetIsolate());
7690   int length;
7691   std::unique_ptr<char[]> cstring =
7692       url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7693   return CompiledWasmModule(std::move(obj->shared_native_module()),
7694                             cstring.get(), length);
7695 #else
7696   UNREACHABLE();
7697 #endif  // V8_ENABLE_WEBASSEMBLY
7698 }
7699 
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7700 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7701     Isolate* isolate, const CompiledWasmModule& compiled_module) {
7702 #if V8_ENABLE_WEBASSEMBLY
7703   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7704   i::Handle<i::WasmModuleObject> module_object =
7705       i::wasm::GetWasmEngine()->ImportNativeModule(
7706           i_isolate, compiled_module.native_module_,
7707           base::VectorOf(compiled_module.source_url()));
7708   return Local<WasmModuleObject>::Cast(
7709       Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7710 #else
7711   UNREACHABLE();
7712 #endif  // V8_ENABLE_WEBASSEMBLY
7713 }
7714 
WasmModuleObjectBuilderStreaming(Isolate * isolate)7715 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7716     Isolate* isolate) {
7717   USE(isolate_);
7718 }
7719 
GetPromise()7720 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7721 
OnBytesReceived(const uint8_t * bytes,size_t size)7722 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7723                                                        size_t size) {}
7724 
Finish()7725 void WasmModuleObjectBuilderStreaming::Finish() {}
7726 
Abort(MaybeLocal<Value> exception)7727 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7728 
Reallocate(void * data,size_t old_length,size_t new_length)7729 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7730                                              size_t new_length) {
7731   if (old_length == new_length) return data;
7732   uint8_t* new_data =
7733       reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7734   if (new_data == nullptr) return nullptr;
7735   size_t bytes_to_copy = std::min(old_length, new_length);
7736   memcpy(new_data, data, bytes_to_copy);
7737   if (new_length > bytes_to_copy) {
7738     memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7739   }
7740   Free(data, old_length);
7741   return new_data;
7742 }
7743 
7744 // static
NewDefaultAllocator()7745 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7746   return new ArrayBufferAllocator();
7747 }
7748 
IsDetachable() const7749 bool v8::ArrayBuffer::IsDetachable() const {
7750   return Utils::OpenHandle(this)->is_detachable();
7751 }
7752 
7753 namespace {
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7754 std::shared_ptr<i::BackingStore> ToInternal(
7755     std::shared_ptr<i::BackingStoreBase> backing_store) {
7756   return std::static_pointer_cast<i::BackingStore>(backing_store);
7757 }
7758 }  // namespace
7759 
Detach()7760 void v8::ArrayBuffer::Detach() {
7761   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7762   i::Isolate* isolate = obj->GetIsolate();
7763   Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
7764                   "Only detachable ArrayBuffers can be detached");
7765   LOG_API(isolate, ArrayBuffer, Detach);
7766   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7767   obj->Detach();
7768 }
7769 
ByteLength() const7770 size_t v8::ArrayBuffer::ByteLength() const {
7771   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7772   return obj->byte_length();
7773 }
7774 
New(Isolate * isolate,size_t byte_length)7775 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7776   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7777   LOG_API(i_isolate, ArrayBuffer, New);
7778   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7779   i::MaybeHandle<i::JSArrayBuffer> result =
7780       i_isolate->factory()->NewJSArrayBufferAndBackingStore(
7781           byte_length, i::InitializedFlag::kZeroInitialized);
7782 
7783   i::Handle<i::JSArrayBuffer> array_buffer;
7784   if (!result.ToHandle(&array_buffer)) {
7785     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7786     // version that throws an exception or otherwise does not crash.
7787     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
7788   }
7789 
7790   return Utils::ToLocal(array_buffer);
7791 }
7792 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7793 Local<ArrayBuffer> v8::ArrayBuffer::New(
7794     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7795   CHECK_IMPLIES(backing_store->ByteLength() != 0,
7796                 backing_store->Data() != nullptr);
7797   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7798   LOG_API(i_isolate, ArrayBuffer, New);
7799   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7800   std::shared_ptr<i::BackingStore> i_backing_store(
7801       ToInternal(std::move(backing_store)));
7802   Utils::ApiCheck(
7803       !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
7804       "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
7805   i::Handle<i::JSArrayBuffer> obj =
7806       i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
7807   return Utils::ToLocal(obj);
7808 }
7809 
NewBackingStore(Isolate * isolate,size_t byte_length)7810 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7811     Isolate* isolate, size_t byte_length) {
7812   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7813   LOG_API(i_isolate, ArrayBuffer, NewBackingStore);
7814   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7815   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7816   std::unique_ptr<i::BackingStoreBase> backing_store =
7817       i::BackingStore::Allocate(i_isolate, byte_length,
7818                                 i::SharedFlag::kNotShared,
7819                                 i::InitializedFlag::kZeroInitialized);
7820   if (!backing_store) {
7821     i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
7822   }
7823   return std::unique_ptr<v8::BackingStore>(
7824       static_cast<v8::BackingStore*>(backing_store.release()));
7825 }
7826 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)7827 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7828     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
7829     void* deleter_data) {
7830   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7831   std::unique_ptr<i::BackingStoreBase> backing_store =
7832       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
7833                                       i::SharedFlag::kNotShared);
7834   return std::unique_ptr<v8::BackingStore>(
7835       static_cast<v8::BackingStore*>(backing_store.release()));
7836 }
7837 
Buffer()7838 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
7839   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7840   i::Handle<i::JSArrayBuffer> buffer;
7841   if (obj->IsJSDataView()) {
7842     i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
7843                                        obj->GetIsolate());
7844     DCHECK(data_view->buffer().IsJSArrayBuffer());
7845     buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
7846                        data_view->GetIsolate());
7847   } else {
7848     DCHECK(obj->IsJSTypedArray());
7849     buffer = i::JSTypedArray::cast(*obj).GetBuffer();
7850   }
7851   return Utils::ToLocal(buffer);
7852 }
7853 
CopyContents(void * dest,size_t byte_length)7854 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
7855   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7856   size_t byte_offset = self->byte_offset();
7857   size_t bytes_to_copy = std::min(byte_length, self->byte_length());
7858   if (bytes_to_copy) {
7859     i::DisallowGarbageCollection no_gc;
7860     i::Isolate* isolate = self->GetIsolate();
7861     i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()),
7862                                        isolate);
7863     const char* source = reinterpret_cast<char*>(buffer->backing_store());
7864     if (source == nullptr) {
7865       DCHECK(self->IsJSTypedArray());
7866       i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self),
7867                                              isolate);
7868       source = reinterpret_cast<char*>(typed_array->DataPtr());
7869     }
7870     memcpy(dest, source + byte_offset, bytes_to_copy);
7871   }
7872   return bytes_to_copy;
7873 }
7874 
HasBuffer() const7875 bool v8::ArrayBufferView::HasBuffer() const {
7876   i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7877   if (!self->IsJSTypedArray()) return true;
7878   auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
7879   return !typed_array->is_on_heap();
7880 }
7881 
ByteOffset()7882 size_t v8::ArrayBufferView::ByteOffset() {
7883   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7884   return obj->WasDetached() ? 0 : obj->byte_offset();
7885 }
7886 
ByteLength()7887 size_t v8::ArrayBufferView::ByteLength() {
7888   i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7889   return obj->WasDetached() ? 0 : obj->byte_length();
7890 }
7891 
Length()7892 size_t v8::TypedArray::Length() {
7893   i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
7894   return obj->WasDetached() ? 0 : obj->length();
7895 }
7896 
7897 static_assert(
7898     v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
7899     "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
7900 
7901 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype)                           \
7902   Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer,     \
7903                                       size_t byte_offset, size_t length) { \
7904     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();  \
7905     LOG_API(isolate, Type##Array, New);                                    \
7906     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
7907     if (!Utils::ApiCheck(length <= kMaxLength,                             \
7908                          "v8::" #Type                                      \
7909                          "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
7910                          "length exceeds max allowed value")) {            \
7911       return Local<Type##Array>();                                         \
7912     }                                                                      \
7913     i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
7914     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
7915         i::kExternal##Type##Array, buffer, byte_offset, length);           \
7916     return Utils::ToLocal##Type##Array(obj);                               \
7917   }                                                                        \
7918   Local<Type##Array> Type##Array::New(                                     \
7919       Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset,    \
7920       size_t length) {                                                     \
7921     CHECK(i::FLAG_harmony_sharedarraybuffer);                              \
7922     i::Isolate* isolate =                                                  \
7923         Utils::OpenHandle(*shared_array_buffer)->GetIsolate();             \
7924     LOG_API(isolate, Type##Array, New);                                    \
7925     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                              \
7926     if (!Utils::ApiCheck(                                                  \
7927             length <= kMaxLength,                                          \
7928             "v8::" #Type                                                   \
7929             "Array::New(Local<SharedArrayBuffer>, size_t, size_t)",        \
7930             "length exceeds max allowed value")) {                         \
7931       return Local<Type##Array>();                                         \
7932     }                                                                      \
7933     i::Handle<i::JSArrayBuffer> buffer =                                   \
7934         Utils::OpenHandle(*shared_array_buffer);                           \
7935     i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(  \
7936         i::kExternal##Type##Array, buffer, byte_offset, length);           \
7937     return Utils::ToLocal##Type##Array(obj);                               \
7938   }
7939 
TYPED_ARRAYS(TYPED_ARRAY_NEW)7940 TYPED_ARRAYS(TYPED_ARRAY_NEW)
7941 #undef TYPED_ARRAY_NEW
7942 
7943 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
7944                               size_t byte_offset, size_t byte_length) {
7945   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
7946   i::Isolate* isolate = buffer->GetIsolate();
7947   LOG_API(isolate, DataView, New);
7948   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7949   i::Handle<i::JSDataView> obj =
7950       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7951   return Utils::ToLocal(obj);
7952 }
7953 
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)7954 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
7955                               size_t byte_offset, size_t byte_length) {
7956   CHECK(i::FLAG_harmony_sharedarraybuffer);
7957   i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
7958   i::Isolate* isolate = buffer->GetIsolate();
7959   LOG_API(isolate, DataView, New);
7960   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7961   i::Handle<i::JSDataView> obj =
7962       isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7963   return Utils::ToLocal(obj);
7964 }
7965 
ByteLength() const7966 size_t v8::SharedArrayBuffer::ByteLength() const {
7967   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7968   return obj->byte_length();
7969 }
7970 
New(Isolate * isolate,size_t byte_length)7971 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
7972                                                     size_t byte_length) {
7973   CHECK(i::FLAG_harmony_sharedarraybuffer);
7974   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7975   LOG_API(i_isolate, SharedArrayBuffer, New);
7976   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7977 
7978   std::unique_ptr<i::BackingStore> backing_store =
7979       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
7980                                 i::InitializedFlag::kZeroInitialized);
7981 
7982   if (!backing_store) {
7983     // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7984     // version that throws an exception or otherwise does not crash.
7985     i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
7986   }
7987 
7988   i::Handle<i::JSArrayBuffer> obj =
7989       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
7990   return Utils::ToLocalShared(obj);
7991 }
7992 
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7993 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
7994     Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7995   CHECK(i::FLAG_harmony_sharedarraybuffer);
7996   CHECK_IMPLIES(backing_store->ByteLength() != 0,
7997                 backing_store->Data() != nullptr);
7998   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7999   LOG_API(i_isolate, SharedArrayBuffer, New);
8000   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8001   std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
8002   Utils::ApiCheck(
8003       i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
8004       "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
8005   i::Handle<i::JSArrayBuffer> obj =
8006       i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
8007   return Utils::ToLocalShared(obj);
8008 }
8009 
NewBackingStore(Isolate * isolate,size_t byte_length)8010 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8011     Isolate* isolate, size_t byte_length) {
8012   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8013   LOG_API(i_isolate, SharedArrayBuffer, NewBackingStore);
8014   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8015   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8016   std::unique_ptr<i::BackingStoreBase> backing_store =
8017       i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8018                                 i::InitializedFlag::kZeroInitialized);
8019   if (!backing_store) {
8020     i::FatalProcessOutOfMemory(i_isolate,
8021                                "v8::SharedArrayBuffer::NewBackingStore");
8022   }
8023   return std::unique_ptr<v8::BackingStore>(
8024       static_cast<v8::BackingStore*>(backing_store.release()));
8025 }
8026 
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8027 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8028     void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8029     void* deleter_data) {
8030   CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8031   std::unique_ptr<i::BackingStoreBase> backing_store =
8032       i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8033                                       i::SharedFlag::kShared);
8034   return std::unique_ptr<v8::BackingStore>(
8035       static_cast<v8::BackingStore*>(backing_store.release()));
8036 }
8037 
New(Isolate * isolate,Local<String> name)8038 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8039   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8040   LOG_API(i_isolate, Symbol, New);
8041   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8042   i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8043   if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8044   return Utils::ToLocal(result);
8045 }
8046 
For(Isolate * isolate,Local<String> name)8047 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8048   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8049   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8050   return Utils::ToLocal(
8051       i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8052 }
8053 
ForApi(Isolate * isolate,Local<String> name)8054 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8055   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8056   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8057   return Utils::ToLocal(
8058       i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8059 }
8060 
8061 #define WELL_KNOWN_SYMBOLS(V)                 \
8062   V(AsyncIterator, async_iterator)            \
8063   V(HasInstance, has_instance)                \
8064   V(IsConcatSpreadable, is_concat_spreadable) \
8065   V(Iterator, iterator)                       \
8066   V(Match, match)                             \
8067   V(Replace, replace)                         \
8068   V(Search, search)                           \
8069   V(Split, split)                             \
8070   V(ToPrimitive, to_primitive)                \
8071   V(ToStringTag, to_string_tag)               \
8072   V(Unscopables, unscopables)
8073 
8074 #define SYMBOL_GETTER(Name, name)                                   \
8075   Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) {           \
8076     i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8077     return Utils::ToLocal(i_isolate->factory()->name##_symbol());   \
8078   }
8079 
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8080 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8081 
8082 #undef SYMBOL_GETTER
8083 #undef WELL_KNOWN_SYMBOLS
8084 
8085 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8086   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8087   LOG_API(i_isolate, Private, New);
8088   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8089   i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8090   if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8091   Local<Symbol> result = Utils::ToLocal(symbol);
8092   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8093 }
8094 
ForApi(Isolate * isolate,Local<String> name)8095 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8096   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8097   i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8098   Local<Symbol> result = Utils::ToLocal(
8099       i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8100   return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8101 }
8102 
New(Isolate * isolate,double value)8103 Local<Number> v8::Number::New(Isolate* isolate, double value) {
8104   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8105   if (std::isnan(value)) {
8106     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8107     value = std::numeric_limits<double>::quiet_NaN();
8108   }
8109   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8110   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8111   return Utils::NumberToLocal(result);
8112 }
8113 
New(Isolate * isolate,int32_t value)8114 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8115   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8116   if (i::Smi::IsValid(value)) {
8117     return Utils::IntegerToLocal(
8118         i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8119   }
8120   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8121   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8122   return Utils::IntegerToLocal(result);
8123 }
8124 
NewFromUnsigned(Isolate * isolate,uint32_t value)8125 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8126   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8127   bool fits_into_int32_t = (value & (1 << 31)) == 0;
8128   if (fits_into_int32_t) {
8129     return Integer::New(isolate, static_cast<int32_t>(value));
8130   }
8131   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8132   i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8133   return Utils::IntegerToLocal(result);
8134 }
8135 
New(Isolate * isolate,int64_t value)8136 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8137   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8138   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8139   i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8140   return Utils::ToLocal(result);
8141 }
8142 
NewFromUnsigned(Isolate * isolate,uint64_t value)8143 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8144   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8145   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8146   i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8147   return Utils::ToLocal(result);
8148 }
8149 
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8150 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8151                                             int sign_bit, int word_count,
8152                                             const uint64_t* words) {
8153   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8154   ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8155                      MaybeLocal<BigInt>(), InternalEscapableScope);
8156   i::MaybeHandle<i::BigInt> result =
8157       i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8158   has_pending_exception = result.is_null();
8159   RETURN_ON_FAILED_EXECUTION(BigInt);
8160   RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8161 }
8162 
Uint64Value(bool * lossless) const8163 uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8164   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8165   return handle->AsUint64(lossless);
8166 }
8167 
Int64Value(bool * lossless) const8168 int64_t v8::BigInt::Int64Value(bool* lossless) const {
8169   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8170   return handle->AsInt64(lossless);
8171 }
8172 
WordCount() const8173 int BigInt::WordCount() const {
8174   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8175   return handle->Words64Count();
8176 }
8177 
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8178 void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8179                           uint64_t* words) const {
8180   i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8181   return handle->ToWordsArray64(sign_bit, word_count, words);
8182 }
8183 
ReportExternalAllocationLimitReached()8184 void Isolate::ReportExternalAllocationLimitReached() {
8185   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8186   if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8187   heap->ReportExternalMemoryPressure();
8188 }
8189 
GetHeapProfiler()8190 HeapProfiler* Isolate::GetHeapProfiler() {
8191   i::HeapProfiler* heap_profiler =
8192       reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8193   return reinterpret_cast<HeapProfiler*>(heap_profiler);
8194 }
8195 
SetIdle(bool is_idle)8196 void Isolate::SetIdle(bool is_idle) {
8197   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8198   isolate->SetIdle(is_idle);
8199 }
8200 
GetArrayBufferAllocator()8201 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8202   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8203   return isolate->array_buffer_allocator();
8204 }
8205 
InContext()8206 bool Isolate::InContext() {
8207   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8208   return !isolate->context().is_null();
8209 }
8210 
ClearKeptObjects()8211 void Isolate::ClearKeptObjects() {
8212   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8213   isolate->ClearKeptObjects();
8214 }
8215 
GetCurrentContext()8216 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8217   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8218   i::Context context = isolate->context();
8219   if (context.is_null()) return Local<Context>();
8220   i::Context native_context = context.native_context();
8221   if (native_context.is_null()) return Local<Context>();
8222   return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8223 }
8224 
GetEnteredOrMicrotaskContext()8225 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8226   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8227   i::Handle<i::Object> last =
8228       isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8229   if (last.is_null()) return Local<Context>();
8230   DCHECK(last->IsNativeContext());
8231   return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8232 }
8233 
GetIncumbentContext()8234 v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8235   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8236   i::Handle<i::Context> context = isolate->GetIncumbentContext();
8237   return Utils::ToLocal(context);
8238 }
8239 
ThrowError(v8::Local<v8::String> message)8240 v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8241   return ThrowException(v8::Exception::Error(message));
8242 }
8243 
ThrowException(v8::Local<v8::Value> value)8244 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8245   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8246   ENTER_V8_DO_NOT_USE(isolate);
8247   // If we're passed an empty handle, we throw an undefined exception
8248   // to deal more gracefully with out of memory situations.
8249   if (value.IsEmpty()) {
8250     isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8251   } else {
8252     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8253   }
8254   return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8255 }
8256 
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8257 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8258                                     GCType gc_type) {
8259   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8260   isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8261 }
8262 
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8263 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8264                                        void* data) {
8265   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8266   isolate->heap()->RemoveGCPrologueCallback(callback, data);
8267 }
8268 
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8269 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8270                                     GCType gc_type) {
8271   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8272   isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8273 }
8274 
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8275 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8276                                        void* data) {
8277   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8278   isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8279 }
8280 
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8281 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8282                                       GCCallbackFlags flags, void* data) {
8283   reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8284 }
8285 
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8286 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8287   void* data = reinterpret_cast<void*>(callback);
8288   AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8289 }
8290 
RemoveGCPrologueCallback(GCCallback callback)8291 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8292   void* data = reinterpret_cast<void*>(callback);
8293   RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8294 }
8295 
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8296 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8297   void* data = reinterpret_cast<void*>(callback);
8298   AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8299 }
8300 
RemoveGCEpilogueCallback(GCCallback callback)8301 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8302   void* data = reinterpret_cast<void*>(callback);
8303   RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8304 }
8305 
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8306 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8307   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8308   isolate->heap()->SetEmbedderHeapTracer(tracer);
8309 }
8310 
GetEmbedderHeapTracer()8311 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8312   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8313   return isolate->heap()->GetEmbedderHeapTracer();
8314 }
8315 
SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8316 void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8317   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8318   isolate->heap()->SetEmbedderRootsHandler(handler);
8319 }
8320 
AttachCppHeap(CppHeap * cpp_heap)8321 void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
8322   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8323   isolate->heap()->AttachCppHeap(cpp_heap);
8324 }
8325 
DetachCppHeap()8326 void Isolate::DetachCppHeap() {
8327   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8328   isolate->heap()->DetachCppHeap();
8329 }
8330 
GetCppHeap() const8331 CppHeap* Isolate::GetCppHeap() const {
8332   const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8333   return isolate->heap()->cpp_heap();
8334 }
8335 
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8336 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8337     GetExternallyAllocatedMemoryInBytesCallback callback) {
8338   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8339   isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8340 }
8341 
TerminateExecution()8342 void Isolate::TerminateExecution() {
8343   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8344   isolate->stack_guard()->RequestTerminateExecution();
8345 }
8346 
IsExecutionTerminating()8347 bool Isolate::IsExecutionTerminating() {
8348   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8349   return IsExecutionTerminatingCheck(isolate);
8350 }
8351 
CancelTerminateExecution()8352 void Isolate::CancelTerminateExecution() {
8353   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8354   isolate->stack_guard()->ClearTerminateExecution();
8355   isolate->CancelTerminateExecution();
8356 }
8357 
RequestInterrupt(InterruptCallback callback,void * data)8358 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8359   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8360   isolate->RequestInterrupt(callback, data);
8361 }
8362 
HasPendingBackgroundTasks()8363 bool Isolate::HasPendingBackgroundTasks() {
8364 #if V8_ENABLE_WEBASSEMBLY
8365   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8366   return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate);
8367 #else
8368   return false;
8369 #endif  // V8_ENABLE_WEBASSEMBLY
8370 }
8371 
RequestGarbageCollectionForTesting(GarbageCollectionType type)8372 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8373   Utils::ApiCheck(i::FLAG_expose_gc,
8374                   "v8::Isolate::RequestGarbageCollectionForTesting",
8375                   "Must use --expose-gc");
8376   if (type == kMinorGarbageCollection) {
8377     reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8378         i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8379         kGCCallbackFlagForced);
8380   } else {
8381     DCHECK_EQ(kFullGarbageCollection, type);
8382     reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8383         i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8384         kGCCallbackFlagForced);
8385   }
8386 }
8387 
GetCurrent()8388 Isolate* Isolate::GetCurrent() {
8389   i::Isolate* isolate = i::Isolate::Current();
8390   return reinterpret_cast<Isolate*>(isolate);
8391 }
8392 
TryGetCurrent()8393 Isolate* Isolate::TryGetCurrent() {
8394   i::Isolate* isolate = i::Isolate::TryGetCurrent();
8395   return reinterpret_cast<Isolate*>(isolate);
8396 }
8397 
8398 // static
Allocate()8399 Isolate* Isolate::Allocate() {
8400   return reinterpret_cast<Isolate*>(i::Isolate::New());
8401 }
8402 
8403 Isolate::CreateParams::CreateParams() = default;
8404 
8405 Isolate::CreateParams::~CreateParams() = default;
8406 
8407 // static
8408 // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8409 void Isolate::Initialize(Isolate* isolate,
8410                          const v8::Isolate::CreateParams& params) {
8411   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8412   if (auto allocator = params.array_buffer_allocator_shared) {
8413     CHECK(params.array_buffer_allocator == nullptr ||
8414           params.array_buffer_allocator == allocator.get());
8415     i_isolate->set_array_buffer_allocator(allocator.get());
8416     i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8417   } else {
8418     CHECK_NOT_NULL(params.array_buffer_allocator);
8419     i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8420   }
8421   if (params.snapshot_blob != nullptr) {
8422     i_isolate->set_snapshot_blob(params.snapshot_blob);
8423   } else {
8424     i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8425   }
8426   if (params.counter_lookup_callback) {
8427     isolate->SetCounterFunction(params.counter_lookup_callback);
8428   }
8429 
8430   if (params.create_histogram_callback) {
8431     isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8432   }
8433 
8434   if (params.add_histogram_sample_callback) {
8435     isolate->SetAddHistogramSampleFunction(
8436         params.add_histogram_sample_callback);
8437   }
8438 
8439   i_isolate->set_api_external_references(params.external_references);
8440   i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8441 
8442   i_isolate->heap()->ConfigureHeap(params.constraints);
8443   if (params.constraints.stack_limit() != nullptr) {
8444     uintptr_t limit =
8445         reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8446     i_isolate->stack_guard()->SetStackLimit(limit);
8447   }
8448   // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
8449   Isolate::Scope isolate_scope(isolate);
8450   if (i_isolate->snapshot_blob() == nullptr) {
8451     FATAL(
8452         "V8 snapshot blob was not set during initialization. This can mean "
8453         "that the snapshot blob file is corrupted or missing.");
8454   }
8455   if (!i::Snapshot::Initialize(i_isolate)) {
8456     // If snapshot data was provided and we failed to deserialize it must
8457     // have been corrupted.
8458     FATAL(
8459         "Failed to deserialize the V8 snapshot blob. This can mean that the "
8460         "snapshot blob file is corrupted or missing.");
8461   }
8462 
8463   {
8464     // Set up code event handlers. Needs to be after i::Snapshot::Initialize
8465     // because that is where we add the isolate to WasmEngine.
8466     auto code_event_handler = params.code_event_handler;
8467 #ifdef ENABLE_GDB_JIT_INTERFACE
8468     if (code_event_handler == nullptr && i::FLAG_gdbjit) {
8469       code_event_handler = i::GDBJITInterface::EventHandler;
8470     }
8471 #endif  // ENABLE_GDB_JIT_INTERFACE
8472 #if defined(V8_OS_WIN) && defined(V8_ENABLE_SYSTEM_INSTRUMENTATION)
8473     if (code_event_handler == nullptr &&
8474         i::FLAG_enable_system_instrumentation) {
8475       code_event_handler = i::ETWJITInterface::EventHandler;
8476     }
8477 #endif  // defined(V8_OS_WIN)
8478 
8479     if (code_event_handler) {
8480       isolate->SetJitCodeEventHandler(kJitCodeEventDefault, code_event_handler);
8481     }
8482   }
8483 
8484   i_isolate->set_only_terminate_in_safe_scope(
8485       params.only_terminate_in_safe_scope);
8486   i_isolate->set_embedder_wrapper_type_index(
8487       params.embedder_wrapper_type_index);
8488   i_isolate->set_embedder_wrapper_object_index(
8489       params.embedder_wrapper_object_index);
8490 
8491   if (!i::V8::GetCurrentPlatform()
8492            ->GetForegroundTaskRunner(isolate)
8493            ->NonNestableTasksEnabled()) {
8494     FATAL(
8495         "The current platform's foreground task runner does not have "
8496         "non-nestable tasks enabled. The embedder must provide one.");
8497   }
8498 }
8499 
New(const Isolate::CreateParams & params)8500 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8501   Isolate* isolate = Allocate();
8502   Initialize(isolate, params);
8503   return isolate;
8504 }
8505 
Dispose()8506 void Isolate::Dispose() {
8507   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8508   if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8509                        "Disposing the isolate that is entered by a thread.")) {
8510     return;
8511   }
8512   i::Isolate::Delete(isolate);
8513 }
8514 
DumpAndResetStats()8515 void Isolate::DumpAndResetStats() {
8516   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8517   isolate->DumpAndResetStats();
8518 }
8519 
DiscardThreadSpecificMetadata()8520 void Isolate::DiscardThreadSpecificMetadata() {
8521   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8522   isolate->DiscardPerThreadDataForThisThread();
8523 }
8524 
Enter()8525 void Isolate::Enter() {
8526   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8527   isolate->Enter();
8528 }
8529 
Exit()8530 void Isolate::Exit() {
8531   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8532   isolate->Exit();
8533 }
8534 
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8535 void Isolate::SetAbortOnUncaughtExceptionCallback(
8536     AbortOnUncaughtExceptionCallback callback) {
8537   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8538   isolate->SetAbortOnUncaughtExceptionCallback(callback);
8539 }
8540 
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8541 void Isolate::SetHostImportModuleDynamicallyCallback(
8542     HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8543   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8544   isolate->SetHostImportModuleDynamicallyCallback(callback);
8545 }
8546 
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8547 void Isolate::SetHostInitializeImportMetaObjectCallback(
8548     HostInitializeImportMetaObjectCallback callback) {
8549   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8550   isolate->SetHostInitializeImportMetaObjectCallback(callback);
8551 }
8552 
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8553 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8554   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8555   isolate->SetPrepareStackTraceCallback(callback);
8556 }
8557 
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8558 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8559     Isolate* isolate,
8560     Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8561     : on_failure_(on_failure), isolate_(isolate) {
8562   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8563   switch (on_failure_) {
8564     case CRASH_ON_FAILURE:
8565       i::DisallowJavascriptExecution::Open(i_isolate,
8566                                            &was_execution_allowed_assert_);
8567       break;
8568     case THROW_ON_FAILURE:
8569       i::ThrowOnJavascriptExecution::Open(i_isolate,
8570                                           &was_execution_allowed_throws_);
8571       break;
8572     case DUMP_ON_FAILURE:
8573       i::DumpOnJavascriptExecution::Open(i_isolate,
8574                                          &was_execution_allowed_dump_);
8575       break;
8576     default:
8577       UNREACHABLE();
8578   }
8579 }
8580 
~DisallowJavascriptExecutionScope()8581 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8582   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8583   switch (on_failure_) {
8584     case CRASH_ON_FAILURE:
8585       i::DisallowJavascriptExecution::Close(i_isolate,
8586                                             was_execution_allowed_assert_);
8587       break;
8588     case THROW_ON_FAILURE:
8589       i::ThrowOnJavascriptExecution::Close(i_isolate,
8590                                            was_execution_allowed_throws_);
8591       break;
8592     case DUMP_ON_FAILURE:
8593       i::DumpOnJavascriptExecution::Close(i_isolate,
8594                                           was_execution_allowed_dump_);
8595       break;
8596     default:
8597       UNREACHABLE();
8598   }
8599 }
8600 
AllowJavascriptExecutionScope(Isolate * isolate)8601 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8602     Isolate* isolate)
8603     : isolate_(isolate) {
8604   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8605   i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_);
8606   i::NoThrowOnJavascriptExecution::Open(i_isolate,
8607                                         &was_execution_allowed_throws_);
8608   i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_);
8609 }
8610 
~AllowJavascriptExecutionScope()8611 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8612   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8613   i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_);
8614   i::NoThrowOnJavascriptExecution::Close(i_isolate,
8615                                          was_execution_allowed_throws_);
8616   i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_);
8617 }
8618 
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8619 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8620     Isolate* isolate, MicrotaskQueue* microtask_queue)
8621     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8622       microtask_queue_(microtask_queue
8623                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8624                            : isolate_->default_microtask_queue()) {
8625   isolate_->thread_local_top()->IncrementCallDepth(this);
8626   microtask_queue_->IncrementMicrotasksSuppressions();
8627 }
8628 
~SuppressMicrotaskExecutionScope()8629 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8630   microtask_queue_->DecrementMicrotasksSuppressions();
8631   isolate_->thread_local_top()->DecrementCallDepth(this);
8632 }
8633 
SafeForTerminationScope(v8::Isolate * isolate)8634 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8635     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8636       prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8637   isolate_->set_next_v8_call_is_safe_for_termination(true);
8638 }
8639 
~SafeForTerminationScope()8640 Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8641   isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8642 }
8643 
GetDataFromSnapshotOnce(size_t index)8644 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8645   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8646   i::FixedArray list = i_isolate->heap()->serialized_objects();
8647   return GetSerializedDataFromFixedArray(i_isolate, list, index);
8648 }
8649 
GetHeapStatistics(HeapStatistics * heap_statistics)8650 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8651   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8652   i::Heap* heap = isolate->heap();
8653 
8654   // The order of acquiring memory statistics is important here. We query in
8655   // this order because of concurrent allocation: 1) used memory 2) comitted
8656   // physical memory 3) committed memory. Therefore the condition used <=
8657   // committed physical <= committed should hold.
8658   heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8659   heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8660   DCHECK_LE(heap_statistics->used_global_handles_size_,
8661             heap_statistics->total_global_handles_size_);
8662 
8663   heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8664   heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8665   heap_statistics->total_heap_size_ = heap->CommittedMemory();
8666 
8667   heap_statistics->total_available_size_ = heap->Available();
8668 
8669   if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8670     i::ReadOnlySpace* ro_space = heap->read_only_space();
8671     heap_statistics->used_heap_size_ += ro_space->Size();
8672     heap_statistics->total_physical_size_ +=
8673         ro_space->CommittedPhysicalMemory();
8674     heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8675   }
8676 
8677   // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8678   // this and add DCHECK.
8679   DCHECK_LE(heap_statistics->used_heap_size_,
8680             heap_statistics->total_heap_size_);
8681 
8682   heap_statistics->total_heap_size_executable_ =
8683       heap->CommittedMemoryExecutable();
8684   heap_statistics->heap_size_limit_ = heap->MaxReserved();
8685   // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8686   // API becomes available we should report the malloced memory separately. For
8687   // now we just add the values, thereby over-approximating the peak slightly.
8688   heap_statistics->malloced_memory_ =
8689       isolate->allocator()->GetCurrentMemoryUsage() +
8690       isolate->string_table()->GetCurrentMemoryUsage();
8691   // On 32-bit systems backing_store_bytes() might overflow size_t temporarily
8692   // due to concurrent array buffer sweeping.
8693   heap_statistics->external_memory_ =
8694       isolate->heap()->backing_store_bytes() < SIZE_MAX
8695           ? static_cast<size_t>(isolate->heap()->backing_store_bytes())
8696           : SIZE_MAX;
8697   heap_statistics->peak_malloced_memory_ =
8698       isolate->allocator()->GetMaxMemoryUsage();
8699   heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8700   heap_statistics->number_of_detached_contexts_ =
8701       heap->NumberOfDetachedContexts();
8702   heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8703 
8704 #if V8_ENABLE_WEBASSEMBLY
8705   heap_statistics->malloced_memory_ +=
8706       i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage();
8707   heap_statistics->peak_malloced_memory_ +=
8708       i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage();
8709 #endif  // V8_ENABLE_WEBASSEMBLY
8710 }
8711 
NumberOfHeapSpaces()8712 size_t Isolate::NumberOfHeapSpaces() {
8713   return i::LAST_SPACE - i::FIRST_SPACE + 1;
8714 }
8715 
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8716 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8717                                      size_t index) {
8718   if (!space_statistics) return false;
8719   if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8720     return false;
8721 
8722   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8723   i::Heap* heap = isolate->heap();
8724 
8725   i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
8726   space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
8727 
8728   if (allocation_space == i::RO_SPACE) {
8729     if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8730       // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
8731       space_statistics->space_size_ = 0;
8732       space_statistics->space_used_size_ = 0;
8733       space_statistics->space_available_size_ = 0;
8734       space_statistics->physical_space_size_ = 0;
8735     } else {
8736       i::ReadOnlySpace* space = heap->read_only_space();
8737       space_statistics->space_size_ = space->CommittedMemory();
8738       space_statistics->space_used_size_ = space->Size();
8739       space_statistics->space_available_size_ = 0;
8740       space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8741     }
8742   } else {
8743     i::Space* space = heap->space(static_cast<int>(index));
8744     space_statistics->space_size_ = space ? space->CommittedMemory() : 0;
8745     space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0;
8746     space_statistics->space_available_size_ = space ? space->Available() : 0;
8747     space_statistics->physical_space_size_ =
8748         space ? space->CommittedPhysicalMemory() : 0;
8749   }
8750   return true;
8751 }
8752 
NumberOfTrackedHeapObjectTypes()8753 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8754   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8755   i::Heap* heap = isolate->heap();
8756   return heap->NumberOfTrackedHeapObjectTypes();
8757 }
8758 
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8759 bool Isolate::GetHeapObjectStatisticsAtLastGC(
8760     HeapObjectStatistics* object_statistics, size_t type_index) {
8761   if (!object_statistics) return false;
8762   if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
8763 
8764   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8765   i::Heap* heap = isolate->heap();
8766   if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8767 
8768   const char* object_type;
8769   const char* object_sub_type;
8770   size_t object_count = heap->ObjectCountAtLastGC(type_index);
8771   size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8772   if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8773     // There should be no objects counted when the type is unknown.
8774     DCHECK_EQ(object_count, 0U);
8775     DCHECK_EQ(object_size, 0U);
8776     return false;
8777   }
8778 
8779   object_statistics->object_type_ = object_type;
8780   object_statistics->object_sub_type_ = object_sub_type;
8781   object_statistics->object_count_ = object_count;
8782   object_statistics->object_size_ = object_size;
8783   return true;
8784 }
8785 
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)8786 bool Isolate::GetHeapCodeAndMetadataStatistics(
8787     HeapCodeStatistics* code_statistics) {
8788   if (!code_statistics) return false;
8789 
8790   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8791   isolate->heap()->CollectCodeStatistics();
8792 
8793   code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8794   code_statistics->bytecode_and_metadata_size_ =
8795       isolate->bytecode_and_metadata_size();
8796   code_statistics->external_script_source_size_ =
8797       isolate->external_script_source_size();
8798   return true;
8799 }
8800 
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)8801 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
8802                             MeasureMemoryExecution execution) {
8803   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8804   return isolate->heap()->MeasureMemory(std::move(delegate), execution);
8805 }
8806 
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)8807 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
8808     Isolate* isolate, Local<Context> context,
8809     Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
8810   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8811   i::Handle<i::NativeContext> native_context =
8812       handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
8813   i::Handle<i::JSPromise> js_promise =
8814       i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
8815   return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
8816                                                   mode);
8817 }
8818 
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)8819 void Isolate::GetStackSample(const RegisterState& state, void** frames,
8820                              size_t frames_limit, SampleInfo* sample_info) {
8821   RegisterState regs = state;
8822   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8823   if (i::TickSample::GetStackSample(isolate, &regs,
8824                                     i::TickSample::kSkipCEntryFrame, frames,
8825                                     frames_limit, sample_info)) {
8826     return;
8827   }
8828   sample_info->frames_count = 0;
8829   sample_info->vm_state = OTHER;
8830   sample_info->external_callback_entry = nullptr;
8831 }
8832 
NumberOfPhantomHandleResetsSinceLastCall()8833 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
8834   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8835   return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
8836 }
8837 
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)8838 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
8839     int64_t change_in_bytes) {
8840   // Try to check for unreasonably large or small values from the embedder.
8841   const int64_t kMaxReasonableBytes = int64_t(1) << 60;
8842   const int64_t kMinReasonableBytes = -kMaxReasonableBytes;
8843   STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength);
8844 
8845   CHECK(kMinReasonableBytes <= change_in_bytes &&
8846         change_in_bytes < kMaxReasonableBytes);
8847 
8848   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8849   int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
8850 
8851   if (change_in_bytes <= 0) return amount;
8852 
8853   if (amount > i_isolate->heap()->external_memory_limit()) {
8854     ReportExternalAllocationLimitReached();
8855   }
8856   return amount;
8857 }
8858 
SetEventLogger(LogEventCallback that)8859 void Isolate::SetEventLogger(LogEventCallback that) {
8860   // Do not overwrite the event logger if we want to log explicitly.
8861   if (i::FLAG_log_internal_timer_events) return;
8862   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8863   isolate->set_event_logger(that);
8864 }
8865 
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8866 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
8867   if (callback == nullptr) return;
8868   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8869   isolate->AddBeforeCallEnteredCallback(callback);
8870 }
8871 
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8872 void Isolate::RemoveBeforeCallEnteredCallback(
8873     BeforeCallEnteredCallback callback) {
8874   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8875   isolate->RemoveBeforeCallEnteredCallback(callback);
8876 }
8877 
AddCallCompletedCallback(CallCompletedCallback callback)8878 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
8879   if (callback == nullptr) return;
8880   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8881   isolate->AddCallCompletedCallback(callback);
8882 }
8883 
RemoveCallCompletedCallback(CallCompletedCallback callback)8884 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
8885   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8886   isolate->RemoveCallCompletedCallback(callback);
8887 }
8888 
Wake()8889 void Isolate::AtomicsWaitWakeHandle::Wake() {
8890   reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
8891 }
8892 
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)8893 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
8894   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8895   isolate->SetAtomicsWaitCallback(callback, data);
8896 }
8897 
SetPromiseHook(PromiseHook hook)8898 void Isolate::SetPromiseHook(PromiseHook hook) {
8899   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8900   isolate->SetPromiseHook(hook);
8901 }
8902 
SetPromiseRejectCallback(PromiseRejectCallback callback)8903 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
8904   if (callback == nullptr) return;
8905   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8906   isolate->SetPromiseRejectCallback(callback);
8907 }
8908 
PerformMicrotaskCheckpoint()8909 void Isolate::PerformMicrotaskCheckpoint() {
8910   DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
8911   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8912   isolate->default_microtask_queue()->PerformCheckpoint(this);
8913 }
8914 
EnqueueMicrotask(Local<Function> v8_function)8915 void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
8916   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8917   i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
8918   i::Handle<i::NativeContext> handler_context;
8919   if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
8920           &handler_context))
8921     handler_context = isolate->native_context();
8922   MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
8923   if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
8924 }
8925 
EnqueueMicrotask(MicrotaskCallback callback,void * data)8926 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
8927   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8928   isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
8929 }
8930 
SetMicrotasksPolicy(MicrotasksPolicy policy)8931 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
8932   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8933   isolate->default_microtask_queue()->set_microtasks_policy(policy);
8934 }
8935 
GetMicrotasksPolicy() const8936 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
8937   i::Isolate* isolate =
8938       reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
8939   return isolate->default_microtask_queue()->microtasks_policy();
8940 }
8941 
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)8942 void Isolate::AddMicrotasksCompletedCallback(
8943     MicrotasksCompletedCallbackWithData callback, void* data) {
8944   DCHECK(callback);
8945   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8946   isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
8947                                                                      data);
8948 }
8949 
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)8950 void Isolate::RemoveMicrotasksCompletedCallback(
8951     MicrotasksCompletedCallbackWithData callback, void* data) {
8952   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8953   isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
8954       callback, data);
8955 }
8956 
SetUseCounterCallback(UseCounterCallback callback)8957 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
8958   reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
8959 }
8960 
SetCounterFunction(CounterLookupCallback callback)8961 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
8962   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8963   isolate->counters()->ResetCounterFunction(callback);
8964 }
8965 
SetCreateHistogramFunction(CreateHistogramCallback callback)8966 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
8967   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8968   isolate->counters()->ResetCreateHistogramFunction(callback);
8969 }
8970 
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)8971 void Isolate::SetAddHistogramSampleFunction(
8972     AddHistogramSampleCallback callback) {
8973   reinterpret_cast<i::Isolate*>(this)
8974       ->counters()
8975       ->SetAddHistogramSampleFunction(callback);
8976 }
8977 
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)8978 void Isolate::SetMetricsRecorder(
8979     const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
8980   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8981   isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder);
8982 }
8983 
SetAddCrashKeyCallback(AddCrashKeyCallback callback)8984 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
8985   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8986   isolate->SetAddCrashKeyCallback(callback);
8987 }
8988 
IdleNotificationDeadline(double deadline_in_seconds)8989 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
8990   // Returning true tells the caller that it need not
8991   // continue to call IdleNotification.
8992   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8993   if (!i::FLAG_use_idle_notification) return true;
8994   return isolate->heap()->IdleNotification(deadline_in_seconds);
8995 }
8996 
LowMemoryNotification()8997 void Isolate::LowMemoryNotification() {
8998   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8999   {
9000     i::NestedTimedHistogramScope idle_notification_scope(
9001         isolate->counters()->gc_low_memory_notification());
9002     TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9003     isolate->heap()->CollectAllAvailableGarbage(
9004         i::GarbageCollectionReason::kLowMemoryNotification);
9005   }
9006 }
9007 
ContextDisposedNotification(bool dependant_context)9008 int Isolate::ContextDisposedNotification(bool dependant_context) {
9009   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9010 #if V8_ENABLE_WEBASSEMBLY
9011   if (!dependant_context) {
9012     if (!isolate->context().is_null()) {
9013       // We left the current context, we can abort all WebAssembly compilations
9014       // of that context.
9015       // A handle scope for the native context.
9016       i::HandleScope handle_scope(isolate);
9017       i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext(
9018           isolate->native_context());
9019     }
9020   }
9021 #endif  // V8_ENABLE_WEBASSEMBLY
9022   // TODO(ahaas): move other non-heap activity out of the heap call.
9023   return isolate->heap()->NotifyContextDisposed(dependant_context);
9024 }
9025 
IsolateInForegroundNotification()9026 void Isolate::IsolateInForegroundNotification() {
9027   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9028   return isolate->IsolateInForegroundNotification();
9029 }
9030 
IsolateInBackgroundNotification()9031 void Isolate::IsolateInBackgroundNotification() {
9032   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9033   return isolate->IsolateInBackgroundNotification();
9034 }
9035 
MemoryPressureNotification(MemoryPressureLevel level)9036 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9037   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9038   bool on_isolate_thread =
9039       v8::Locker::WasEverUsed()
9040           ? isolate->thread_manager()->IsLockedByCurrentThread()
9041           : i::ThreadId::Current() == isolate->thread_id();
9042   isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9043 }
9044 
ClearCachesForTesting()9045 void Isolate::ClearCachesForTesting() {
9046   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9047   isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9048   isolate->ClearSerializerData();
9049 }
9050 
EnableMemorySavingsMode()9051 void Isolate::EnableMemorySavingsMode() {
9052   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9053   isolate->EnableMemorySavingsMode();
9054 }
9055 
DisableMemorySavingsMode()9056 void Isolate::DisableMemorySavingsMode() {
9057   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9058   isolate->DisableMemorySavingsMode();
9059 }
9060 
SetRAILMode(RAILMode rail_mode)9061 void Isolate::SetRAILMode(RAILMode rail_mode) {
9062   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9063   return isolate->SetRAILMode(rail_mode);
9064 }
9065 
UpdateLoadStartTime()9066 void Isolate::UpdateLoadStartTime() {
9067   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9068   isolate->UpdateLoadStartTime();
9069 }
9070 
IncreaseHeapLimitForDebugging()9071 void Isolate::IncreaseHeapLimitForDebugging() {
9072   // No-op.
9073 }
9074 
RestoreOriginalHeapLimit()9075 void Isolate::RestoreOriginalHeapLimit() {
9076   // No-op.
9077 }
9078 
IsHeapLimitIncreasedForDebugging()9079 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9080 
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9081 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9082                                      JitCodeEventHandler event_handler) {
9083   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9084   // Ensure that logging is initialized for our isolate.
9085   isolate->InitializeLoggingAndCounters();
9086   isolate->logger()->SetCodeEventHandler(options, event_handler);
9087 }
9088 
SetStackLimit(uintptr_t stack_limit)9089 void Isolate::SetStackLimit(uintptr_t stack_limit) {
9090   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9091   CHECK(stack_limit);
9092   isolate->stack_guard()->SetStackLimit(stack_limit);
9093 }
9094 
GetCodeRange(void ** start,size_t * length_in_bytes)9095 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9096   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9097   const base::AddressRegion& code_region = isolate->heap()->code_region();
9098   *start = reinterpret_cast<void*>(code_region.begin());
9099   *length_in_bytes = code_region.size();
9100 }
9101 
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9102 void Isolate::GetEmbeddedCodeRange(const void** start,
9103                                    size_t* length_in_bytes) {
9104   // Note, we should return the embedded code rande from the .text section here.
9105   i::EmbeddedData d = i::EmbeddedData::FromBlob();
9106   *start = reinterpret_cast<const void*>(d.code());
9107   *length_in_bytes = d.code_size();
9108 }
9109 
GetJSEntryStubs()9110 JSEntryStubs Isolate::GetJSEntryStubs() {
9111   JSEntryStubs entry_stubs;
9112 
9113   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9114   std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = {
9115       {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub},
9116        {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9117        {i::Builtin::kJSRunMicrotasksEntry,
9118         &entry_stubs.js_run_microtasks_entry_stub}}};
9119   for (auto& pair : stubs) {
9120     i::Code js_entry = isolate->heap()->builtin(pair.first);
9121     pair.second->code.start =
9122         reinterpret_cast<const void*>(js_entry.InstructionStart());
9123     pair.second->code.length_in_bytes = js_entry.InstructionSize();
9124   }
9125 
9126   return entry_stubs;
9127 }
9128 
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9129 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9130 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9131   // Not implemented on other platforms.
9132   UNREACHABLE();
9133 #else
9134 
9135   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9136   std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9137 
9138   DCHECK_NOT_NULL(code_pages);
9139 
9140   // Copy as many elements into the output vector as we can. If the
9141   // caller-provided buffer is not big enough, we fill it, and the caller can
9142   // provide a bigger one next time. We do it this way because allocation is not
9143   // allowed in signal handlers.
9144   size_t limit = std::min(capacity, code_pages->size());
9145   for (size_t i = 0; i < limit; i++) {
9146     code_pages_out[i] = code_pages->at(i);
9147   }
9148   return code_pages->size();
9149 #endif
9150 }
9151 
9152 #define CALLBACK_SETTER(ExternalName, Type, InternalName)      \
9153   void Isolate::Set##ExternalName(Type callback) {             \
9154     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9155     isolate->set_##InternalName(callback);                     \
9156   }
9157 
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9158 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9159 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9160 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9161                 ModifyCodeGenerationFromStringsCallback2,
9162                 modify_code_gen_callback2)
9163 CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9164                 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9165 
9166 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9167 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9168 
9169 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9170                 wasm_streaming_callback)
9171 
9172 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9173                 wasm_load_source_map_callback)
9174 
9175 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9176                 wasm_simd_enabled_callback)
9177 
9178 CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9179                 wasm_exceptions_enabled_callback)
9180 
9181 CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9182                 WasmDynamicTieringEnabledCallback,
9183                 wasm_dynamic_tiering_enabled_callback)
9184 
9185 CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9186                 SharedArrayBufferConstructorEnabledCallback,
9187                 sharedarraybuffer_constructor_enabled_callback)
9188 
9189 void Isolate::InstallConditionalFeatures(Local<Context> context) {
9190   v8::HandleScope handle_scope(this);
9191   v8::Context::Scope context_scope(context);
9192   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9193   isolate->InstallConditionalFeatures(Utils::OpenHandle(*context));
9194 #if V8_ENABLE_WEBASSEMBLY
9195   if (i::FLAG_expose_wasm) {
9196     i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context));
9197   }
9198 #endif  // V8_ENABLE_WEBASSEMBLY
9199 }
9200 
AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9201 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9202                                        void* data) {
9203   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9204   isolate->heap()->AddNearHeapLimitCallback(callback, data);
9205 }
9206 
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9207 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9208                                           size_t heap_limit) {
9209   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9210   isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9211 }
9212 
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9213 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9214   DCHECK_GT(threshold_percent, 0.0);
9215   DCHECK_LT(threshold_percent, 1.0);
9216   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9217   isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9218 }
9219 
IsDead()9220 bool Isolate::IsDead() {
9221   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9222   return isolate->IsDead();
9223 }
9224 
AddMessageListener(MessageCallback that,Local<Value> data)9225 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9226   return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9227 }
9228 
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9229 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9230                                                int message_levels,
9231                                                Local<Value> data) {
9232   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9233   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9234   i::HandleScope scope(isolate);
9235   i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9236   i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9237   i::Handle<i::Foreign> foreign =
9238       isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9239   listener->set(0, *foreign);
9240   listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9241                                   : *Utils::OpenHandle(*data));
9242   listener->set(2, i::Smi::FromInt(message_levels));
9243   list = i::TemplateList::Add(isolate, list, listener);
9244   isolate->heap()->SetMessageListeners(*list);
9245   return true;
9246 }
9247 
RemoveMessageListeners(MessageCallback that)9248 void Isolate::RemoveMessageListeners(MessageCallback that) {
9249   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9250   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9251   i::HandleScope scope(isolate);
9252   i::DisallowGarbageCollection no_gc;
9253   i::TemplateList listeners = isolate->heap()->message_listeners();
9254   for (int i = 0; i < listeners.length(); i++) {
9255     if (listeners.get(i).IsUndefined(isolate)) continue;  // skip deleted ones
9256     i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9257     i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9258     if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9259       listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9260     }
9261   }
9262 }
9263 
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9264 void Isolate::SetFailedAccessCheckCallbackFunction(
9265     FailedAccessCheckCallback callback) {
9266   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9267   isolate->SetFailedAccessCheckCallback(callback);
9268 }
9269 
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9270 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9271     bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9272   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9273   isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9274                                                      options);
9275 }
9276 
VisitExternalResources(ExternalResourceVisitor * visitor)9277 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9278   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9279   isolate->heap()->VisitExternalResources(visitor);
9280 }
9281 
IsInUse()9282 bool Isolate::IsInUse() {
9283   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9284   return isolate->IsInUse();
9285 }
9286 
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9287 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9288   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9289   i::DisallowGarbageCollection no_gc;
9290   isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9291 }
9292 
VisitWeakHandles(PersistentHandleVisitor * visitor)9293 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9294   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9295   i::DisallowGarbageCollection no_gc;
9296   isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9297 }
9298 
SetAllowAtomicsWait(bool allow)9299 void Isolate::SetAllowAtomicsWait(bool allow) {
9300   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9301   isolate->set_allow_atomics_wait(allow);
9302 }
9303 
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9304 void v8::Isolate::DateTimeConfigurationChangeNotification(
9305     TimeZoneDetection time_zone_detection) {
9306   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9307   LOG_API(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9308   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9309   i_isolate->date_cache()->ResetDateCache(
9310       static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9311 #ifdef V8_INTL_SUPPORT
9312   i_isolate->clear_cached_icu_object(
9313       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9314   i_isolate->clear_cached_icu_object(
9315       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9316   i_isolate->clear_cached_icu_object(
9317       i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9318 #endif  // V8_INTL_SUPPORT
9319 }
9320 
LocaleConfigurationChangeNotification()9321 void v8::Isolate::LocaleConfigurationChangeNotification() {
9322   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9323   LOG_API(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9324   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9325 
9326 #ifdef V8_INTL_SUPPORT
9327   i_isolate->ResetDefaultLocale();
9328   i_isolate->clear_cached_icu_objects();
9329 #endif  // V8_INTL_SUPPORT
9330 }
9331 
IsCodeLike(v8::Isolate * isolate) const9332 bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
9333   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9334   LOG_API(i_isolate, Object, IsCodeLike);
9335   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9336   i::HandleScope scope(i_isolate);
9337   return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9338 }
9339 
9340 // static
New(Isolate * isolate,MicrotasksPolicy policy)9341 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9342                                                     MicrotasksPolicy policy) {
9343   auto microtask_queue =
9344       i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9345   microtask_queue->set_microtasks_policy(policy);
9346   std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9347   return ret;
9348 }
9349 
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9350 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9351     : MicrotasksScope(isolate, nullptr, type) {}
9352 
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9353 MicrotasksScope::MicrotasksScope(Isolate* isolate,
9354                                  MicrotaskQueue* microtask_queue,
9355                                  MicrotasksScope::Type type)
9356     : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9357       microtask_queue_(microtask_queue
9358                            ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9359                            : isolate_->default_microtask_queue()),
9360       run_(type == MicrotasksScope::kRunMicrotasks) {
9361   if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9362 #ifdef DEBUG
9363   if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9364 #endif
9365 }
9366 
~MicrotasksScope()9367 MicrotasksScope::~MicrotasksScope() {
9368   if (run_) {
9369     microtask_queue_->DecrementMicrotasksScopeDepth();
9370     if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9371         !isolate_->has_scheduled_exception()) {
9372       DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9373                      isolate_->scheduled_exception() ==
9374                          i::ReadOnlyRoots(isolate_).termination_exception());
9375       microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9376     }
9377   }
9378 #ifdef DEBUG
9379   if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9380 #endif
9381 }
9382 
9383 // static
PerformCheckpoint(Isolate * v8_isolate)9384 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9385   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9386   auto* microtask_queue = isolate->default_microtask_queue();
9387   microtask_queue->PerformCheckpoint(v8_isolate);
9388 }
9389 
9390 // static
GetCurrentDepth(Isolate * v8_isolate)9391 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9392   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9393   auto* microtask_queue = isolate->default_microtask_queue();
9394   return microtask_queue->GetMicrotasksScopeDepth();
9395 }
9396 
9397 // static
IsRunningMicrotasks(Isolate * v8_isolate)9398 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9399   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9400   auto* microtask_queue = isolate->default_microtask_queue();
9401   return microtask_queue->IsRunningMicrotasks();
9402 }
9403 
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9404 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9405     : str_(nullptr), length_(0) {
9406   if (obj.IsEmpty()) return;
9407   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9408   ENTER_V8_DO_NOT_USE(i_isolate);
9409   i::HandleScope scope(i_isolate);
9410   Local<Context> context = isolate->GetCurrentContext();
9411   TryCatch try_catch(isolate);
9412   Local<String> str;
9413   if (!obj->ToString(context).ToLocal(&str)) return;
9414   length_ = str->Utf8Length(isolate);
9415   str_ = i::NewArray<char>(length_ + 1);
9416   str->WriteUtf8(isolate, str_);
9417 }
9418 
~Utf8Value()9419 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9420 
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9421 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9422     : str_(nullptr), length_(0) {
9423   if (obj.IsEmpty()) return;
9424   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9425   ENTER_V8_DO_NOT_USE(i_isolate);
9426   i::HandleScope scope(i_isolate);
9427   Local<Context> context = isolate->GetCurrentContext();
9428   TryCatch try_catch(isolate);
9429   Local<String> str;
9430   if (!obj->ToString(context).ToLocal(&str)) return;
9431   length_ = str->Length();
9432   str_ = i::NewArray<uint16_t>(length_ + 1);
9433   str->Write(isolate, str_);
9434 }
9435 
~Value()9436 String::Value::~Value() { i::DeleteArray(str_); }
9437 
9438 #define DEFINE_ERROR(NAME, name)                                         \
9439   Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) {      \
9440     i::Isolate* isolate = i::Isolate::Current();                         \
9441     LOG_API(isolate, NAME, New);                                         \
9442     ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);                            \
9443     i::Object error;                                                     \
9444     {                                                                    \
9445       i::HandleScope scope(isolate);                                     \
9446       i::Handle<i::String> message = Utils::OpenHandle(*raw_message);    \
9447       i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9448       error = *isolate->factory()->NewError(constructor, message);       \
9449     }                                                                    \
9450     i::Handle<i::Object> result(error, isolate);                         \
9451     return Utils::ToLocal(result);                                       \
9452   }
9453 
DEFINE_ERROR(RangeError,range_error)9454 DEFINE_ERROR(RangeError, range_error)
9455 DEFINE_ERROR(ReferenceError, reference_error)
9456 DEFINE_ERROR(SyntaxError, syntax_error)
9457 DEFINE_ERROR(TypeError, type_error)
9458 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9459 DEFINE_ERROR(WasmLinkError, wasm_link_error)
9460 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9461 DEFINE_ERROR(Error, error)
9462 
9463 #undef DEFINE_ERROR
9464 
9465 Local<Message> Exception::CreateMessage(Isolate* isolate,
9466                                         Local<Value> exception) {
9467   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9468   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9469   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9470   i::HandleScope scope(i_isolate);
9471   return Utils::MessageToLocal(
9472       scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9473 }
9474 
GetStackTrace(Local<Value> exception)9475 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9476   i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9477   if (!obj->IsJSObject()) return Local<StackTrace>();
9478   i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9479   i::Isolate* isolate = js_obj->GetIsolate();
9480   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9481   return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9482 }
9483 
PreviewEntries(bool * is_key_value)9484 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
9485   if (IsMap()) {
9486     *is_key_value = true;
9487     return Map::Cast(this)->AsArray();
9488   }
9489   if (IsSet()) {
9490     *is_key_value = false;
9491     return Set::Cast(this)->AsArray();
9492   }
9493 
9494   i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
9495   i::Isolate* isolate = object->GetIsolate();
9496   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
9497   ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9498   if (object->IsJSWeakCollection()) {
9499     *is_key_value = object->IsJSWeakMap();
9500     return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9501         i::Handle<i::JSWeakCollection>::cast(object), 0));
9502   }
9503   if (object->IsJSMapIterator()) {
9504     i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
9505     MapAsArrayKind const kind =
9506         static_cast<MapAsArrayKind>(it->map().instance_type());
9507     *is_key_value = kind == MapAsArrayKind::kEntries;
9508     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9509     return Utils::ToLocal(
9510         MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9511   }
9512   if (object->IsJSSetIterator()) {
9513     i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9514     SetAsArrayKind const kind =
9515         static_cast<SetAsArrayKind>(it->map().instance_type());
9516     *is_key_value = kind == SetAsArrayKind::kEntries;
9517     if (!it->HasMore()) return v8::Array::New(v8_isolate);
9518     return Utils::ToLocal(
9519         SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9520   }
9521   return v8::MaybeLocal<v8::Array>();
9522 }
9523 
GetFunctionName() const9524 Local<String> CpuProfileNode::GetFunctionName() const {
9525   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9526   i::Isolate* isolate = node->isolate();
9527   const i::CodeEntry* entry = node->entry();
9528   i::Handle<i::String> name =
9529       isolate->factory()->InternalizeUtf8String(entry->name());
9530   return ToApiHandle<String>(name);
9531 }
9532 
GetFunctionNameStr() const9533 const char* CpuProfileNode::GetFunctionNameStr() const {
9534   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9535   return node->entry()->name();
9536 }
9537 
GetScriptId() const9538 int CpuProfileNode::GetScriptId() const {
9539   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9540   const i::CodeEntry* entry = node->entry();
9541   return entry->script_id();
9542 }
9543 
GetScriptResourceName() const9544 Local<String> CpuProfileNode::GetScriptResourceName() const {
9545   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9546   i::Isolate* isolate = node->isolate();
9547   return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9548       node->entry()->resource_name()));
9549 }
9550 
GetScriptResourceNameStr() const9551 const char* CpuProfileNode::GetScriptResourceNameStr() const {
9552   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9553   return node->entry()->resource_name();
9554 }
9555 
IsScriptSharedCrossOrigin() const9556 bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9557   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9558   return node->entry()->is_shared_cross_origin();
9559 }
9560 
GetLineNumber() const9561 int CpuProfileNode::GetLineNumber() const {
9562   return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9563 }
9564 
GetColumnNumber() const9565 int CpuProfileNode::GetColumnNumber() const {
9566   return reinterpret_cast<const i::ProfileNode*>(this)
9567       ->entry()
9568       ->column_number();
9569 }
9570 
GetHitLineCount() const9571 unsigned int CpuProfileNode::GetHitLineCount() const {
9572   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9573   return node->GetHitLineCount();
9574 }
9575 
GetLineTicks(LineTick * entries,unsigned int length) const9576 bool CpuProfileNode::GetLineTicks(LineTick* entries,
9577                                   unsigned int length) const {
9578   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9579   return node->GetLineTicks(entries, length);
9580 }
9581 
GetBailoutReason() const9582 const char* CpuProfileNode::GetBailoutReason() const {
9583   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9584   return node->entry()->bailout_reason();
9585 }
9586 
GetHitCount() const9587 unsigned CpuProfileNode::GetHitCount() const {
9588   return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9589 }
9590 
GetNodeId() const9591 unsigned CpuProfileNode::GetNodeId() const {
9592   return reinterpret_cast<const i::ProfileNode*>(this)->id();
9593 }
9594 
GetSourceType() const9595 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9596   return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9597 }
9598 
GetChildrenCount() const9599 int CpuProfileNode::GetChildrenCount() const {
9600   return static_cast<int>(
9601       reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9602 }
9603 
GetChild(int index) const9604 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9605   const i::ProfileNode* child =
9606       reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9607   return reinterpret_cast<const CpuProfileNode*>(child);
9608 }
9609 
GetParent() const9610 const CpuProfileNode* CpuProfileNode::GetParent() const {
9611   const i::ProfileNode* parent =
9612       reinterpret_cast<const i::ProfileNode*>(this)->parent();
9613   return reinterpret_cast<const CpuProfileNode*>(parent);
9614 }
9615 
GetDeoptInfos() const9616 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9617   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9618   return node->deopt_infos();
9619 }
9620 
Delete()9621 void CpuProfile::Delete() {
9622   i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9623   i::CpuProfiler* profiler = profile->cpu_profiler();
9624   DCHECK_NOT_NULL(profiler);
9625   profiler->DeleteProfile(profile);
9626 }
9627 
GetTitle() const9628 Local<String> CpuProfile::GetTitle() const {
9629   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9630   i::Isolate* isolate = profile->top_down()->isolate();
9631   return ToApiHandle<String>(
9632       isolate->factory()->InternalizeUtf8String(profile->title()));
9633 }
9634 
GetTopDownRoot() const9635 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9636   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9637   return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9638 }
9639 
GetSample(int index) const9640 const CpuProfileNode* CpuProfile::GetSample(int index) const {
9641   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9642   return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
9643 }
9644 
9645 const int CpuProfileNode::kNoLineNumberInfo;
9646 const int CpuProfileNode::kNoColumnNumberInfo;
9647 
GetSampleTimestamp(int index) const9648 int64_t CpuProfile::GetSampleTimestamp(int index) const {
9649   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9650   return profile->sample(index).timestamp.since_origin().InMicroseconds();
9651 }
9652 
GetStartTime() const9653 int64_t CpuProfile::GetStartTime() const {
9654   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9655   return profile->start_time().since_origin().InMicroseconds();
9656 }
9657 
GetEndTime() const9658 int64_t CpuProfile::GetEndTime() const {
9659   const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9660   return profile->end_time().since_origin().InMicroseconds();
9661 }
9662 
GetSamplesCount() const9663 int CpuProfile::GetSamplesCount() const {
9664   return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9665 }
9666 
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)9667 CpuProfiler* CpuProfiler::New(Isolate* isolate,
9668                               CpuProfilingNamingMode naming_mode,
9669                               CpuProfilingLoggingMode logging_mode) {
9670   return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
9671       reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
9672 }
9673 
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)9674 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
9675                                          unsigned max_samples,
9676                                          int sampling_interval_us,
9677                                          MaybeLocal<Context> filter_context)
9678     : mode_(mode),
9679       max_samples_(max_samples),
9680       sampling_interval_us_(sampling_interval_us) {
9681   if (!filter_context.IsEmpty()) {
9682     Local<Context> local_filter_context = filter_context.ToLocalChecked();
9683     filter_context_.Reset(local_filter_context->GetIsolate(),
9684                           local_filter_context);
9685     filter_context_.SetWeak();
9686   }
9687 }
9688 
raw_filter_context() const9689 void* CpuProfilingOptions::raw_filter_context() const {
9690   return reinterpret_cast<void*>(
9691       i::Context::cast(*Utils::OpenPersistent(filter_context_))
9692           .native_context()
9693           .address());
9694 }
9695 
Dispose()9696 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9697 
9698 // static
CollectSample(Isolate * isolate)9699 void CpuProfiler::CollectSample(Isolate* isolate) {
9700   i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
9701 }
9702 
SetSamplingInterval(int us)9703 void CpuProfiler::SetSamplingInterval(int us) {
9704   DCHECK_GE(us, 0);
9705   return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
9706       base::TimeDelta::FromMicroseconds(us));
9707 }
9708 
SetUsePreciseSampling(bool use_precise_sampling)9709 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
9710   reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
9711       use_precise_sampling);
9712 }
9713 
StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9714 CpuProfilingStatus CpuProfiler::StartProfiling(
9715     Local<String> title, CpuProfilingOptions options,
9716     std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9717   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9718       *Utils::OpenHandle(*title), options, std::move(delegate));
9719 }
9720 
StartProfiling(Local<String> title,bool record_samples)9721 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9722                                                bool record_samples) {
9723   CpuProfilingOptions options(
9724       kLeafNodeLineNumbers,
9725       record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
9726   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9727       *Utils::OpenHandle(*title), options);
9728 }
9729 
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9730 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9731                                                CpuProfilingMode mode,
9732                                                bool record_samples,
9733                                                unsigned max_samples) {
9734   CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
9735   return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9736       *Utils::OpenHandle(*title), options);
9737 }
9738 
StopProfiling(Local<String> title)9739 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
9740   return reinterpret_cast<CpuProfile*>(
9741       reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
9742           *Utils::OpenHandle(*title)));
9743 }
9744 
UseDetailedSourcePositionsForProfiling(Isolate * isolate)9745 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
9746   reinterpret_cast<i::Isolate*>(isolate)
9747       ->SetDetailedSourcePositionsForProfiling(true);
9748 }
9749 
GetCodeStartAddress()9750 uintptr_t CodeEvent::GetCodeStartAddress() {
9751   return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
9752 }
9753 
GetCodeSize()9754 size_t CodeEvent::GetCodeSize() {
9755   return reinterpret_cast<i::CodeEvent*>(this)->code_size;
9756 }
9757 
GetFunctionName()9758 Local<String> CodeEvent::GetFunctionName() {
9759   return ToApiHandle<String>(
9760       reinterpret_cast<i::CodeEvent*>(this)->function_name);
9761 }
9762 
GetScriptName()9763 Local<String> CodeEvent::GetScriptName() {
9764   return ToApiHandle<String>(
9765       reinterpret_cast<i::CodeEvent*>(this)->script_name);
9766 }
9767 
GetScriptLine()9768 int CodeEvent::GetScriptLine() {
9769   return reinterpret_cast<i::CodeEvent*>(this)->script_line;
9770 }
9771 
GetScriptColumn()9772 int CodeEvent::GetScriptColumn() {
9773   return reinterpret_cast<i::CodeEvent*>(this)->script_column;
9774 }
9775 
GetCodeType()9776 CodeEventType CodeEvent::GetCodeType() {
9777   return reinterpret_cast<i::CodeEvent*>(this)->code_type;
9778 }
9779 
GetComment()9780 const char* CodeEvent::GetComment() {
9781   return reinterpret_cast<i::CodeEvent*>(this)->comment;
9782 }
9783 
GetPreviousCodeStartAddress()9784 uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
9785   return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
9786 }
9787 
GetCodeEventTypeName(CodeEventType code_event_type)9788 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
9789   switch (code_event_type) {
9790     case kUnknownType:
9791       return "Unknown";
9792 #define V(Name)       \
9793   case k##Name##Type: \
9794     return #Name;
9795       CODE_EVENTS_LIST(V)
9796 #undef V
9797   }
9798   // The execution should never pass here
9799   UNREACHABLE();
9800 }
9801 
CodeEventHandler(Isolate * isolate)9802 CodeEventHandler::CodeEventHandler(Isolate* isolate) {
9803   internal_listener_ =
9804       new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
9805 }
9806 
~CodeEventHandler()9807 CodeEventHandler::~CodeEventHandler() {
9808   delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
9809 }
9810 
Enable()9811 void CodeEventHandler::Enable() {
9812   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
9813       ->StartListening(this);
9814 }
9815 
Disable()9816 void CodeEventHandler::Disable() {
9817   reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
9818       ->StopListening();
9819 }
9820 
ToInternal(const HeapGraphEdge * edge)9821 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
9822   return const_cast<i::HeapGraphEdge*>(
9823       reinterpret_cast<const i::HeapGraphEdge*>(edge));
9824 }
9825 
GetType() const9826 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
9827   return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
9828 }
9829 
GetName() const9830 Local<Value> HeapGraphEdge::GetName() const {
9831   i::HeapGraphEdge* edge = ToInternal(this);
9832   i::Isolate* isolate = edge->isolate();
9833   switch (edge->type()) {
9834     case i::HeapGraphEdge::kContextVariable:
9835     case i::HeapGraphEdge::kInternal:
9836     case i::HeapGraphEdge::kProperty:
9837     case i::HeapGraphEdge::kShortcut:
9838     case i::HeapGraphEdge::kWeak:
9839       return ToApiHandle<String>(
9840           isolate->factory()->InternalizeUtf8String(edge->name()));
9841     case i::HeapGraphEdge::kElement:
9842     case i::HeapGraphEdge::kHidden:
9843       return ToApiHandle<Number>(
9844           isolate->factory()->NewNumberFromInt(edge->index()));
9845     default:
9846       UNREACHABLE();
9847   }
9848 }
9849 
GetFromNode() const9850 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
9851   const i::HeapEntry* from = ToInternal(this)->from();
9852   return reinterpret_cast<const HeapGraphNode*>(from);
9853 }
9854 
GetToNode() const9855 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
9856   const i::HeapEntry* to = ToInternal(this)->to();
9857   return reinterpret_cast<const HeapGraphNode*>(to);
9858 }
9859 
ToInternal(const HeapGraphNode * entry)9860 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
9861   return const_cast<i::HeapEntry*>(
9862       reinterpret_cast<const i::HeapEntry*>(entry));
9863 }
9864 
GetType() const9865 HeapGraphNode::Type HeapGraphNode::GetType() const {
9866   return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
9867 }
9868 
GetName() const9869 Local<String> HeapGraphNode::GetName() const {
9870   i::Isolate* isolate = ToInternal(this)->isolate();
9871   return ToApiHandle<String>(
9872       isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
9873 }
9874 
GetId() const9875 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
9876 
GetShallowSize() const9877 size_t HeapGraphNode::GetShallowSize() const {
9878   return ToInternal(this)->self_size();
9879 }
9880 
GetChildrenCount() const9881 int HeapGraphNode::GetChildrenCount() const {
9882   return ToInternal(this)->children_count();
9883 }
9884 
GetChild(int index) const9885 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
9886   return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
9887 }
9888 
ToInternal(const HeapSnapshot * snapshot)9889 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
9890   return const_cast<i::HeapSnapshot*>(
9891       reinterpret_cast<const i::HeapSnapshot*>(snapshot));
9892 }
9893 
Delete()9894 void HeapSnapshot::Delete() {
9895   i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
9896   if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
9897       isolate->heap_profiler()->IsTakingSnapshot()) {
9898     ToInternal(this)->Delete();
9899   } else {
9900     // If this is the last snapshot, clean up all accessory data as well.
9901     isolate->heap_profiler()->DeleteAllSnapshots();
9902   }
9903 }
9904 
GetRoot() const9905 const HeapGraphNode* HeapSnapshot::GetRoot() const {
9906   return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
9907 }
9908 
GetNodeById(SnapshotObjectId id) const9909 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
9910   return reinterpret_cast<const HeapGraphNode*>(
9911       ToInternal(this)->GetEntryById(id));
9912 }
9913 
GetNodesCount() const9914 int HeapSnapshot::GetNodesCount() const {
9915   return static_cast<int>(ToInternal(this)->entries().size());
9916 }
9917 
GetNode(int index) const9918 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
9919   return reinterpret_cast<const HeapGraphNode*>(
9920       &ToInternal(this)->entries().at(index));
9921 }
9922 
GetMaxSnapshotJSObjectId() const9923 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
9924   return ToInternal(this)->max_snapshot_js_object_id();
9925 }
9926 
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const9927 void HeapSnapshot::Serialize(OutputStream* stream,
9928                              HeapSnapshot::SerializationFormat format) const {
9929   Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
9930                   "Unknown serialization format");
9931   Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
9932                   "Invalid stream chunk size");
9933   i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
9934   serializer.Serialize(stream);
9935 }
9936 
9937 // static
9938 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
9939     HeapProfiler::kUnknownObjectId;
9940 
GetSnapshotCount()9941 int HeapProfiler::GetSnapshotCount() {
9942   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
9943 }
9944 
GetHeapSnapshot(int index)9945 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
9946   return reinterpret_cast<const HeapSnapshot*>(
9947       reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
9948 }
9949 
GetObjectId(Local<Value> value)9950 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
9951   i::Handle<i::Object> obj = Utils::OpenHandle(*value);
9952   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
9953 }
9954 
GetObjectId(NativeObject value)9955 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
9956   return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
9957 }
9958 
FindObjectById(SnapshotObjectId id)9959 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
9960   i::Handle<i::Object> obj =
9961       reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
9962   if (obj.is_null()) return Local<Value>();
9963   return Utils::ToLocal(obj);
9964 }
9965 
ClearObjectIds()9966 void HeapProfiler::ClearObjectIds() {
9967   reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
9968 }
9969 
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)9970 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
9971     ActivityControl* control, ObjectNameResolver* resolver,
9972     bool treat_global_objects_as_roots, bool capture_numeric_value) {
9973   return reinterpret_cast<const HeapSnapshot*>(
9974       reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
9975           control, resolver, treat_global_objects_as_roots,
9976           capture_numeric_value));
9977 }
9978 
StartTrackingHeapObjects(bool track_allocations)9979 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
9980   reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
9981       track_allocations);
9982 }
9983 
StopTrackingHeapObjects()9984 void HeapProfiler::StopTrackingHeapObjects() {
9985   reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
9986 }
9987 
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)9988 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
9989                                             int64_t* timestamp_us) {
9990   i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
9991   return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
9992 }
9993 
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)9994 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
9995                                              int stack_depth,
9996                                              SamplingFlags flags) {
9997   return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
9998       sample_interval, stack_depth, flags);
9999 }
10000 
StopSamplingHeapProfiler()10001 void HeapProfiler::StopSamplingHeapProfiler() {
10002   reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10003 }
10004 
GetAllocationProfile()10005 AllocationProfile* HeapProfiler::GetAllocationProfile() {
10006   return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10007 }
10008 
DeleteAllHeapSnapshots()10009 void HeapProfiler::DeleteAllHeapSnapshots() {
10010   reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10011 }
10012 
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10013 void HeapProfiler::AddBuildEmbedderGraphCallback(
10014     BuildEmbedderGraphCallback callback, void* data) {
10015   reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10016       callback, data);
10017 }
10018 
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10019 void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10020     BuildEmbedderGraphCallback callback, void* data) {
10021   reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10022       callback, data);
10023 }
10024 
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10025 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10026                                               void* data) {
10027   reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10028                                                                        data);
10029 }
10030 
SetStackStart(void * stack_start)10031 void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10032   CHECK(isolate_);
10033   reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10034       stack_start);
10035 }
10036 
NotifyEmptyEmbedderStack()10037 void EmbedderHeapTracer::NotifyEmptyEmbedderStack() {
10038   CHECK(isolate_);
10039   reinterpret_cast<i::Isolate*>(isolate_)
10040       ->heap()
10041       ->local_embedder_heap_tracer()
10042       ->NotifyEmptyEmbedderStack();
10043 }
10044 
FinalizeTracing()10045 void EmbedderHeapTracer::FinalizeTracing() {
10046   if (isolate_) {
10047     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10048     if (isolate->heap()->incremental_marking()->IsMarking()) {
10049       isolate->heap()->FinalizeIncrementalMarkingAtomically(
10050           i::GarbageCollectionReason::kExternalFinalize);
10051     }
10052   }
10053 }
10054 
GarbageCollectionForTesting(EmbedderStackState stack_state)10055 void EmbedderHeapTracer::GarbageCollectionForTesting(
10056     EmbedderStackState stack_state) {
10057   CHECK(isolate_);
10058   Utils::ApiCheck(i::FLAG_expose_gc,
10059                   "v8::EmbedderHeapTracer::GarbageCollectionForTesting",
10060                   "Must use --expose-gc");
10061   i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10062   heap->SetEmbedderStackStateForNextFinalization(stack_state);
10063   heap->PreciseCollectAllGarbage(i::Heap::kNoGCFlags,
10064                                  i::GarbageCollectionReason::kTesting,
10065                                  kGCCallbackFlagForced);
10066 }
10067 
IncreaseAllocatedSize(size_t bytes)10068 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
10069   if (isolate_) {
10070     i::LocalEmbedderHeapTracer* const tracer =
10071         reinterpret_cast<i::Isolate*>(isolate_)
10072             ->heap()
10073             ->local_embedder_heap_tracer();
10074     DCHECK_NOT_NULL(tracer);
10075     tracer->IncreaseAllocatedSize(bytes);
10076   }
10077 }
10078 
DecreaseAllocatedSize(size_t bytes)10079 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
10080   if (isolate_) {
10081     i::LocalEmbedderHeapTracer* const tracer =
10082         reinterpret_cast<i::Isolate*>(isolate_)
10083             ->heap()
10084             ->local_embedder_heap_tracer();
10085     DCHECK_NOT_NULL(tracer);
10086     tracer->DecreaseAllocatedSize(bytes);
10087   }
10088 }
10089 
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10090 void EmbedderHeapTracer::RegisterEmbedderReference(
10091     const BasicTracedReference<v8::Data>& ref) {
10092   if (ref.IsEmpty()) return;
10093 
10094   i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10095   heap->RegisterExternallyReferencedObject(
10096       reinterpret_cast<i::Address*>(ref.val_));
10097 }
10098 
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10099 void EmbedderHeapTracer::IterateTracedGlobalHandles(
10100     TracedGlobalHandleVisitor* visitor) {
10101   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10102   i::DisallowGarbageCollection no_gc;
10103   isolate->global_handles()->IterateTracedNodes(visitor);
10104 }
10105 
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10106 bool EmbedderHeapTracer::IsRootForNonTracingGC(
10107     const v8::TracedReference<v8::Value>& handle) {
10108   return true;
10109 }
10110 
IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value> & handle)10111 bool EmbedderHeapTracer::IsRootForNonTracingGC(
10112     const v8::TracedGlobal<v8::Value>& handle) {
10113   return true;
10114 }
10115 
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10116 void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10117     const v8::TracedReference<v8::Value>& handle) {
10118   UNREACHABLE();
10119 }
10120 
CheckValue() const10121 void TracedReferenceBase::CheckValue() const {
10122 #ifdef V8_HOST_ARCH_64_BIT
10123   if (!val_) return;
10124 
10125   CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_));
10126 #endif  // V8_HOST_ARCH_64_BIT
10127 }
10128 
CFunction(const void * address,const CFunctionInfo * type_info)10129 CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
10130     : address_(address), type_info_(type_info) {
10131   CHECK_NOT_NULL(address_);
10132   CHECK_NOT_NULL(type_info_);
10133 }
10134 
CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10135 CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info,
10136                              unsigned int arg_count, const CTypeInfo* arg_info)
10137     : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) {
10138   if (arg_count_ > 0) {
10139     for (unsigned int i = 0; i < arg_count_ - 1; ++i) {
10140       DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType);
10141     }
10142   }
10143 }
10144 
ArgumentInfo(unsigned int index) const10145 const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10146   DCHECK_LT(index, ArgumentCount());
10147   return arg_info_[index];
10148 }
10149 
ValidateIndex(size_t index) const10150 void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10151   DCHECK_LT(index, length_);
10152 }
10153 
RegisterState()10154 RegisterState::RegisterState()
10155     : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10156 RegisterState::~RegisterState() = default;
10157 
RegisterState(const RegisterState & other)10158 RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10159 
operator =(const RegisterState & other)10160 RegisterState& RegisterState::operator=(const RegisterState& other) {
10161   if (&other != this) {
10162     pc = other.pc;
10163     sp = other.sp;
10164     fp = other.fp;
10165     lr = other.lr;
10166     if (other.callee_saved) {
10167       // Make a deep copy if {other.callee_saved} is non-null.
10168       callee_saved =
10169           std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
10170     } else {
10171       // Otherwise, set {callee_saved} to null to match {other}.
10172       callee_saved.reset();
10173     }
10174   }
10175   return *this;
10176 }
10177 
10178 #if !V8_ENABLE_WEBASSEMBLY
10179 // If WebAssembly is disabled, we still need to provide an implementation of the
10180 // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all
10181 // methods are unreachable.
10182 
10183 class WasmStreaming::WasmStreamingImpl {};
10184 
WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10185 WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10186   UNREACHABLE();
10187 }
10188 
10189 WasmStreaming::~WasmStreaming() = default;
10190 
OnBytesReceived(const uint8_t * bytes,size_t size)10191 void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10192   UNREACHABLE();
10193 }
10194 
Finish()10195 void WasmStreaming::Finish() { UNREACHABLE(); }
10196 
Abort(MaybeLocal<Value> exception)10197 void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10198 
SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10199 bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10200   UNREACHABLE();
10201 }
10202 
SetClient(std::shared_ptr<Client> client)10203 void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10204 
SetUrl(const char * url,size_t length)10205 void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10206 
10207 // static
Unpack(Isolate * isolate,Local<Value> value)10208 std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10209                                                      Local<Value> value) {
10210   FATAL("WebAssembly is disabled");
10211 }
10212 #endif  // !V8_ENABLE_WEBASSEMBLY
10213 
10214 namespace internal {
10215 
10216 const size_t HandleScopeImplementer::kEnteredContextsOffset =
10217     offsetof(HandleScopeImplementer, entered_contexts_);
10218 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10219     offsetof(HandleScopeImplementer, is_microtask_context_);
10220 
FreeThreadResources()10221 void HandleScopeImplementer::FreeThreadResources() { Free(); }
10222 
ArchiveThread(char * storage)10223 char* HandleScopeImplementer::ArchiveThread(char* storage) {
10224   HandleScopeData* current = isolate_->handle_scope_data();
10225   handle_scope_data_ = *current;
10226   MemCopy(storage, this, sizeof(*this));
10227 
10228   ResetAfterArchive();
10229   current->Initialize();
10230 
10231   return storage + ArchiveSpacePerThread();
10232 }
10233 
ArchiveSpacePerThread()10234 int HandleScopeImplementer::ArchiveSpacePerThread() {
10235   return sizeof(HandleScopeImplementer);
10236 }
10237 
RestoreThread(char * storage)10238 char* HandleScopeImplementer::RestoreThread(char* storage) {
10239   MemCopy(this, storage, sizeof(*this));
10240   *isolate_->handle_scope_data() = handle_scope_data_;
10241   return storage + ArchiveSpacePerThread();
10242 }
10243 
IterateThis(RootVisitor * v)10244 void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10245 #ifdef DEBUG
10246   bool found_block_before_deferred = false;
10247 #endif
10248   // Iterate over all handles in the blocks except for the last.
10249   for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10250     Address* block = blocks()->at(i);
10251     // Cast possibly-unrelated pointers to plain Address before comparing them
10252     // to avoid undefined behavior.
10253     if (last_handle_before_deferred_block_ != nullptr &&
10254         (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
10255          reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
10256         (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
10257          reinterpret_cast<Address>(block))) {
10258       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10259                            FullObjectSlot(last_handle_before_deferred_block_));
10260       DCHECK(!found_block_before_deferred);
10261 #ifdef DEBUG
10262       found_block_before_deferred = true;
10263 #endif
10264     } else {
10265       v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10266                            FullObjectSlot(&block[kHandleBlockSize]));
10267     }
10268   }
10269 
10270   DCHECK(last_handle_before_deferred_block_ == nullptr ||
10271          found_block_before_deferred);
10272 
10273   // Iterate over live handles in the last block (if any).
10274   if (!blocks()->empty()) {
10275     v->VisitRootPointers(Root::kHandleScope, nullptr,
10276                          FullObjectSlot(blocks()->back()),
10277                          FullObjectSlot(handle_scope_data_.next));
10278   }
10279 
10280   DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
10281                                                  &entered_contexts_};
10282   for (unsigned i = 0; i < arraysize(context_lists); i++) {
10283     context_lists[i]->shrink_to_fit();
10284     if (context_lists[i]->empty()) continue;
10285     FullObjectSlot start(&context_lists[i]->front());
10286     v->VisitRootPointers(Root::kHandleScope, nullptr, start,
10287                          start + static_cast<int>(context_lists[i]->size()));
10288   }
10289 }
10290 
Iterate(RootVisitor * v)10291 void HandleScopeImplementer::Iterate(RootVisitor* v) {
10292   HandleScopeData* current = isolate_->handle_scope_data();
10293   handle_scope_data_ = *current;
10294   IterateThis(v);
10295 }
10296 
Iterate(RootVisitor * v,char * storage)10297 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10298   HandleScopeImplementer* scope_implementer =
10299       reinterpret_cast<HandleScopeImplementer*>(storage);
10300   scope_implementer->IterateThis(v);
10301   return storage + ArchiveSpacePerThread();
10302 }
10303 
DetachPersistent(Address * prev_limit)10304 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
10305     Address* prev_limit) {
10306   std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
10307   DCHECK_NOT_NULL(prev_limit);
10308 
10309   while (!blocks_.empty()) {
10310     Address* block_start = blocks_.back();
10311     Address* block_limit = &block_start[kHandleBlockSize];
10312     // We should not need to check for SealHandleScope here. Assert this.
10313     DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
10314                    prev_limit == block_limit);
10315     if (prev_limit == block_limit) break;
10316     ph->blocks_.push_back(blocks_.back());
10317 #if DEBUG
10318     ph->ordered_blocks_.insert(blocks_.back());
10319 #endif
10320     blocks_.pop_back();
10321   }
10322 
10323   // ph->blocks_ now contains the blocks installed on the
10324   // HandleScope stack since BeginDeferredScope was called, but in
10325   // reverse order.
10326 
10327   // Switch first and last blocks, such that the last block is the one
10328   // that is potentially half full.
10329   DCHECK(!blocks_.empty() && !ph->blocks_.empty());
10330   std::swap(ph->blocks_.front(), ph->blocks_.back());
10331 
10332   ph->block_next_ = isolate()->handle_scope_data()->next;
10333   Address* block_start = ph->blocks_.back();
10334   ph->block_limit_ = block_start + kHandleBlockSize;
10335 
10336   DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10337   last_handle_before_deferred_block_ = nullptr;
10338   return ph;
10339 }
10340 
BeginDeferredScope()10341 void HandleScopeImplementer::BeginDeferredScope() {
10342   DCHECK_NULL(last_handle_before_deferred_block_);
10343   last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10344 }
10345 
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10346 void InvokeAccessorGetterCallback(
10347     v8::Local<v8::Name> property,
10348     const v8::PropertyCallbackInfo<v8::Value>& info,
10349     v8::AccessorNameGetterCallback getter) {
10350   // Leaving JavaScript.
10351   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10352   RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
10353   Address getter_address = reinterpret_cast<Address>(getter);
10354   ExternalCallbackScope call_scope(isolate, getter_address);
10355   getter(property, info);
10356 }
10357 
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10358 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10359                             v8::FunctionCallback callback) {
10360   Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10361   RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
10362   Address callback_address = reinterpret_cast<Address>(callback);
10363   ExternalCallbackScope call_scope(isolate, callback_address);
10364   callback(info);
10365 }
10366 
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10367 void InvokeFinalizationRegistryCleanupFromTask(
10368     Handle<Context> context,
10369     Handle<JSFinalizationRegistry> finalization_registry,
10370     Handle<Object> callback) {
10371   Isolate* isolate = finalization_registry->native_context().GetIsolate();
10372   RCS_SCOPE(isolate,
10373             RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
10374   // Do not use ENTER_V8 because this is always called from a running
10375   // FinalizationRegistryCleanupTask within V8 and we should not log it as an
10376   // API call. This method is implemented here to avoid duplication of the
10377   // exception handling and microtask running logic in CallDepthScope.
10378   if (IsExecutionTerminatingCheck(isolate)) return;
10379   Local<v8::Context> api_context = Utils::ToLocal(context);
10380   CallDepthScope<true> call_depth_scope(isolate, api_context);
10381   VMState<OTHER> state(isolate);
10382   Handle<Object> argv[] = {callback};
10383   if (Execution::CallBuiltin(isolate,
10384                              isolate->finalization_registry_cleanup_some(),
10385                              finalization_registry, arraysize(argv), argv)
10386           .is_null()) {
10387     call_depth_scope.Escape();
10388   }
10389 }
10390 
10391 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10392 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10393 int32_t ConvertDouble(double d) {
10394   return internal::DoubleToInt32(d);
10395 }
10396 
10397 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10398 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10399 uint32_t ConvertDouble(double d) {
10400   return internal::DoubleToUint32(d);
10401 }
10402 
10403 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10404 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10405 float ConvertDouble(double d) {
10406   return internal::DoubleToFloat32(d);
10407 }
10408 
10409 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10410 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10411 double ConvertDouble(double d) {
10412   return d;
10413 }
10414 
10415 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10416 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10417 int64_t ConvertDouble(double d) {
10418   return internal::DoubleToWebIDLInt64(d);
10419 }
10420 
10421 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10422 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10423 uint64_t ConvertDouble(double d) {
10424   return internal::DoubleToWebIDLUint64(d);
10425 }
10426 
10427 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10428 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10429 bool ConvertDouble(double d) {
10430   // Implements https://tc39.es/ecma262/#sec-toboolean.
10431   return !std::isnan(d) && d != 0;
10432 }
10433 
10434 // Undefine macros for jumbo build.
10435 #undef SET_FIELD_WRAPPED
10436 #undef NEW_STRING
10437 #undef CALLBACK_SETTER
10438 
10439 }  // namespace internal
10440 
10441 template <>
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10442 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
10443     internal::CTypeInfoBuilder<int32_t>::Build().GetId(), int32_t>(
10444     Local<Array> src, int32_t* dst, uint32_t max_length) {
10445   return CopyAndConvertArrayToCppBuffer<
10446       CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence)
10447           .GetId(),
10448       int32_t>(src, dst, max_length);
10449 }
10450 
10451 template <>
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10452 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
10453     internal::CTypeInfoBuilder<uint32_t>::Build().GetId(), uint32_t>(
10454     Local<Array> src, uint32_t* dst, uint32_t max_length) {
10455   return CopyAndConvertArrayToCppBuffer<
10456       CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence)
10457           .GetId(),
10458       uint32_t>(src, dst, max_length);
10459 }
10460 
10461 template <>
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10462 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
10463     internal::CTypeInfoBuilder<float>::Build().GetId(), float>(
10464     Local<Array> src, float* dst, uint32_t max_length) {
10465   return CopyAndConvertArrayToCppBuffer<
10466       CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence)
10467           .GetId(),
10468       float>(src, dst, max_length);
10469 }
10470 
10471 template <>
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10472 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer<
10473     internal::CTypeInfoBuilder<double>::Build().GetId(), double>(
10474     Local<Array> src, double* dst, uint32_t max_length) {
10475   return CopyAndConvertArrayToCppBuffer<
10476       CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence)
10477           .GetId(),
10478       double>(src, dst, max_length);
10479 }
10480 
10481 }  // namespace v8
10482 
10483 #undef TRACE_BS
10484 #include "src/api/api-macros-undef.h"
10485