1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/api/api.h"
6
7 #include <algorithm> // For min
8 #include <cmath> // For isnan.
9 #include <limits>
10 #include <sstream>
11 #include <string>
12 #include <utility> // For move
13 #include <vector>
14
15 #include "include/v8-callbacks.h"
16 #include "include/v8-cppgc.h"
17 #include "include/v8-date.h"
18 #include "include/v8-embedder-state-scope.h"
19 #include "include/v8-extension.h"
20 #include "include/v8-fast-api-calls.h"
21 #include "include/v8-function.h"
22 #include "include/v8-json.h"
23 #include "include/v8-locker.h"
24 #include "include/v8-primitive-object.h"
25 #include "include/v8-profiler.h"
26 #include "include/v8-unwinder-state.h"
27 #include "include/v8-util.h"
28 #include "include/v8-wasm.h"
29 #include "src/api/api-inl.h"
30 #include "src/api/api-natives.h"
31 #include "src/base/functional.h"
32 #include "src/base/logging.h"
33 #include "src/base/platform/platform.h"
34 #include "src/base/platform/time.h"
35 #include "src/base/safe_conversions.h"
36 #include "src/base/utils/random-number-generator.h"
37 #include "src/baseline/baseline-batch-compiler.h"
38 #include "src/builtins/accessors.h"
39 #include "src/builtins/builtins-utils.h"
40 #include "src/codegen/compiler.h"
41 #include "src/codegen/cpu-features.h"
42 #include "src/codegen/script-details.h"
43 #include "src/common/assert-scope.h"
44 #include "src/common/globals.h"
45 #include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
46 #include "src/date/date.h"
47 #include "src/objects/primitive-heap-object.h"
48 #if V8_ENABLE_WEBASSEMBLY
49 #include "src/debug/debug-wasm-objects.h"
50 #endif // V8_ENABLE_WEBASSEMBLY
51 #include "src/debug/liveedit.h"
52 #include "src/deoptimizer/deoptimizer.h"
53 #include "src/execution/embedder-state.h"
54 #include "src/execution/execution.h"
55 #include "src/execution/frames-inl.h"
56 #include "src/execution/isolate-inl.h"
57 #include "src/execution/messages.h"
58 #include "src/execution/microtask-queue.h"
59 #include "src/execution/simulator.h"
60 #include "src/execution/v8threads.h"
61 #include "src/execution/vm-state-inl.h"
62 #include "src/handles/global-handles.h"
63 #include "src/handles/persistent-handles.h"
64 #include "src/heap/embedder-tracing.h"
65 #include "src/heap/heap-inl.h"
66 #include "src/heap/heap-write-barrier.h"
67 #include "src/heap/safepoint.h"
68 #include "src/init/bootstrapper.h"
69 #include "src/init/icu_util.h"
70 #include "src/init/startup-data-util.h"
71 #include "src/init/v8.h"
72 #include "src/json/json-parser.h"
73 #include "src/json/json-stringifier.h"
74 #include "src/logging/counters-scopes.h"
75 #include "src/logging/metrics.h"
76 #include "src/logging/runtime-call-stats-scope.h"
77 #include "src/logging/tracing-flags.h"
78 #include "src/numbers/conversions-inl.h"
79 #include "src/objects/api-callbacks.h"
80 #include "src/objects/contexts.h"
81 #include "src/objects/embedder-data-array-inl.h"
82 #include "src/objects/embedder-data-slot-inl.h"
83 #include "src/objects/hash-table-inl.h"
84 #include "src/objects/heap-object.h"
85 #include "src/objects/js-array-buffer-inl.h"
86 #include "src/objects/js-array-inl.h"
87 #include "src/objects/js-collection-inl.h"
88 #include "src/objects/js-promise-inl.h"
89 #include "src/objects/js-regexp-inl.h"
90 #include "src/objects/js-weak-refs-inl.h"
91 #include "src/objects/module-inl.h"
92 #include "src/objects/objects-inl.h"
93 #include "src/objects/oddball.h"
94 #include "src/objects/ordered-hash-table-inl.h"
95 #include "src/objects/property-descriptor.h"
96 #include "src/objects/property-details.h"
97 #include "src/objects/property.h"
98 #include "src/objects/prototype.h"
99 #include "src/objects/shared-function-info.h"
100 #include "src/objects/slots.h"
101 #include "src/objects/smi.h"
102 #include "src/objects/synthetic-module-inl.h"
103 #include "src/objects/templates.h"
104 #include "src/objects/value-serializer.h"
105 #include "src/parsing/parse-info.h"
106 #include "src/parsing/parser.h"
107 #include "src/parsing/pending-compilation-error-handler.h"
108 #include "src/parsing/scanner-character-streams.h"
109 #include "src/profiler/cpu-profiler.h"
110 #include "src/profiler/heap-profiler.h"
111 #include "src/profiler/heap-snapshot-generator-inl.h"
112 #include "src/profiler/profile-generator-inl.h"
113 #include "src/profiler/tick-sample.h"
114 #include "src/regexp/regexp-utils.h"
115 #include "src/runtime/runtime.h"
116 #include "src/sandbox/external-pointer.h"
117 #include "src/sandbox/sandbox.h"
118 #include "src/snapshot/code-serializer.h"
119 #include "src/snapshot/embedded/embedded-data.h"
120 #include "src/snapshot/snapshot.h"
121 #include "src/snapshot/startup-serializer.h" // For SerializedHandleChecker.
122 #include "src/strings/char-predicates-inl.h"
123 #include "src/strings/string-hasher.h"
124 #include "src/strings/unicode-inl.h"
125 #include "src/tracing/trace-event.h"
126 #include "src/utils/detachable-vector.h"
127 #include "src/utils/version.h"
128 #include "src/web-snapshot/web-snapshot.h"
129
130 #if V8_ENABLE_WEBASSEMBLY
131 #include "src/trap-handler/trap-handler.h"
132 #include "src/wasm/streaming-decoder.h"
133 #include "src/wasm/value-type.h"
134 #include "src/wasm/wasm-engine.h"
135 #include "src/wasm/wasm-js.h"
136 #include "src/wasm/wasm-objects-inl.h"
137 #include "src/wasm/wasm-result.h"
138 #include "src/wasm/wasm-serialization.h"
139 #endif // V8_ENABLE_WEBASSEMBLY
140
141 #if V8_OS_LINUX || V8_OS_DARWIN || V8_OS_FREEBSD
142 #include <signal.h>
143 #include "include/v8-wasm-trap-handler-posix.h"
144 #include "src/trap-handler/handler-inside-posix.h"
145 #endif
146
147 #if V8_OS_WIN
148 #include <windows.h>
149
150 // This has to come after windows.h.
151 #include <versionhelpers.h>
152
153 #include "include/v8-wasm-trap-handler-win.h"
154 #include "src/trap-handler/handler-inside-win.h"
155 #if defined(V8_OS_WIN64)
156 #include "src/base/platform/wrappers.h"
157 #include "src/diagnostics/unwinding-info-win64.h"
158 #endif // V8_OS_WIN64
159 #endif // V8_OS_WIN
160
161 // Has to be the last include (doesn't have include guards):
162 #include "src/api/api-macros.h"
163
164 #define TRACE_BS(...) \
165 do { \
166 if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \
167 } while (false)
168
169 namespace v8 {
170
171 static OOMErrorCallback g_oom_error_callback = nullptr;
172
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)173 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
174 i::Handle<i::Script> script) {
175 i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
176 i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
177 i::Handle<i::Object> host_defined_options(script->host_defined_options(),
178 isolate);
179 ScriptOriginOptions options(script->origin_options());
180 bool is_wasm = false;
181 #if V8_ENABLE_WEBASSEMBLY
182 is_wasm = script->type() == i::Script::TYPE_WASM;
183 #endif // V8_ENABLE_WEBASSEMBLY
184 v8::ScriptOrigin origin(
185 reinterpret_cast<v8::Isolate*>(isolate), Utils::ToLocal(scriptName),
186 script->line_offset(), script->column_offset(),
187 options.IsSharedCrossOrigin(), script->id(),
188 Utils::ToLocal(source_map_url), options.IsOpaque(), is_wasm,
189 options.IsModule(), Utils::ToLocal(host_defined_options));
190 return origin;
191 }
192
HostDefinedOptions() const193 Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
194 // TODO(cbruni, chromium:1244145): remove once migrated to the context.
195 Utils::ApiCheck(!host_defined_options_->IsFixedArray(),
196 "ScriptOrigin::HostDefinedOptions",
197 "HostDefinedOptions is not a PrimitiveArray, please use "
198 "ScriptOrigin::GetHostDefinedOptions()");
199 i::Handle<i::FixedArray> options =
200 Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
201 return Utils::PrimitiveArrayToLocal(options);
202 }
203
204 // --- E x c e p t i o n B e h a v i o r ---
205
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location)206 void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
207 i::V8::FatalProcessOutOfMemory(isolate, location, false);
208 }
209
210 // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
211 // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location,bool is_heap_oom)212 void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
213 bool is_heap_oom) {
214 char last_few_messages[Heap::kTraceRingBufferSize + 1];
215 char js_stacktrace[Heap::kStacktraceBufferSize + 1];
216 i::HeapStats heap_stats;
217
218 if (isolate == nullptr) {
219 isolate = Isolate::TryGetCurrent();
220 }
221
222 if (isolate == nullptr) {
223 // If the Isolate is not available for the current thread we cannot retrieve
224 // memory information from the Isolate. Write easy-to-recognize values on
225 // the stack.
226 memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
227 memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
228 memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
229 // Give the embedder a chance to handle the condition. If it doesn't,
230 // just crash.
231 if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
232 FATAL("Fatal process out of memory: %s", location);
233 UNREACHABLE();
234 }
235
236 memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
237 memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
238
239 intptr_t start_marker;
240 heap_stats.start_marker = &start_marker;
241 size_t ro_space_size;
242 heap_stats.ro_space_size = &ro_space_size;
243 size_t ro_space_capacity;
244 heap_stats.ro_space_capacity = &ro_space_capacity;
245 size_t new_space_size;
246 heap_stats.new_space_size = &new_space_size;
247 size_t new_space_capacity;
248 heap_stats.new_space_capacity = &new_space_capacity;
249 size_t old_space_size;
250 heap_stats.old_space_size = &old_space_size;
251 size_t old_space_capacity;
252 heap_stats.old_space_capacity = &old_space_capacity;
253 size_t code_space_size;
254 heap_stats.code_space_size = &code_space_size;
255 size_t code_space_capacity;
256 heap_stats.code_space_capacity = &code_space_capacity;
257 size_t map_space_size;
258 heap_stats.map_space_size = &map_space_size;
259 size_t map_space_capacity;
260 heap_stats.map_space_capacity = &map_space_capacity;
261 size_t lo_space_size;
262 heap_stats.lo_space_size = &lo_space_size;
263 size_t code_lo_space_size;
264 heap_stats.code_lo_space_size = &code_lo_space_size;
265 size_t global_handle_count;
266 heap_stats.global_handle_count = &global_handle_count;
267 size_t weak_global_handle_count;
268 heap_stats.weak_global_handle_count = &weak_global_handle_count;
269 size_t pending_global_handle_count;
270 heap_stats.pending_global_handle_count = &pending_global_handle_count;
271 size_t near_death_global_handle_count;
272 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
273 size_t free_global_handle_count;
274 heap_stats.free_global_handle_count = &free_global_handle_count;
275 size_t memory_allocator_size;
276 heap_stats.memory_allocator_size = &memory_allocator_size;
277 size_t memory_allocator_capacity;
278 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
279 size_t malloced_memory;
280 heap_stats.malloced_memory = &malloced_memory;
281 size_t malloced_peak_memory;
282 heap_stats.malloced_peak_memory = &malloced_peak_memory;
283 size_t objects_per_type[LAST_TYPE + 1] = {0};
284 heap_stats.objects_per_type = objects_per_type;
285 size_t size_per_type[LAST_TYPE + 1] = {0};
286 heap_stats.size_per_type = size_per_type;
287 int os_error;
288 heap_stats.os_error = &os_error;
289 heap_stats.last_few_messages = last_few_messages;
290 heap_stats.js_stacktrace = js_stacktrace;
291 intptr_t end_marker;
292 heap_stats.end_marker = &end_marker;
293 if (isolate->heap()->HasBeenSetUp()) {
294 // BUG(1718): Don't use the take_snapshot since we don't support
295 // HeapObjectIterator here without doing a special GC.
296 isolate->heap()->RecordStats(&heap_stats, false);
297 if (!FLAG_correctness_fuzzer_suppressions) {
298 char* first_newline = strchr(last_few_messages, '\n');
299 if (first_newline == nullptr || first_newline[1] == '\0')
300 first_newline = last_few_messages;
301 base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline);
302 base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
303 }
304 }
305 Utils::ReportOOMFailure(isolate, location, is_heap_oom);
306 if (g_oom_error_callback) g_oom_error_callback(location, is_heap_oom);
307 // If the fatal error handler returns, we stop execution.
308 FATAL("API fatal error handler returned after process out of memory");
309 }
310
ReportApiFailure(const char * location,const char * message)311 void Utils::ReportApiFailure(const char* location, const char* message) {
312 i::Isolate* isolate = i::Isolate::TryGetCurrent();
313 FatalErrorCallback callback = nullptr;
314 if (isolate != nullptr) {
315 callback = isolate->exception_behavior();
316 }
317 if (callback == nullptr) {
318 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
319 message);
320 base::OS::Abort();
321 } else {
322 callback(location, message);
323 }
324 isolate->SignalFatalError();
325 }
326
ReportOOMFailure(i::Isolate * isolate,const char * location,bool is_heap_oom)327 void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location,
328 bool is_heap_oom) {
329 OOMErrorCallback oom_callback = isolate->oom_behavior();
330 if (oom_callback == nullptr) {
331 // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
332 // crbug.com/614440.
333 FatalErrorCallback fatal_callback = isolate->exception_behavior();
334 if (fatal_callback == nullptr) {
335 base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
336 is_heap_oom ? "javascript" : "process", location);
337 #ifdef V8_FUZZILLI
338 exit(0);
339 #else
340 base::OS::Abort();
341 #endif // V8_FUZZILLI
342 } else {
343 fatal_callback(location,
344 is_heap_oom
345 ? "Allocation failed - JavaScript heap out of memory"
346 : "Allocation failed - process out of memory");
347 }
348 } else {
349 oom_callback(location, is_heap_oom);
350 }
351 isolate->SignalFatalError();
352 }
353
SetSnapshotDataBlob(StartupData * snapshot_blob)354 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
355 i::V8::SetSnapshotBlob(snapshot_blob);
356 }
357
358 namespace {
359
360 #ifdef V8_SANDBOXED_POINTERS
361 // ArrayBufferAllocator to use when sandboxed pointers are used in which case
362 // all ArrayBuffer backing stores need to be allocated inside the sandbox.
363 // Note, the current implementation is extremely inefficient as it uses the
364 // BoundedPageAllocator. In the future, we'll need a proper allocator
365 // implementation.
366 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
367 public:
ArrayBufferAllocator()368 ArrayBufferAllocator() { CHECK(page_allocator_); }
369
Allocate(size_t length)370 void* Allocate(size_t length) override {
371 return page_allocator_->AllocatePages(nullptr, RoundUp(length, page_size_),
372 page_size_,
373 PageAllocator::kReadWrite);
374 }
375
AllocateUninitialized(size_t length)376 void* AllocateUninitialized(size_t length) override {
377 return Allocate(length);
378 }
379
Free(void * data,size_t length)380 void Free(void* data, size_t length) override {
381 page_allocator_->FreePages(data, RoundUp(length, page_size_));
382 }
383
384 private:
385 PageAllocator* page_allocator_ = internal::GetArrayBufferPageAllocator();
386 const size_t page_size_ = page_allocator_->AllocatePageSize();
387 };
388
389 #else
390
391 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
392 public:
393 void* Allocate(size_t length) override {
394 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
395 // Work around for GCC bug on AIX
396 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
397 void* data = __linux_calloc(length, 1);
398 #else
399 void* data = base::Calloc(length, 1);
400 #endif
401 return data;
402 }
403
404 void* AllocateUninitialized(size_t length) override {
405 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
406 // Work around for GCC bug on AIX
407 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
408 void* data = __linux_malloc(length);
409 #else
410 void* data = base::Malloc(length);
411 #endif
412 return data;
413 }
414
415 void Free(void* data, size_t) override { base::Free(data); }
416
417 void* Reallocate(void* data, size_t old_length, size_t new_length) override {
418 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
419 // Work around for GCC bug on AIX
420 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
421 void* new_data = __linux_realloc(data, new_length);
422 #else
423 void* new_data = base::Realloc(data, new_length);
424 #endif
425 if (new_length > old_length) {
426 memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0,
427 new_length - old_length);
428 }
429 return new_data;
430 }
431 };
432 #endif // V8_SANDBOXED_POINTERS
433
434 struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anon4d9620be0111::SnapshotCreatorData435 explicit SnapshotCreatorData(Isolate* isolate)
436 : isolate_(isolate),
437 default_context_(),
438 contexts_(isolate),
439 created_(false) {}
440
castv8::__anon4d9620be0111::SnapshotCreatorData441 static SnapshotCreatorData* cast(void* data) {
442 return reinterpret_cast<SnapshotCreatorData*>(data);
443 }
444
445 ArrayBufferAllocator allocator_;
446 Isolate* isolate_;
447 Persistent<Context> default_context_;
448 SerializeInternalFieldsCallback default_embedder_fields_serializer_;
449 PersistentValueVector<Context> contexts_;
450 std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
451 bool created_;
452 };
453
454 } // namespace
455
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)456 SnapshotCreator::SnapshotCreator(Isolate* isolate,
457 const intptr_t* external_references,
458 StartupData* existing_snapshot) {
459 SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
460 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
461 internal_isolate->set_array_buffer_allocator(&data->allocator_);
462 internal_isolate->set_api_external_references(external_references);
463 internal_isolate->enable_serializer();
464 isolate->Enter();
465 const StartupData* blob = existing_snapshot
466 ? existing_snapshot
467 : i::Snapshot::DefaultSnapshotBlob();
468 if (blob && blob->raw_size > 0) {
469 internal_isolate->set_snapshot_blob(blob);
470 i::Snapshot::Initialize(internal_isolate);
471 } else {
472 internal_isolate->InitWithoutSnapshot();
473 }
474 data_ = data;
475 // Disable batch compilation during snapshot creation.
476 internal_isolate->baseline_batch_compiler()->set_enabled(false);
477 }
478
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)479 SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
480 StartupData* existing_snapshot)
481 : SnapshotCreator(Isolate::Allocate(), external_references,
482 existing_snapshot) {}
483
~SnapshotCreator()484 SnapshotCreator::~SnapshotCreator() {
485 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
486 Isolate* isolate = data->isolate_;
487 isolate->Exit();
488 isolate->Dispose();
489 delete data;
490 }
491
GetIsolate()492 Isolate* SnapshotCreator::GetIsolate() {
493 return SnapshotCreatorData::cast(data_)->isolate_;
494 }
495
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)496 void SnapshotCreator::SetDefaultContext(
497 Local<Context> context, SerializeInternalFieldsCallback callback) {
498 DCHECK(!context.IsEmpty());
499 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
500 DCHECK(!data->created_);
501 DCHECK(data->default_context_.IsEmpty());
502 Isolate* isolate = data->isolate_;
503 CHECK_EQ(isolate, context->GetIsolate());
504 data->default_context_.Reset(isolate, context);
505 data->default_embedder_fields_serializer_ = callback;
506 }
507
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)508 size_t SnapshotCreator::AddContext(Local<Context> context,
509 SerializeInternalFieldsCallback callback) {
510 DCHECK(!context.IsEmpty());
511 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
512 DCHECK(!data->created_);
513 Isolate* isolate = data->isolate_;
514 CHECK_EQ(isolate, context->GetIsolate());
515 size_t index = data->contexts_.Size();
516 data->contexts_.Append(context);
517 data->embedder_fields_serializers_.push_back(callback);
518 return index;
519 }
520
AddData(i::Address object)521 size_t SnapshotCreator::AddData(i::Address object) {
522 DCHECK_NE(object, i::kNullAddress);
523 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
524 DCHECK(!data->created_);
525 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
526 i::HandleScope scope(isolate);
527 i::Handle<i::Object> obj(i::Object(object), isolate);
528 i::Handle<i::ArrayList> list;
529 if (!isolate->heap()->serialized_objects().IsArrayList()) {
530 list = i::ArrayList::New(isolate, 1);
531 } else {
532 list = i::Handle<i::ArrayList>(
533 i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
534 }
535 size_t index = static_cast<size_t>(list->Length());
536 list = i::ArrayList::Add(isolate, list, obj);
537 isolate->heap()->SetSerializedObjects(*list);
538 return index;
539 }
540
AddData(Local<Context> context,i::Address object)541 size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
542 DCHECK_NE(object, i::kNullAddress);
543 DCHECK(!SnapshotCreatorData::cast(data_)->created_);
544 i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
545 i::Isolate* isolate = ctx->GetIsolate();
546 i::HandleScope scope(isolate);
547 i::Handle<i::Object> obj(i::Object(object), isolate);
548 i::Handle<i::ArrayList> list;
549 if (!ctx->serialized_objects().IsArrayList()) {
550 list = i::ArrayList::New(isolate, 1);
551 } else {
552 list = i::Handle<i::ArrayList>(
553 i::ArrayList::cast(ctx->serialized_objects()), isolate);
554 }
555 size_t index = static_cast<size_t>(list->Length());
556 list = i::ArrayList::Add(isolate, list, obj);
557 ctx->set_serialized_objects(*list);
558 return index;
559 }
560
561 namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)562 void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
563 i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
564 i::Isolate* isolate = ctx->GetIsolate();
565 if (!ctx->serialized_objects().IsArrayList()) {
566 ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
567 } else {
568 i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
569 isolate);
570 i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
571 ctx->set_serialized_objects(*elements);
572 }
573 }
574
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)575 void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
576 if (!isolate->heap()->serialized_objects().IsArrayList()) {
577 isolate->heap()->SetSerializedObjects(
578 i::ReadOnlyRoots(isolate).empty_fixed_array());
579 } else {
580 i::Handle<i::ArrayList> list(
581 i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
582 i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
583 isolate->heap()->SetSerializedObjects(*elements);
584 }
585 }
586 } // anonymous namespace
587
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)588 StartupData SnapshotCreator::CreateBlob(
589 SnapshotCreator::FunctionCodeHandling function_code_handling) {
590 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
591 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
592 Utils::ApiCheck(!data->created_, "v8::SnapshotCreator::CreateBlob",
593 "CreateBlob() cannot be called more than once on the same "
594 "SnapshotCreator.");
595 Utils::ApiCheck(
596 !data->default_context_.IsEmpty(), "v8::SnapshotCreator::CreateBlob",
597 "CreateBlob() cannot be called before the default context is set.");
598
599 const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
600 const int num_contexts = num_additional_contexts + 1; // The default context.
601
602 // Create and store lists of embedder-provided data needed during
603 // serialization.
604 {
605 i::HandleScope scope(isolate);
606 // Convert list of context-independent data to FixedArray.
607 ConvertSerializedObjectsToFixedArray(isolate);
608
609 // Convert lists of context-dependent data to FixedArray.
610 ConvertSerializedObjectsToFixedArray(
611 data->default_context_.Get(data->isolate_));
612 for (int i = 0; i < num_additional_contexts; i++) {
613 ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
614 }
615
616 // We need to store the global proxy size upfront in case we need the
617 // bootstrapper to create a global proxy before we deserialize the context.
618 i::Handle<i::FixedArray> global_proxy_sizes =
619 isolate->factory()->NewFixedArray(num_additional_contexts,
620 i::AllocationType::kOld);
621 for (int i = 0; i < num_additional_contexts; i++) {
622 i::Handle<i::Context> context =
623 v8::Utils::OpenHandle(*data->contexts_.Get(i));
624 global_proxy_sizes->set(i,
625 i::Smi::FromInt(context->global_proxy().Size()));
626 }
627 isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
628 }
629
630 // We might rehash strings and re-sort descriptors. Clear the lookup cache.
631 isolate->descriptor_lookup_cache()->Clear();
632
633 // If we don't do this then we end up with a stray root pointing at the
634 // context even after we have disposed of the context.
635 isolate->heap()->CollectAllAvailableGarbage(
636 i::GarbageCollectionReason::kSnapshotCreator);
637 {
638 i::HandleScope scope(isolate);
639 isolate->heap()->CompactWeakArrayLists();
640 }
641
642 i::Snapshot::ClearReconstructableDataForSerialization(
643 isolate, function_code_handling == FunctionCodeHandling::kClear);
644
645 i::GlobalSafepointScope global_safepoint(isolate);
646 i::DisallowGarbageCollection no_gc_from_here_on;
647
648 // Create a vector with all contexts and clear associated Persistent fields.
649 // Note these contexts may be dead after calling Clear(), but will not be
650 // collected until serialization completes and the DisallowGarbageCollection
651 // scope above goes out of scope.
652 std::vector<i::Context> contexts;
653 contexts.reserve(num_contexts);
654 {
655 i::HandleScope scope(isolate);
656 contexts.push_back(
657 *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
658 data->default_context_.Reset();
659 for (int i = 0; i < num_additional_contexts; i++) {
660 i::Handle<i::Context> context =
661 v8::Utils::OpenHandle(*data->contexts_.Get(i));
662 contexts.push_back(*context);
663 }
664 data->contexts_.Clear();
665 }
666
667 // Check that values referenced by global/eternal handles are accounted for.
668 i::SerializedHandleChecker handle_checker(isolate, &contexts);
669 CHECK(handle_checker.CheckGlobalAndEternalHandles());
670
671 // Create a vector with all embedder fields serializers.
672 std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
673 embedder_fields_serializers.reserve(num_contexts);
674 embedder_fields_serializers.push_back(
675 data->default_embedder_fields_serializer_);
676 for (int i = 0; i < num_additional_contexts; i++) {
677 embedder_fields_serializers.push_back(
678 data->embedder_fields_serializers_[i]);
679 }
680
681 data->created_ = true;
682 return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
683 global_safepoint, no_gc_from_here_on);
684 }
685
CanBeRehashed() const686 bool StartupData::CanBeRehashed() const {
687 DCHECK(i::Snapshot::VerifyChecksum(this));
688 return i::Snapshot::ExtractRehashability(this);
689 }
690
IsValid() const691 bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
692
SetDcheckErrorHandler(DcheckErrorCallback that)693 void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
694 v8::base::SetDcheckFunction(that);
695 }
696
SetFlagsFromString(const char * str)697 void V8::SetFlagsFromString(const char* str) {
698 SetFlagsFromString(str, strlen(str));
699 }
700
SetFlagsFromString(const char * str,size_t length)701 void V8::SetFlagsFromString(const char* str, size_t length) {
702 i::FlagList::SetFlagsFromString(str, length);
703 i::FlagList::EnforceFlagImplications();
704 }
705
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)706 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
707 using HelpOptions = i::FlagList::HelpOptions;
708 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
709 HelpOptions(HelpOptions::kDontExit));
710 }
711
712 RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
713
RegisteredExtension(std::unique_ptr<Extension> extension)714 RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
715 : extension_(std::move(extension)) {}
716
717 // static
Register(std::unique_ptr<Extension> extension)718 void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
719 RegisteredExtension* new_extension =
720 new RegisteredExtension(std::move(extension));
721 new_extension->next_ = first_extension_;
722 first_extension_ = new_extension;
723 }
724
725 // static
UnregisterAll()726 void RegisteredExtension::UnregisterAll() {
727 RegisteredExtension* re = first_extension_;
728 while (re != nullptr) {
729 RegisteredExtension* next = re->next();
730 delete re;
731 re = next;
732 }
733 first_extension_ = nullptr;
734 }
735
736 namespace {
737 class ExtensionResource : public String::ExternalOneByteStringResource {
738 public:
ExtensionResource()739 ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)740 ExtensionResource(const char* data, size_t length)
741 : data_(data), length_(length) {}
data() const742 const char* data() const override { return data_; }
length() const743 size_t length() const override { return length_; }
Dispose()744 void Dispose() override {}
745
746 private:
747 const char* data_;
748 size_t length_;
749 };
750 } // anonymous namespace
751
RegisterExtension(std::unique_ptr<Extension> extension)752 void RegisterExtension(std::unique_ptr<Extension> extension) {
753 RegisteredExtension::Register(std::move(extension));
754 }
755
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)756 Extension::Extension(const char* name, const char* source, int dep_count,
757 const char** deps, int source_length)
758 : name_(name),
759 source_length_(source_length >= 0
760 ? source_length
761 : (source ? static_cast<int>(strlen(source)) : 0)),
762 dep_count_(dep_count),
763 deps_(deps),
764 auto_enable_(false) {
765 source_ = new ExtensionResource(source, source_length_);
766 CHECK(source != nullptr || source_length_ == 0);
767 }
768
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)769 void ResourceConstraints::ConfigureDefaultsFromHeapSize(
770 size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
771 CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
772 if (maximum_heap_size_in_bytes == 0) {
773 return;
774 }
775 size_t young_generation, old_generation;
776 i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
777 &young_generation, &old_generation);
778 set_max_young_generation_size_in_bytes(
779 std::max(young_generation, i::Heap::MinYoungGenerationSize()));
780 set_max_old_generation_size_in_bytes(
781 std::max(old_generation, i::Heap::MinOldGenerationSize()));
782 if (initial_heap_size_in_bytes > 0) {
783 i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
784 &young_generation, &old_generation);
785 // We do not set lower bounds for the initial sizes.
786 set_initial_young_generation_size_in_bytes(young_generation);
787 set_initial_old_generation_size_in_bytes(old_generation);
788 }
789 if (i::kPlatformRequiresCodeRange) {
790 set_code_range_size_in_bytes(
791 std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
792 }
793 }
794
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)795 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
796 uint64_t virtual_memory_limit) {
797 size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
798 size_t young_generation, old_generation;
799 i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
800 &old_generation);
801 set_max_young_generation_size_in_bytes(young_generation);
802 set_max_old_generation_size_in_bytes(old_generation);
803
804 if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
805 set_code_range_size_in_bytes(
806 std::min(i::kMaximalCodeRangeSize,
807 static_cast<size_t>(virtual_memory_limit / 8)));
808 }
809 }
810
811 namespace internal {
812
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,GlobalHandleStoreMode store_mode)813 i::Address* GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
814 internal::Address* slot,
815 GlobalHandleStoreMode store_mode) {
816 API_RCS_SCOPE(isolate, TracedGlobal, New);
817 #ifdef DEBUG
818 Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
819 "the address slot must be not null");
820 #endif
821 i::Handle<i::Object> result =
822 isolate->global_handles()->CreateTraced(*obj, slot, store_mode);
823 #ifdef VERIFY_HEAP
824 if (i::FLAG_verify_heap) {
825 i::Object(*obj).ObjectVerify(isolate);
826 }
827 #endif // VERIFY_HEAP
828 return result.location();
829 }
830
MoveTracedReference(internal::Address ** from,internal::Address ** to)831 void MoveTracedReference(internal::Address** from, internal::Address** to) {
832 GlobalHandles::MoveTracedReference(from, to);
833 }
834
CopyTracedReference(const internal::Address * const * from,internal::Address ** to)835 void CopyTracedReference(const internal::Address* const* from,
836 internal::Address** to) {
837 GlobalHandles::CopyTracedReference(from, to);
838 }
839
DisposeTracedReference(internal::Address * location)840 void DisposeTracedReference(internal::Address* location) {
841 GlobalHandles::DestroyTracedReference(location);
842 }
843
844 } // namespace internal
845
846 namespace api_internal {
847
GlobalizeReference(i::Isolate * isolate,i::Address * obj)848 i::Address* GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
849 API_RCS_SCOPE(isolate, Persistent, New);
850 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
851 #ifdef VERIFY_HEAP
852 if (i::FLAG_verify_heap) {
853 i::Object(*obj).ObjectVerify(isolate);
854 }
855 #endif // VERIFY_HEAP
856 return result.location();
857 }
858
CopyGlobalReference(i::Address * from)859 i::Address* CopyGlobalReference(i::Address* from) {
860 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
861 return result.location();
862 }
863
MoveGlobalReference(internal::Address ** from,internal::Address ** to)864 void MoveGlobalReference(internal::Address** from, internal::Address** to) {
865 i::GlobalHandles::MoveGlobal(from, to);
866 }
867
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)868 void MakeWeak(i::Address* location, void* parameter,
869 WeakCallbackInfo<void>::Callback weak_callback,
870 WeakCallbackType type) {
871 i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
872 }
873
MakeWeak(i::Address ** location_addr)874 void MakeWeak(i::Address** location_addr) {
875 i::GlobalHandles::MakeWeak(location_addr);
876 }
877
ClearWeak(i::Address * location)878 void* ClearWeak(i::Address* location) {
879 return i::GlobalHandles::ClearWeakness(location);
880 }
881
AnnotateStrongRetainer(i::Address * location,const char * label)882 void AnnotateStrongRetainer(i::Address* location, const char* label) {
883 i::GlobalHandles::AnnotateStrongRetainer(location, label);
884 }
885
DisposeGlobal(i::Address * location)886 void DisposeGlobal(i::Address* location) {
887 i::GlobalHandles::Destroy(location);
888 }
889
Eternalize(Isolate * v8_isolate,Value * value)890 Value* Eternalize(Isolate* v8_isolate, Value* value) {
891 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
892 i::Object object = *Utils::OpenHandle(value);
893 int index = -1;
894 isolate->eternal_handles()->Create(isolate, object, &index);
895 return reinterpret_cast<Value*>(
896 isolate->eternal_handles()->Get(index).location());
897 }
898
FromJustIsNothing()899 void FromJustIsNothing() {
900 Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
901 }
902
ToLocalEmpty()903 void ToLocalEmpty() {
904 Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
905 }
906
InternalFieldOutOfBounds(int index)907 void InternalFieldOutOfBounds(int index) {
908 Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
909 "WeakCallbackInfo::GetInternalField",
910 "Internal field out of bounds.");
911 }
912
913 } // namespace api_internal
914
915 // --- H a n d l e s ---
916
HandleScope(Isolate * isolate)917 HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
918
Initialize(Isolate * isolate)919 void HandleScope::Initialize(Isolate* isolate) {
920 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
921 // We do not want to check the correct usage of the Locker class all over the
922 // place, so we do it only here: Without a HandleScope, an embedder can do
923 // almost nothing, so it is enough to check in this central place.
924 // We make an exception if the serializer is enabled, which means that the
925 // Isolate is exclusively used to create a snapshot.
926 Utils::ApiCheck(
927 !internal_isolate->was_locker_ever_used() ||
928 internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
929 internal_isolate->serializer_enabled(),
930 "HandleScope::HandleScope",
931 "Entering the V8 API without proper locking in place");
932 i::HandleScopeData* current = internal_isolate->handle_scope_data();
933 isolate_ = internal_isolate;
934 prev_next_ = current->next;
935 prev_limit_ = current->limit;
936 current->level++;
937 }
938
~HandleScope()939 HandleScope::~HandleScope() {
940 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
941 }
942
operator new(size_t)943 void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)944 void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)945 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)946 void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
947
NumberOfHandles(Isolate * isolate)948 int HandleScope::NumberOfHandles(Isolate* isolate) {
949 return i::HandleScope::NumberOfHandles(
950 reinterpret_cast<i::Isolate*>(isolate));
951 }
952
CreateHandle(i::Isolate * isolate,i::Address value)953 i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
954 return i::HandleScope::CreateHandle(isolate, value);
955 }
956
EscapableHandleScope(Isolate * v8_isolate)957 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
958 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
959 escape_slot_ =
960 CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
961 Initialize(v8_isolate);
962 }
963
Escape(i::Address * escape_value)964 i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
965 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
966 Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
967 "EscapableHandleScope::Escape", "Escape value set twice");
968 if (escape_value == nullptr) {
969 *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
970 return nullptr;
971 }
972 *escape_slot_ = *escape_value;
973 return escape_slot_;
974 }
975
operator new(size_t)976 void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)977 void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)978 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)979 void EscapableHandleScope::operator delete[](void*, size_t) {
980 base::OS::Abort();
981 }
982
SealHandleScope(Isolate * isolate)983 SealHandleScope::SealHandleScope(Isolate* isolate)
984 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
985 i::HandleScopeData* current = isolate_->handle_scope_data();
986 prev_limit_ = current->limit;
987 current->limit = current->next;
988 prev_sealed_level_ = current->sealed_level;
989 current->sealed_level = current->level;
990 }
991
~SealHandleScope()992 SealHandleScope::~SealHandleScope() {
993 i::HandleScopeData* current = isolate_->handle_scope_data();
994 DCHECK_EQ(current->next, current->limit);
995 current->limit = prev_limit_;
996 DCHECK_EQ(current->level, current->sealed_level);
997 current->sealed_level = prev_sealed_level_;
998 }
999
operator new(size_t)1000 void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1001 void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1002 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1003 void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1004
IsModule() const1005 bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
IsFixedArray() const1006 bool Data::IsFixedArray() const {
1007 return Utils::OpenHandle(this)->IsFixedArray();
1008 }
1009
IsValue() const1010 bool Data::IsValue() const {
1011 i::DisallowGarbageCollection no_gc;
1012 i::Object self = *Utils::OpenHandle(this);
1013 if (self.IsSmi()) return true;
1014 i::HeapObject heap_object = i::HeapObject::cast(self);
1015 DCHECK(!heap_object.IsTheHole());
1016 if (heap_object.IsSymbol()) {
1017 return !i::Symbol::cast(heap_object).is_private();
1018 }
1019 return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1020 }
1021
IsPrivate() const1022 bool Data::IsPrivate() const {
1023 return Utils::OpenHandle(this)->IsPrivateSymbol();
1024 }
1025
IsObjectTemplate() const1026 bool Data::IsObjectTemplate() const {
1027 return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1028 }
1029
IsFunctionTemplate() const1030 bool Data::IsFunctionTemplate() const {
1031 return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1032 }
1033
IsContext() const1034 bool Data::IsContext() const { return Utils::OpenHandle(this)->IsContext(); }
1035
Enter()1036 void Context::Enter() {
1037 i::Handle<i::Context> env = Utils::OpenHandle(this);
1038 i::Isolate* isolate = env->GetIsolate();
1039 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1040 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1041 impl->EnterContext(*env);
1042 impl->SaveContext(isolate->context());
1043 isolate->set_context(*env);
1044 }
1045
Exit()1046 void Context::Exit() {
1047 i::Handle<i::Context> env = Utils::OpenHandle(this);
1048 i::Isolate* isolate = env->GetIsolate();
1049 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1050 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1051 if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1052 "Cannot exit non-entered context")) {
1053 return;
1054 }
1055 impl->LeaveContext();
1056 isolate->set_context(impl->RestoreContext());
1057 }
1058
BackupIncumbentScope(Local<Context> backup_incumbent_context)1059 Context::BackupIncumbentScope::BackupIncumbentScope(
1060 Local<Context> backup_incumbent_context)
1061 : backup_incumbent_context_(backup_incumbent_context) {
1062 DCHECK(!backup_incumbent_context_.IsEmpty());
1063
1064 i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1065 i::Isolate* isolate = env->GetIsolate();
1066
1067 js_stack_comparable_address_ =
1068 i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1069
1070 prev_ = isolate->top_backup_incumbent_scope();
1071 isolate->set_top_backup_incumbent_scope(this);
1072 }
1073
~BackupIncumbentScope()1074 Context::BackupIncumbentScope::~BackupIncumbentScope() {
1075 i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1076 i::Isolate* isolate = env->GetIsolate();
1077
1078 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1079
1080 isolate->set_top_backup_incumbent_scope(prev_);
1081 }
1082
1083 STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1084
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1085 static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1086 int index, bool can_grow,
1087 const char* location) {
1088 i::Handle<i::Context> env = Utils::OpenHandle(context);
1089 i::Isolate* isolate = env->GetIsolate();
1090 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
1091 bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1092 "Not a native context") &&
1093 Utils::ApiCheck(index >= 0, location, "Negative index");
1094 if (!ok) return i::Handle<i::EmbedderDataArray>();
1095 // TODO(ishell): remove cast once embedder_data slot has a proper type.
1096 i::Handle<i::EmbedderDataArray> data(
1097 i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1098 if (index < data->length()) return data;
1099 if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1100 location, "Index too large")) {
1101 return i::Handle<i::EmbedderDataArray>();
1102 }
1103 data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1104 env->set_embedder_data(*data);
1105 return data;
1106 }
1107
GetNumberOfEmbedderDataFields()1108 uint32_t Context::GetNumberOfEmbedderDataFields() {
1109 i::Handle<i::Context> context = Utils::OpenHandle(this);
1110 ASSERT_NO_SCRIPT_NO_EXCEPTION(context->GetIsolate());
1111 Utils::ApiCheck(context->IsNativeContext(),
1112 "Context::GetNumberOfEmbedderDataFields",
1113 "Not a native context");
1114 // TODO(ishell): remove cast once embedder_data slot has a proper type.
1115 return static_cast<uint32_t>(
1116 i::EmbedderDataArray::cast(context->embedder_data()).length());
1117 }
1118
SlowGetEmbedderData(int index)1119 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1120 const char* location = "v8::Context::GetEmbedderData()";
1121 i::Handle<i::EmbedderDataArray> data =
1122 EmbedderDataFor(this, index, false, location);
1123 if (data.is_null()) return Local<Value>();
1124 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1125 i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1126 isolate);
1127 return Utils::ToLocal(result);
1128 }
1129
SetEmbedderData(int index,v8::Local<Value> value)1130 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1131 const char* location = "v8::Context::SetEmbedderData()";
1132 i::Handle<i::EmbedderDataArray> data =
1133 EmbedderDataFor(this, index, true, location);
1134 if (data.is_null()) return;
1135 i::Handle<i::Object> val = Utils::OpenHandle(*value);
1136 i::EmbedderDataSlot::store_tagged(*data, index, *val);
1137 DCHECK_EQ(*Utils::OpenHandle(*value),
1138 *Utils::OpenHandle(*GetEmbedderData(index)));
1139 }
1140
SlowGetAlignedPointerFromEmbedderData(int index)1141 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1142 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1143 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1144 i::HandleScope handle_scope(isolate);
1145 i::Handle<i::EmbedderDataArray> data =
1146 EmbedderDataFor(this, index, false, location);
1147 if (data.is_null()) return nullptr;
1148 void* result;
1149 Utils::ApiCheck(
1150 i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1151 location, "Pointer is not aligned");
1152 return result;
1153 }
1154
SetAlignedPointerInEmbedderData(int index,void * value)1155 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1156 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1157 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1158 i::Handle<i::EmbedderDataArray> data =
1159 EmbedderDataFor(this, index, true, location);
1160 bool ok =
1161 i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1162 Utils::ApiCheck(ok, location, "Pointer is not aligned");
1163 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1164 }
1165
1166 // --- T e m p l a t e ---
1167
InitializeTemplate(i::TemplateInfo that,int type,bool do_not_cache)1168 static void InitializeTemplate(i::TemplateInfo that, int type,
1169 bool do_not_cache) {
1170 that.set_number_of_properties(0);
1171 that.set_tag(type);
1172 int serial_number =
1173 do_not_cache ? i::TemplateInfo::kDoNotCache : i::TemplateInfo::kUncached;
1174 that.set_serial_number(serial_number);
1175 }
1176
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1177 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1178 v8::PropertyAttribute attribute) {
1179 auto templ = Utils::OpenHandle(this);
1180 i::Isolate* isolate = templ->GetIsolate();
1181 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1182 i::HandleScope scope(isolate);
1183 auto value_obj = Utils::OpenHandle(*value);
1184
1185 Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(),
1186 "v8::Template::Set",
1187 "Invalid value, must be a primitive or a Template");
1188
1189 // The template cache only performs shallow clones, if we set an
1190 // ObjectTemplate as a property value then we can not cache the receiver
1191 // template.
1192 if (value_obj->IsObjectTemplateInfo()) {
1193 templ->set_serial_number(i::TemplateInfo::kDoNotCache);
1194 }
1195
1196 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1197 value_obj,
1198 static_cast<i::PropertyAttributes>(attribute));
1199 }
1200
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1201 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1202 v8::PropertyAttribute attribute) {
1203 Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1204 attribute);
1205 }
1206
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1207 void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1208 v8::Local<FunctionTemplate> getter,
1209 v8::Local<FunctionTemplate> setter,
1210 v8::PropertyAttribute attribute,
1211 v8::AccessControl access_control) {
1212 // TODO(verwaest): Remove |access_control|.
1213 DCHECK_EQ(v8::DEFAULT, access_control);
1214 auto templ = Utils::OpenHandle(this);
1215 auto isolate = templ->GetIsolate();
1216 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1217 DCHECK(!name.IsEmpty());
1218 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1219 i::HandleScope scope(isolate);
1220 i::ApiNatives::AddAccessorProperty(
1221 isolate, templ, Utils::OpenHandle(*name),
1222 Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1223 static_cast<i::PropertyAttributes>(attribute));
1224 }
1225
1226 // --- F u n c t i o n T e m p l a t e ---
InitializeFunctionTemplate(i::FunctionTemplateInfo info,bool do_not_cache)1227 static void InitializeFunctionTemplate(i::FunctionTemplateInfo info,
1228 bool do_not_cache) {
1229 InitializeTemplate(info, Consts::FUNCTION_TEMPLATE, do_not_cache);
1230 info.set_flag(0);
1231 }
1232
1233 static Local<ObjectTemplate> ObjectTemplateNew(
1234 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1235 bool do_not_cache);
1236
PrototypeTemplate()1237 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1238 auto self = Utils::OpenHandle(this);
1239 i::Isolate* i_isolate = self->GetIsolate();
1240 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1241 i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1242 if (result->IsUndefined(i_isolate)) {
1243 // Do not cache prototype objects.
1244 result = Utils::OpenHandle(
1245 *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1246 i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1247 }
1248 return ToApiHandle<ObjectTemplate>(result);
1249 }
1250
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1251 void FunctionTemplate::SetPrototypeProviderTemplate(
1252 Local<FunctionTemplate> prototype_provider) {
1253 auto self = Utils::OpenHandle(this);
1254 i::Isolate* i_isolate = self->GetIsolate();
1255 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1256 i::Handle<i::FunctionTemplateInfo> result =
1257 Utils::OpenHandle(*prototype_provider);
1258 Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
1259 "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1260 "Protoype must be undefined");
1261 Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
1262 "v8::FunctionTemplate::SetPrototypeProviderTemplate",
1263 "Prototype provider must be empty");
1264 i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1265 result);
1266 }
1267
EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,const char * func)1268 static void EnsureNotPublished(i::Handle<i::FunctionTemplateInfo> info,
1269 const char* func) {
1270 DCHECK_IMPLIES(info->instantiated(), info->published());
1271 Utils::ApiCheck(!info->published(), func,
1272 "FunctionTemplate already instantiated");
1273 }
1274
Inherit(v8::Local<FunctionTemplate> value)1275 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1276 auto info = Utils::OpenHandle(this);
1277 EnsureNotPublished(info, "v8::FunctionTemplate::Inherit");
1278 i::Isolate* i_isolate = info->GetIsolate();
1279 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1280 Utils::ApiCheck(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate),
1281 "v8::FunctionTemplate::Inherit",
1282 "Protoype provider must be empty");
1283 i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1284 Utils::OpenHandle(*value));
1285 }
1286
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> (),SideEffectType side_effect_type=SideEffectType::kHasSideEffect,const MemorySpan<const CFunction> & c_function_overloads={},uint8_t instance_type=0,uint8_t allowed_receiver_instance_type_range_start=0,uint8_t allowed_receiver_instance_type_range_end=0)1287 static Local<FunctionTemplate> FunctionTemplateNew(
1288 i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1289 v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1290 bool do_not_cache,
1291 v8::Local<Private> cached_property_name = v8::Local<Private>(),
1292 SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1293 const MemorySpan<const CFunction>& c_function_overloads = {},
1294 uint8_t instance_type = 0,
1295 uint8_t allowed_receiver_instance_type_range_start = 0,
1296 uint8_t allowed_receiver_instance_type_range_end = 0) {
1297 i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1298 i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1299 i::Handle<i::FunctionTemplateInfo> obj =
1300 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1301 {
1302 // Disallow GC until all fields of obj have acceptable types.
1303 i::DisallowGarbageCollection no_gc;
1304 i::FunctionTemplateInfo raw = *obj;
1305 InitializeFunctionTemplate(raw, do_not_cache);
1306 raw.set_length(length);
1307 raw.set_undetectable(false);
1308 raw.set_needs_access_check(false);
1309 raw.set_accept_any_receiver(true);
1310 if (!signature.IsEmpty()) {
1311 raw.set_signature(*Utils::OpenHandle(*signature));
1312 }
1313 raw.set_cached_property_name(
1314 cached_property_name.IsEmpty()
1315 ? i::ReadOnlyRoots(isolate).the_hole_value()
1316 : *Utils::OpenHandle(*cached_property_name));
1317 if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
1318 raw.SetInstanceType(instance_type);
1319 raw.set_allowed_receiver_instance_type_range_start(
1320 allowed_receiver_instance_type_range_start);
1321 raw.set_allowed_receiver_instance_type_range_end(
1322 allowed_receiver_instance_type_range_end);
1323 }
1324 if (callback != nullptr) {
1325 Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1326 c_function_overloads);
1327 }
1328 return Utils::ToLocal(obj);
1329 }
1330
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const CFunction * c_function,uint16_t instance_type,uint16_t allowed_receiver_instance_type_range_start,uint16_t allowed_receiver_instance_type_range_end)1331 Local<FunctionTemplate> FunctionTemplate::New(
1332 Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1333 v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1334 SideEffectType side_effect_type, const CFunction* c_function,
1335 uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
1336 uint16_t allowed_receiver_instance_type_range_end) {
1337 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1338 // Changes to the environment cannot be captured in the snapshot. Expect no
1339 // function templates when the isolate is created for serialization.
1340 API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1341
1342 if (!Utils::ApiCheck(
1343 !c_function || behavior == ConstructorBehavior::kThrow,
1344 "FunctionTemplate::New",
1345 "Fast API calls are not supported for constructor functions.")) {
1346 return Local<FunctionTemplate>();
1347 }
1348
1349 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1350 return FunctionTemplateNew(
1351 i_isolate, callback, data, signature, length, behavior, false,
1352 Local<Private>(), side_effect_type,
1353 c_function ? MemorySpan<const CFunction>{c_function, 1}
1354 : MemorySpan<const CFunction>{},
1355 instance_type, allowed_receiver_instance_type_range_start,
1356 allowed_receiver_instance_type_range_end);
1357 }
1358
NewWithCFunctionOverloads(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1359 Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1360 Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1361 v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1362 SideEffectType side_effect_type,
1363 const MemorySpan<const CFunction>& c_function_overloads) {
1364 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1365 API_RCS_SCOPE(i_isolate, FunctionTemplate, New);
1366
1367 if (!Utils::ApiCheck(
1368 c_function_overloads.size() == 0 ||
1369 behavior == ConstructorBehavior::kThrow,
1370 "FunctionTemplate::NewWithCFunctionOverloads",
1371 "Fast API calls are not supported for constructor functions.")) {
1372 return Local<FunctionTemplate>();
1373 }
1374
1375 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1376 return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1377 behavior, false, Local<Private>(),
1378 side_effect_type, c_function_overloads);
1379 }
1380
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1381 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1382 Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1383 Local<Value> data, Local<Signature> signature, int length,
1384 SideEffectType side_effect_type) {
1385 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1386 API_RCS_SCOPE(i_isolate, FunctionTemplate, NewWithCache);
1387 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1388 return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1389 ConstructorBehavior::kAllow, false, cache_property,
1390 side_effect_type);
1391 }
1392
New(Isolate * isolate,Local<FunctionTemplate> receiver)1393 Local<Signature> Signature::New(Isolate* isolate,
1394 Local<FunctionTemplate> receiver) {
1395 return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1396 }
1397
New(Isolate * isolate,Local<FunctionTemplate> receiver)1398 Local<AccessorSignature> AccessorSignature::New(
1399 Isolate* isolate, Local<FunctionTemplate> receiver) {
1400 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1401 }
1402
1403 #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata) \
1404 do { \
1405 i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1406 (obj)->setter(*foreign); \
1407 } while (false)
1408
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const MemorySpan<const CFunction> & c_function_overloads)1409 void FunctionTemplate::SetCallHandler(
1410 FunctionCallback callback, v8::Local<Value> data,
1411 SideEffectType side_effect_type,
1412 const MemorySpan<const CFunction>& c_function_overloads) {
1413 auto info = Utils::OpenHandle(this);
1414 EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
1415 i::Isolate* isolate = info->GetIsolate();
1416 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1417 i::HandleScope scope(isolate);
1418 i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1419 side_effect_type == SideEffectType::kHasNoSideEffect);
1420 SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1421 SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1422 if (data.IsEmpty()) {
1423 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424 }
1425 obj->set_data(*Utils::OpenHandle(*data));
1426 if (c_function_overloads.size() > 0) {
1427 // Stores the data for a sequence of CFunction overloads into a single
1428 // FixedArray, as [address_0, signature_0, ... address_n-1, signature_n-1].
1429 i::Handle<i::FixedArray> function_overloads =
1430 isolate->factory()->NewFixedArray(static_cast<int>(
1431 c_function_overloads.size() *
1432 i::FunctionTemplateInfo::kFunctionOverloadEntrySize));
1433 int function_count = static_cast<int>(c_function_overloads.size());
1434 for (int i = 0; i < function_count; i++) {
1435 const CFunction& c_function = c_function_overloads.data()[i];
1436 i::Handle<i::Object> address =
1437 FromCData(isolate, c_function.GetAddress());
1438 function_overloads->set(
1439 i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i, *address);
1440 i::Handle<i::Object> signature =
1441 FromCData(isolate, c_function.GetTypeInfo());
1442 function_overloads->set(
1443 i::FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1,
1444 *signature);
1445 }
1446 i::FunctionTemplateInfo::SetCFunctionOverloads(isolate, info,
1447 function_overloads);
1448 }
1449 info->set_call_code(*obj, kReleaseStore);
1450 }
1451
1452 namespace {
1453
1454 template <typename Getter, typename Setter>
MakeAccessorInfo(i::Isolate * isolate,v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1455 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1456 i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1457 v8::Local<Value> data, v8::AccessControl settings,
1458 v8::Local<AccessorSignature> signature, bool is_special_data_property,
1459 bool replace_on_access) {
1460 i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1461 SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1462 DCHECK_IMPLIES(replace_on_access,
1463 is_special_data_property && setter == nullptr);
1464 if (is_special_data_property && setter == nullptr) {
1465 setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1466 }
1467 SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1468 i::Address redirected = obj->redirected_getter();
1469 if (redirected != i::kNullAddress) {
1470 SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1471 }
1472
1473 i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1474 if (!accessor_name->IsUniqueName()) {
1475 accessor_name = isolate->factory()->InternalizeString(
1476 i::Handle<i::String>::cast(accessor_name));
1477 }
1478 i::DisallowGarbageCollection no_gc;
1479 i::AccessorInfo raw_obj = *obj;
1480 if (data.IsEmpty()) {
1481 raw_obj.set_data(i::ReadOnlyRoots(isolate).undefined_value());
1482 } else {
1483 raw_obj.set_data(*Utils::OpenHandle(*data));
1484 }
1485 raw_obj.set_name(*accessor_name);
1486 raw_obj.set_is_special_data_property(is_special_data_property);
1487 raw_obj.set_replace_on_access(replace_on_access);
1488 if (settings & ALL_CAN_READ) raw_obj.set_all_can_read(true);
1489 if (settings & ALL_CAN_WRITE) raw_obj.set_all_can_write(true);
1490 raw_obj.set_initial_property_attributes(i::NONE);
1491 if (!signature.IsEmpty()) {
1492 raw_obj.set_expected_receiver_type(*Utils::OpenHandle(*signature));
1493 }
1494 return obj;
1495 }
1496
1497 } // namespace
1498
InstanceTemplate()1499 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1500 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1501 if (!Utils::ApiCheck(!handle.is_null(),
1502 "v8::FunctionTemplate::InstanceTemplate()",
1503 "Reading from empty handle")) {
1504 return Local<ObjectTemplate>();
1505 }
1506 i::Isolate* isolate = handle->GetIsolate();
1507 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1508 if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1509 Local<ObjectTemplate> templ =
1510 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1511 i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1512 Utils::OpenHandle(*templ));
1513 }
1514 i::Handle<i::ObjectTemplateInfo> result(
1515 i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1516 return Utils::ToLocal(result);
1517 }
1518
SetLength(int length)1519 void FunctionTemplate::SetLength(int length) {
1520 auto info = Utils::OpenHandle(this);
1521 EnsureNotPublished(info, "v8::FunctionTemplate::SetLength");
1522 auto isolate = info->GetIsolate();
1523 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1524 info->set_length(length);
1525 }
1526
SetClassName(Local<String> name)1527 void FunctionTemplate::SetClassName(Local<String> name) {
1528 auto info = Utils::OpenHandle(this);
1529 EnsureNotPublished(info, "v8::FunctionTemplate::SetClassName");
1530 auto isolate = info->GetIsolate();
1531 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1532 info->set_class_name(*Utils::OpenHandle(*name));
1533 }
1534
SetAcceptAnyReceiver(bool value)1535 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1536 auto info = Utils::OpenHandle(this);
1537 EnsureNotPublished(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1538 auto isolate = info->GetIsolate();
1539 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1540 info->set_accept_any_receiver(value);
1541 }
1542
ReadOnlyPrototype()1543 void FunctionTemplate::ReadOnlyPrototype() {
1544 auto info = Utils::OpenHandle(this);
1545 EnsureNotPublished(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1546 auto isolate = info->GetIsolate();
1547 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548 info->set_read_only_prototype(true);
1549 }
1550
RemovePrototype()1551 void FunctionTemplate::RemovePrototype() {
1552 auto info = Utils::OpenHandle(this);
1553 EnsureNotPublished(info, "v8::FunctionTemplate::RemovePrototype");
1554 auto isolate = info->GetIsolate();
1555 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1556 info->set_remove_prototype(true);
1557 }
1558
1559 // --- O b j e c t T e m p l a t e ---
1560
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1561 Local<ObjectTemplate> ObjectTemplate::New(
1562 Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1563 return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1564 }
1565
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1566 static Local<ObjectTemplate> ObjectTemplateNew(
1567 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1568 bool do_not_cache) {
1569 API_RCS_SCOPE(isolate, ObjectTemplate, New);
1570 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1571 i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1572 i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1573 i::Handle<i::ObjectTemplateInfo> obj =
1574 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1575 {
1576 // Disallow GC until all fields of obj have acceptable types.
1577 i::DisallowGarbageCollection no_gc;
1578 i::ObjectTemplateInfo raw = *obj;
1579 InitializeTemplate(raw, Consts::OBJECT_TEMPLATE, do_not_cache);
1580 raw.set_data(0);
1581 if (!constructor.IsEmpty()) {
1582 raw.set_constructor(*Utils::OpenHandle(*constructor));
1583 }
1584 }
1585 return Utils::ToLocal(obj);
1586 }
1587
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1588 Local<ObjectTemplate> ObjectTemplate::New(
1589 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1590 return ObjectTemplateNew(isolate, constructor, false);
1591 }
1592
1593 // Ensure that the object template has a constructor. If no
1594 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1595 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1596 i::Isolate* isolate, ObjectTemplate* object_template) {
1597 i::Object obj = Utils::OpenHandle(object_template)->constructor();
1598 if (!obj.IsUndefined(isolate)) {
1599 i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1600 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1601 }
1602 Local<FunctionTemplate> templ =
1603 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1604 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1605 i::FunctionTemplateInfo::SetInstanceTemplate(
1606 isolate, constructor, Utils::OpenHandle(object_template));
1607 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1608 return constructor;
1609 }
1610
1611 template <typename Getter, typename Setter, typename Data, typename Template>
TemplateSetAccessor(Template * template_obj,v8::Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1612 static void TemplateSetAccessor(
1613 Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1614 Data data, AccessControl settings, PropertyAttribute attribute,
1615 v8::Local<AccessorSignature> signature, bool is_special_data_property,
1616 bool replace_on_access, SideEffectType getter_side_effect_type,
1617 SideEffectType setter_side_effect_type) {
1618 auto info = Utils::OpenHandle(template_obj);
1619 auto isolate = info->GetIsolate();
1620 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1621 i::HandleScope scope(isolate);
1622 i::Handle<i::AccessorInfo> accessor_info =
1623 MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1624 is_special_data_property, replace_on_access);
1625 {
1626 i::DisallowGarbageCollection no_gc;
1627 i::AccessorInfo raw = *accessor_info;
1628 raw.set_initial_property_attributes(
1629 static_cast<i::PropertyAttributes>(attribute));
1630 raw.set_getter_side_effect_type(getter_side_effect_type);
1631 raw.set_setter_side_effect_type(setter_side_effect_type);
1632 }
1633 i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1634 }
1635
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1636 void Template::SetNativeDataProperty(v8::Local<String> name,
1637 AccessorGetterCallback getter,
1638 AccessorSetterCallback setter,
1639 v8::Local<Value> data,
1640 PropertyAttribute attribute,
1641 AccessControl settings,
1642 SideEffectType getter_side_effect_type,
1643 SideEffectType setter_side_effect_type) {
1644 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1645 Local<AccessorSignature>(), true, false,
1646 getter_side_effect_type, setter_side_effect_type);
1647 }
1648
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1649 void Template::SetNativeDataProperty(
1650 v8::Local<String> name, AccessorGetterCallback getter,
1651 AccessorSetterCallback setter, v8::Local<Value> data,
1652 PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1653 AccessControl settings, SideEffectType getter_side_effect_type,
1654 SideEffectType setter_side_effect_type) {
1655 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1656 signature, true, false, getter_side_effect_type,
1657 setter_side_effect_type);
1658 }
1659
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1660 void Template::SetNativeDataProperty(v8::Local<Name> name,
1661 AccessorNameGetterCallback getter,
1662 AccessorNameSetterCallback setter,
1663 v8::Local<Value> data,
1664 PropertyAttribute attribute,
1665 AccessControl settings,
1666 SideEffectType getter_side_effect_type,
1667 SideEffectType setter_side_effect_type) {
1668 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1669 Local<AccessorSignature>(), true, false,
1670 getter_side_effect_type, setter_side_effect_type);
1671 }
1672
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1673 void Template::SetNativeDataProperty(
1674 v8::Local<Name> name, AccessorNameGetterCallback getter,
1675 AccessorNameSetterCallback setter, v8::Local<Value> data,
1676 PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1677 AccessControl settings, SideEffectType getter_side_effect_type,
1678 SideEffectType setter_side_effect_type) {
1679 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1680 signature, true, false, getter_side_effect_type,
1681 setter_side_effect_type);
1682 }
1683
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1684 void Template::SetLazyDataProperty(v8::Local<Name> name,
1685 AccessorNameGetterCallback getter,
1686 v8::Local<Value> data,
1687 PropertyAttribute attribute,
1688 SideEffectType getter_side_effect_type,
1689 SideEffectType setter_side_effect_type) {
1690 TemplateSetAccessor(this, name, getter,
1691 static_cast<AccessorNameSetterCallback>(nullptr), data,
1692 DEFAULT, attribute, Local<AccessorSignature>(), true,
1693 true, getter_side_effect_type, setter_side_effect_type);
1694 }
1695
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1696 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1697 PropertyAttribute attribute) {
1698 auto templ = Utils::OpenHandle(this);
1699 i::Isolate* isolate = templ->GetIsolate();
1700 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1701 i::HandleScope scope(isolate);
1702 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1703 intrinsic,
1704 static_cast<i::PropertyAttributes>(attribute));
1705 }
1706
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1707 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1708 AccessorGetterCallback getter,
1709 AccessorSetterCallback setter,
1710 v8::Local<Value> data, AccessControl settings,
1711 PropertyAttribute attribute,
1712 SideEffectType getter_side_effect_type,
1713 SideEffectType setter_side_effect_type) {
1714 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1715 Local<AccessorSignature>(),
1716 i::FLAG_disable_old_api_accessors, false,
1717 getter_side_effect_type, setter_side_effect_type);
1718 }
1719
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1720 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1721 AccessorNameGetterCallback getter,
1722 AccessorNameSetterCallback setter,
1723 v8::Local<Value> data, AccessControl settings,
1724 PropertyAttribute attribute,
1725 SideEffectType getter_side_effect_type,
1726 SideEffectType setter_side_effect_type) {
1727 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1728 Local<AccessorSignature>(),
1729 i::FLAG_disable_old_api_accessors, false,
1730 getter_side_effect_type, setter_side_effect_type);
1731 }
1732
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1733 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1734 AccessorGetterCallback getter,
1735 AccessorSetterCallback setter,
1736 v8::Local<Value> data, AccessControl settings,
1737 PropertyAttribute attribute,
1738 v8::Local<AccessorSignature> signature,
1739 SideEffectType getter_side_effect_type,
1740 SideEffectType setter_side_effect_type) {
1741 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1742 signature, i::FLAG_disable_old_api_accessors, false,
1743 getter_side_effect_type, setter_side_effect_type);
1744 }
1745
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1746 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1747 AccessorNameGetterCallback getter,
1748 AccessorNameSetterCallback setter,
1749 v8::Local<Value> data, AccessControl settings,
1750 PropertyAttribute attribute,
1751 v8::Local<AccessorSignature> signature,
1752 SideEffectType getter_side_effect_type,
1753 SideEffectType setter_side_effect_type) {
1754 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1755 signature, i::FLAG_disable_old_api_accessors, false,
1756 getter_side_effect_type, setter_side_effect_type);
1757 }
1758
1759 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1760 typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1761 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1762 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1763 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1764 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1765 auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1766 i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1767 obj->set_flags(0);
1768
1769 if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1770 if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1771 if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1772 if (descriptor != nullptr)
1773 SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1774 if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1775 if (enumerator != nullptr)
1776 SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1777 if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1778 obj->set_can_intercept_symbols(
1779 !(static_cast<int>(flags) &
1780 static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1781 obj->set_all_can_read(static_cast<int>(flags) &
1782 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1783 obj->set_non_masking(static_cast<int>(flags) &
1784 static_cast<int>(PropertyHandlerFlags::kNonMasking));
1785 obj->set_has_no_side_effect(
1786 static_cast<int>(flags) &
1787 static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1788
1789 if (data.IsEmpty()) {
1790 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1791 }
1792 obj->set_data(*Utils::OpenHandle(*data));
1793 return obj;
1794 }
1795
1796 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1797 typename Deleter, typename Enumerator, typename Definer>
CreateNamedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1798 static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1799 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1800 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1801 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1802 auto interceptor =
1803 CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1804 enumerator, definer, data, flags);
1805 interceptor->set_is_named(true);
1806 return interceptor;
1807 }
1808
1809 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1810 typename Deleter, typename Enumerator, typename Definer>
CreateIndexedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1811 static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1812 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1813 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1814 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1815 auto interceptor =
1816 CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1817 enumerator, definer, data, flags);
1818 interceptor->set_is_named(false);
1819 return interceptor;
1820 }
1821
1822 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1823 typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1824 static void ObjectTemplateSetNamedPropertyHandler(
1825 ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1826 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1827 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1828 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1829 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1830 i::HandleScope scope(isolate);
1831 auto cons = EnsureConstructor(isolate, templ);
1832 EnsureNotPublished(cons, "ObjectTemplateSetNamedPropertyHandler");
1833 auto obj =
1834 CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1835 remover, enumerator, definer, data, flags);
1836 i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1837 }
1838
SetHandler(const NamedPropertyHandlerConfiguration & config)1839 void ObjectTemplate::SetHandler(
1840 const NamedPropertyHandlerConfiguration& config) {
1841 ObjectTemplateSetNamedPropertyHandler(
1842 this, config.getter, config.setter, config.query, config.descriptor,
1843 config.deleter, config.enumerator, config.definer, config.data,
1844 config.flags);
1845 }
1846
MarkAsUndetectable()1847 void ObjectTemplate::MarkAsUndetectable() {
1848 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1849 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1850 i::HandleScope scope(isolate);
1851 auto cons = EnsureConstructor(isolate, this);
1852 EnsureNotPublished(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1853 cons->set_undetectable(true);
1854 }
1855
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1856 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1857 Local<Value> data) {
1858 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1859 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1860 i::HandleScope scope(isolate);
1861 auto cons = EnsureConstructor(isolate, this);
1862 EnsureNotPublished(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1863
1864 i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1865 i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1866 i::Handle<i::AccessCheckInfo> info =
1867 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1868
1869 SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1870 info->set_named_interceptor(i::Object());
1871 info->set_indexed_interceptor(i::Object());
1872
1873 if (data.IsEmpty()) {
1874 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1875 }
1876 info->set_data(*Utils::OpenHandle(*data));
1877
1878 i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1879 cons->set_needs_access_check(true);
1880 }
1881
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1882 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1883 AccessCheckCallback callback,
1884 const NamedPropertyHandlerConfiguration& named_handler,
1885 const IndexedPropertyHandlerConfiguration& indexed_handler,
1886 Local<Value> data) {
1887 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1888 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1889 i::HandleScope scope(isolate);
1890 auto cons = EnsureConstructor(isolate, this);
1891 EnsureNotPublished(cons,
1892 "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1893
1894 i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1895 i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1896 i::Handle<i::AccessCheckInfo> info =
1897 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1898
1899 SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1900 auto named_interceptor = CreateNamedInterceptorInfo(
1901 isolate, named_handler.getter, named_handler.setter, named_handler.query,
1902 named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1903 named_handler.definer, named_handler.data, named_handler.flags);
1904 info->set_named_interceptor(*named_interceptor);
1905 auto indexed_interceptor = CreateIndexedInterceptorInfo(
1906 isolate, indexed_handler.getter, indexed_handler.setter,
1907 indexed_handler.query, indexed_handler.descriptor,
1908 indexed_handler.deleter, indexed_handler.enumerator,
1909 indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1910 info->set_indexed_interceptor(*indexed_interceptor);
1911
1912 if (data.IsEmpty()) {
1913 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1914 }
1915 info->set_data(*Utils::OpenHandle(*data));
1916
1917 i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1918 cons->set_needs_access_check(true);
1919 }
1920
SetHandler(const IndexedPropertyHandlerConfiguration & config)1921 void ObjectTemplate::SetHandler(
1922 const IndexedPropertyHandlerConfiguration& config) {
1923 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1924 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1925 i::HandleScope scope(isolate);
1926 auto cons = EnsureConstructor(isolate, this);
1927 EnsureNotPublished(cons, "v8::ObjectTemplate::SetHandler");
1928 auto obj = CreateIndexedInterceptorInfo(
1929 isolate, config.getter, config.setter, config.query, config.descriptor,
1930 config.deleter, config.enumerator, config.definer, config.data,
1931 config.flags);
1932 i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1933 }
1934
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1935 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1936 Local<Value> data) {
1937 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1938 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1939 i::HandleScope scope(isolate);
1940 auto cons = EnsureConstructor(isolate, this);
1941 EnsureNotPublished(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1942 i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1943 SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1944 SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1945 if (data.IsEmpty()) {
1946 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1947 }
1948 obj->set_data(*Utils::OpenHandle(*data));
1949 i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1950 }
1951
InternalFieldCount() const1952 int ObjectTemplate::InternalFieldCount() const {
1953 return Utils::OpenHandle(this)->embedder_field_count();
1954 }
1955
SetInternalFieldCount(int value)1956 void ObjectTemplate::SetInternalFieldCount(int value) {
1957 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1958 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1959 "v8::ObjectTemplate::SetInternalFieldCount()",
1960 "Invalid embedder field count")) {
1961 return;
1962 }
1963 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1964 if (value > 0) {
1965 // The embedder field count is set by the constructor function's
1966 // construct code, so we ensure that there is a constructor
1967 // function to do the setting.
1968 EnsureConstructor(isolate, this);
1969 }
1970 Utils::OpenHandle(this)->set_embedder_field_count(value);
1971 }
1972
IsImmutableProto() const1973 bool ObjectTemplate::IsImmutableProto() const {
1974 return Utils::OpenHandle(this)->immutable_proto();
1975 }
1976
SetImmutableProto()1977 void ObjectTemplate::SetImmutableProto() {
1978 auto self = Utils::OpenHandle(this);
1979 i::Isolate* isolate = self->GetIsolate();
1980 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1981 self->set_immutable_proto(true);
1982 }
1983
IsCodeLike() const1984 bool ObjectTemplate::IsCodeLike() const {
1985 return Utils::OpenHandle(this)->code_like();
1986 }
1987
SetCodeLike()1988 void ObjectTemplate::SetCodeLike() {
1989 auto self = Utils::OpenHandle(this);
1990 i::Isolate* isolate = self->GetIsolate();
1991 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1992 self->set_code_like(true);
1993 }
1994
1995 // --- S c r i p t s ---
1996
1997 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1998 // JSFunction.
1999
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)2000 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
2001 BufferPolicy buffer_policy_)
2002 : data(data_),
2003 length(length_),
2004 rejected(false),
2005 buffer_policy(buffer_policy_) {}
2006
~CachedData()2007 ScriptCompiler::CachedData::~CachedData() {
2008 if (buffer_policy == BufferOwned) {
2009 delete[] data;
2010 }
2011 }
2012
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)2013 ScriptCompiler::StreamedSource::StreamedSource(
2014 std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2015 : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2016
2017 ScriptCompiler::StreamedSource::~StreamedSource() = default;
2018
BindToCurrentContext()2019 Local<Script> UnboundScript::BindToCurrentContext() {
2020 auto function_info =
2021 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2022 i::Isolate* isolate = function_info->GetIsolate();
2023 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2024 i::Handle<i::JSFunction> function =
2025 i::Factory::JSFunctionBuilder{isolate, function_info,
2026 isolate->native_context()}
2027 .Build();
2028 return ToApiHandle<Script>(function);
2029 }
2030
GetId() const2031 int UnboundScript::GetId() const {
2032 auto function_info = i::SharedFunctionInfo::cast(*Utils::OpenHandle(this));
2033 API_RCS_SCOPE(function_info.GetIsolate(), UnboundScript, GetId);
2034 return i::Script::cast(function_info.script()).id();
2035 }
2036
GetLineNumber(int code_pos)2037 int UnboundScript::GetLineNumber(int code_pos) {
2038 i::Handle<i::SharedFunctionInfo> obj =
2039 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2040 i::Isolate* isolate = obj->GetIsolate();
2041 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2042 API_RCS_SCOPE(isolate, UnboundScript, GetLineNumber);
2043 if (obj->script().IsScript()) {
2044 i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2045 return i::Script::GetLineNumber(script, code_pos);
2046 } else {
2047 return -1;
2048 }
2049 }
2050
GetScriptName()2051 Local<Value> UnboundScript::GetScriptName() {
2052 i::Handle<i::SharedFunctionInfo> obj =
2053 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2054 i::Isolate* isolate = obj->GetIsolate();
2055 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2056 API_RCS_SCOPE(isolate, UnboundScript, GetName);
2057 if (obj->script().IsScript()) {
2058 i::Object name = i::Script::cast(obj->script()).name();
2059 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2060 } else {
2061 return Local<String>();
2062 }
2063 }
2064
GetSourceURL()2065 Local<Value> UnboundScript::GetSourceURL() {
2066 i::Handle<i::SharedFunctionInfo> obj =
2067 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2068 i::Isolate* isolate = obj->GetIsolate();
2069 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2070 API_RCS_SCOPE(isolate, UnboundScript, GetSourceURL);
2071 if (obj->script().IsScript()) {
2072 i::Object url = i::Script::cast(obj->script()).source_url();
2073 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2074 } else {
2075 return Local<String>();
2076 }
2077 }
2078
GetSourceMappingURL()2079 Local<Value> UnboundScript::GetSourceMappingURL() {
2080 i::Handle<i::SharedFunctionInfo> obj =
2081 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2082 i::Isolate* isolate = obj->GetIsolate();
2083 API_RCS_SCOPE(isolate, UnboundScript, GetSourceMappingURL);
2084 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2085 if (obj->script().IsScript()) {
2086 i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2087 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2088 } else {
2089 return Local<String>();
2090 }
2091 }
2092
Run(Local<Context> context)2093 MaybeLocal<Value> Script::Run(Local<Context> context) {
2094 return Run(context, Local<Data>());
2095 }
2096
Run(Local<Context> context,Local<Data> host_defined_options)2097 MaybeLocal<Value> Script::Run(Local<Context> context,
2098 Local<Data> host_defined_options) {
2099 auto v8_isolate = context->GetIsolate();
2100 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2101 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2102 ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2103 InternalEscapableScope);
2104 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2105 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2106 isolate);
2107 i::AggregatingHistogramTimerScope histogram_timer(
2108 isolate->counters()->compile_lazy());
2109 auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2110
2111 // TODO(crbug.com/1193459): remove once ablation study is completed
2112 base::ElapsedTimer timer;
2113 base::TimeDelta delta;
2114 if (i::FLAG_script_delay > 0) {
2115 delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay);
2116 }
2117 if (i::FLAG_script_delay_once > 0 && !isolate->did_run_script_delay()) {
2118 delta = v8::base::TimeDelta::FromMillisecondsD(i::FLAG_script_delay_once);
2119 isolate->set_did_run_script_delay(true);
2120 }
2121 if (i::FLAG_script_delay_fraction > 0.0) {
2122 timer.Start();
2123 } else if (delta.InMicroseconds() > 0) {
2124 timer.Start();
2125 while (timer.Elapsed() < delta) {
2126 // Busy wait.
2127 }
2128 }
2129
2130 if (V8_UNLIKELY(i::FLAG_experimental_web_snapshots)) {
2131 i::Handle<i::HeapObject> maybe_script =
2132 handle(fun->shared().script(), isolate);
2133 if (maybe_script->IsScript() &&
2134 i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
2135 i::WebSnapshotDeserializer deserializer(
2136 reinterpret_cast<i::Isolate*>(v8_isolate),
2137 i::Handle<i::Script>::cast(maybe_script));
2138 deserializer.Deserialize();
2139 RETURN_ON_FAILED_EXECUTION(Value);
2140 Local<Value> result = v8::Undefined(v8_isolate);
2141 RETURN_ESCAPED(result);
2142 }
2143 }
2144
2145 i::Handle<i::Object> receiver = isolate->global_proxy();
2146 // TODO(cbruni, chromium:1244145): Remove once migrated to the context.
2147 i::Handle<i::Object> options(
2148 i::Script::cast(fun->shared().script()).host_defined_options(), isolate);
2149 Local<Value> result;
2150 has_pending_exception = !ToLocal<Value>(
2151 i::Execution::CallScript(isolate, fun, receiver, options), &result);
2152
2153 if (i::FLAG_script_delay_fraction > 0.0) {
2154 delta = v8::base::TimeDelta::FromMillisecondsD(
2155 timer.Elapsed().InMillisecondsF() * i::FLAG_script_delay_fraction);
2156 timer.Restart();
2157 while (timer.Elapsed() < delta) {
2158 // Busy wait.
2159 }
2160 }
2161
2162 RETURN_ON_FAILED_EXECUTION(Value);
2163 RETURN_ESCAPED(result);
2164 }
2165
GetResourceName()2166 Local<Value> ScriptOrModule::GetResourceName() {
2167 i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2168 i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2169 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2170 i::Handle<i::Object> val(obj->resource_name(), isolate);
2171 return ToApiHandle<Value>(val);
2172 }
2173
GetHostDefinedOptions()2174 Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2175 return HostDefinedOptions().As<PrimitiveArray>();
2176 }
2177
HostDefinedOptions()2178 Local<Data> ScriptOrModule::HostDefinedOptions() {
2179 i::Handle<i::ScriptOrModule> obj = Utils::OpenHandle(this);
2180 i::Isolate* isolate = i::GetIsolateFromWritableObject(*obj);
2181 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2182 i::Handle<i::Object> val(obj->host_defined_options(), isolate);
2183 return ToApiHandle<Data>(val);
2184 }
2185
GetUnboundScript()2186 Local<UnboundScript> Script::GetUnboundScript() {
2187 i::DisallowGarbageCollection no_gc;
2188 i::Handle<i::JSFunction> obj = Utils::OpenHandle(this);
2189 i::SharedFunctionInfo sfi = (*obj).shared();
2190 i::Isolate* isolate = sfi.GetIsolate();
2191 return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2192 }
2193
GetResourceName()2194 Local<Value> Script::GetResourceName() {
2195 i::DisallowGarbageCollection no_gc;
2196 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2197 i::SharedFunctionInfo sfi = (*func).shared();
2198 i::Isolate* isolate = func->GetIsolate();
2199 CHECK(sfi.script().IsScript());
2200 return ToApiHandle<Value>(
2201 i::handle(i::Script::cast(sfi.script()).name(), isolate));
2202 }
2203
2204 // static
New(Isolate * v8_isolate,int length)2205 Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2206 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2207 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2208 Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2209 "length must be equal or greater than zero");
2210 i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2211 return ToApiHandle<PrimitiveArray>(array);
2212 }
2213
Length() const2214 int PrimitiveArray::Length() const {
2215 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2216 return array->length();
2217 }
2218
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2219 void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2220 Local<Primitive> item) {
2221 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2222 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2223 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2224 Utils::ApiCheck(index >= 0 && index < array->length(),
2225 "v8::PrimitiveArray::Set",
2226 "index must be greater than or equal to 0 and less than the "
2227 "array length");
2228 i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2229 array->set(index, *i_item);
2230 }
2231
Get(Isolate * v8_isolate,int index)2232 Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2233 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2234 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2235 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2236 Utils::ApiCheck(index >= 0 && index < array->length(),
2237 "v8::PrimitiveArray::Get",
2238 "index must be greater than or equal to 0 and less than the "
2239 "array length");
2240 i::Handle<i::Object> i_item(array->get(index), isolate);
2241 return ToApiHandle<Primitive>(i_item);
2242 }
2243
CheckCast(v8::Data * that)2244 void v8::PrimitiveArray::CheckCast(v8::Data* that) {
2245 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2246 Utils::ApiCheck(
2247 obj->IsFixedArray(), "v8::PrimitiveArray::Cast",
2248 "Value is not a PrimitiveArray. This is a temporary issue, v8::Data and "
2249 "v8::PrimitiveArray will not be compatible in the future.");
2250 }
2251
Length() const2252 int FixedArray::Length() const {
2253 i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2254 return self->length();
2255 }
2256
Get(Local<Context> context,int i) const2257 Local<Data> FixedArray::Get(Local<Context> context, int i) const {
2258 i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
2259 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2260 CHECK_LT(i, self->length());
2261 i::Handle<i::Object> entry(self->get(i), isolate);
2262 return ToApiHandle<Data>(entry);
2263 }
2264
GetSpecifier() const2265 Local<String> ModuleRequest::GetSpecifier() const {
2266 i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2267 i::Isolate* isolate = self->GetIsolate();
2268 return ToApiHandle<String>(i::handle(self->specifier(), isolate));
2269 }
2270
GetSourceOffset() const2271 int ModuleRequest::GetSourceOffset() const {
2272 return Utils::OpenHandle(this)->position();
2273 }
2274
GetImportAssertions() const2275 Local<FixedArray> ModuleRequest::GetImportAssertions() const {
2276 i::Handle<i::ModuleRequest> self = Utils::OpenHandle(this);
2277 i::Isolate* isolate = self->GetIsolate();
2278 return ToApiHandle<FixedArray>(i::handle(self->import_assertions(), isolate));
2279 }
2280
GetStatus() const2281 Module::Status Module::GetStatus() const {
2282 i::Handle<i::Module> self = Utils::OpenHandle(this);
2283 switch (self->status()) {
2284 case i::Module::kUnlinked:
2285 case i::Module::kPreLinking:
2286 return kUninstantiated;
2287 case i::Module::kLinking:
2288 return kInstantiating;
2289 case i::Module::kLinked:
2290 return kInstantiated;
2291 case i::Module::kEvaluating:
2292 case i::Module::kEvaluatingAsync:
2293 return kEvaluating;
2294 case i::Module::kEvaluated:
2295 return kEvaluated;
2296 case i::Module::kErrored:
2297 return kErrored;
2298 }
2299 UNREACHABLE();
2300 }
2301
GetException() const2302 Local<Value> Module::GetException() const {
2303 Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2304 "Module status must be kErrored");
2305 i::Handle<i::Module> self = Utils::OpenHandle(this);
2306 i::Isolate* isolate = self->GetIsolate();
2307 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2308 return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2309 }
2310
GetModuleRequests() const2311 Local<FixedArray> Module::GetModuleRequests() const {
2312 i::Handle<i::Module> self = Utils::OpenHandle(this);
2313 if (self->IsSyntheticModule()) {
2314 // Synthetic modules are leaf nodes in the module graph. They have no
2315 // ModuleRequests.
2316 return ToApiHandle<FixedArray>(
2317 self->GetReadOnlyRoots().empty_fixed_array_handle());
2318 } else {
2319 i::Isolate* isolate = self->GetIsolate();
2320 i::Handle<i::FixedArray> module_requests(
2321 i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2322 isolate);
2323 return ToApiHandle<FixedArray>(module_requests);
2324 }
2325 }
2326
SourceOffsetToLocation(int offset) const2327 Location Module::SourceOffsetToLocation(int offset) const {
2328 i::Handle<i::Module> self = Utils::OpenHandle(this);
2329 i::Isolate* isolate = self->GetIsolate();
2330 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2331 i::HandleScope scope(isolate);
2332 Utils::ApiCheck(
2333 self->IsSourceTextModule(), "v8::Module::SourceOffsetToLocation",
2334 "v8::Module::SourceOffsetToLocation must be used on an SourceTextModule");
2335 i::Handle<i::Script> script(
2336 i::Handle<i::SourceTextModule>::cast(self)->GetScript(), isolate);
2337 i::Script::PositionInfo info;
2338 i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
2339 return v8::Location(info.line, info.column);
2340 }
2341
GetModuleNamespace()2342 Local<Value> Module::GetModuleNamespace() {
2343 Utils::ApiCheck(
2344 GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2345 "v8::Module::GetModuleNamespace must be used on an instantiated module");
2346 i::Handle<i::Module> self = Utils::OpenHandle(this);
2347 auto isolate = self->GetIsolate();
2348 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2349 i::Handle<i::JSModuleNamespace> module_namespace =
2350 i::Module::GetModuleNamespace(isolate, self);
2351 return ToApiHandle<Value>(module_namespace);
2352 }
2353
GetUnboundModuleScript()2354 Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2355 i::Handle<i::Module> self = Utils::OpenHandle(this);
2356 Utils::ApiCheck(
2357 self->IsSourceTextModule(), "v8::Module::GetUnboundModuleScript",
2358 "v8::Module::GetUnboundModuleScript must be used on an SourceTextModule");
2359 auto isolate = self->GetIsolate();
2360 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2361 return ToApiHandle<UnboundModuleScript>(i::handle(
2362 i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2363 isolate));
2364 }
2365
ScriptId() const2366 int Module::ScriptId() const {
2367 i::Module self = *Utils::OpenHandle(this);
2368 Utils::ApiCheck(self.IsSourceTextModule(), "v8::Module::ScriptId",
2369 "v8::Module::ScriptId must be used on an SourceTextModule");
2370 ASSERT_NO_SCRIPT_NO_EXCEPTION(self.GetIsolate());
2371 return i::SourceTextModule::cast(self).GetScript().id();
2372 }
2373
IsGraphAsync() const2374 bool Module::IsGraphAsync() const {
2375 Utils::ApiCheck(
2376 GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2377 "v8::Module::IsGraphAsync must be used on an instantiated module");
2378 i::Module self = *Utils::OpenHandle(this);
2379 auto isolate = self.GetIsolate();
2380 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2381 return self.IsGraphAsync(isolate);
2382 }
2383
IsSourceTextModule() const2384 bool Module::IsSourceTextModule() const {
2385 return Utils::OpenHandle(this)->IsSourceTextModule();
2386 }
2387
IsSyntheticModule() const2388 bool Module::IsSyntheticModule() const {
2389 return Utils::OpenHandle(this)->IsSyntheticModule();
2390 }
2391
GetIdentityHash() const2392 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2393
InstantiateModule(Local<Context> context,Module::ResolveModuleCallback callback)2394 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2395 Module::ResolveModuleCallback callback) {
2396 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2397 ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2398 i::HandleScope);
2399 has_pending_exception = !i::Module::Instantiate(
2400 isolate, Utils::OpenHandle(this), context, callback, nullptr);
2401 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2402 return Just(true);
2403 }
2404
Evaluate(Local<Context> context)2405 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2406 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2407 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2408 ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2409 InternalEscapableScope);
2410 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2411 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
2412 isolate);
2413 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2414
2415 i::Handle<i::Module> self = Utils::OpenHandle(this);
2416 Utils::ApiCheck(self->status() >= i::Module::kLinked, "Module::Evaluate",
2417 "Expected instantiated module");
2418
2419 Local<Value> result;
2420 has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2421 RETURN_ON_FAILED_EXECUTION(Value);
2422 RETURN_ESCAPED(result);
2423 }
2424
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2425 Local<Module> Module::CreateSyntheticModule(
2426 Isolate* isolate, Local<String> module_name,
2427 const std::vector<Local<v8::String>>& export_names,
2428 v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2429 auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2430 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
2431 i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2432 i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2433 static_cast<int>(export_names.size()));
2434 for (int i = 0; i < i_export_names->length(); ++i) {
2435 i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2436 Utils::OpenHandle(*export_names[i]));
2437 i_export_names->set(i, *str);
2438 }
2439 return v8::Utils::ToLocal(
2440 i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2441 i_module_name, i_export_names, evaluation_steps)));
2442 }
2443
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2444 Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2445 Local<String> export_name,
2446 Local<v8::Value> export_value) {
2447 auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2448 i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2449 i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2450 i::Handle<i::Module> self = Utils::OpenHandle(this);
2451 Utils::ApiCheck(self->IsSyntheticModule(),
2452 "v8::Module::SyntheticModuleSetExport",
2453 "v8::Module::SyntheticModuleSetExport must only be called on "
2454 "a SyntheticModule");
2455 ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2456 SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2457 has_pending_exception =
2458 i::SyntheticModule::SetExport(i_isolate,
2459 i::Handle<i::SyntheticModule>::cast(self),
2460 i_export_name, i_export_value)
2461 .IsNothing();
2462 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2463 return Just(true);
2464 }
2465
2466 namespace {
2467
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,int resource_line_offset,int resource_column_offset,Local<Value> source_map_url,Local<Data> host_defined_options,ScriptOriginOptions origin_options)2468 i::ScriptDetails GetScriptDetails(
2469 i::Isolate* isolate, Local<Value> resource_name, int resource_line_offset,
2470 int resource_column_offset, Local<Value> source_map_url,
2471 Local<Data> host_defined_options, ScriptOriginOptions origin_options) {
2472 i::ScriptDetails script_details(Utils::OpenHandle(*(resource_name), true),
2473 origin_options);
2474 script_details.line_offset = resource_line_offset;
2475 script_details.column_offset = resource_column_offset;
2476 script_details.host_defined_options =
2477 host_defined_options.IsEmpty()
2478 ? isolate->factory()->empty_fixed_array()
2479 : Utils::OpenHandle(*(host_defined_options));
2480 if (!source_map_url.IsEmpty()) {
2481 script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2482 }
2483 return script_details;
2484 }
2485
2486 } // namespace
2487
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2488 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2489 Isolate* v8_isolate, Source* source, CompileOptions options,
2490 NoCacheReason no_cache_reason) {
2491 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2492 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2493 ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2494 CompileUnbound, MaybeLocal<UnboundScript>(),
2495 InternalEscapableScope);
2496
2497 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2498
2499 i::Handle<i::SharedFunctionInfo> result;
2500 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2501 i::ScriptDetails script_details = GetScriptDetails(
2502 isolate, source->resource_name, source->resource_line_offset,
2503 source->resource_column_offset, source->source_map_url,
2504 source->host_defined_options, source->resource_options);
2505
2506 i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info;
2507 if (options == kConsumeCodeCache) {
2508 if (source->consume_cache_task) {
2509 // Take ownership of the internal deserialization task and clear it off
2510 // the consume task on the source.
2511 DCHECK_NOT_NULL(source->consume_cache_task->impl_);
2512 std::unique_ptr<i::BackgroundDeserializeTask> deserialize_task =
2513 std::move(source->consume_cache_task->impl_);
2514 maybe_function_info =
2515 i::Compiler::GetSharedFunctionInfoForScriptWithDeserializeTask(
2516 isolate, str, script_details, deserialize_task.get(), options,
2517 no_cache_reason, i::NOT_NATIVES_CODE);
2518 source->cached_data->rejected = deserialize_task->rejected();
2519 } else {
2520 DCHECK(source->cached_data);
2521 // AlignedCachedData takes care of pointer-aligning the data.
2522 auto cached_data = std::make_unique<i::AlignedCachedData>(
2523 source->cached_data->data, source->cached_data->length);
2524 maybe_function_info =
2525 i::Compiler::GetSharedFunctionInfoForScriptWithCachedData(
2526 isolate, str, script_details, cached_data.get(), options,
2527 no_cache_reason, i::NOT_NATIVES_CODE);
2528 source->cached_data->rejected = cached_data->rejected();
2529 }
2530 } else {
2531 // Compile without any cache.
2532 maybe_function_info = i::Compiler::GetSharedFunctionInfoForScript(
2533 isolate, str, script_details, options, no_cache_reason,
2534 i::NOT_NATIVES_CODE);
2535 }
2536
2537 has_pending_exception = !maybe_function_info.ToHandle(&result);
2538 RETURN_ON_FAILED_EXECUTION(UnboundScript);
2539 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2540 }
2541
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2542 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2543 Isolate* v8_isolate, Source* source, CompileOptions options,
2544 NoCacheReason no_cache_reason) {
2545 Utils::ApiCheck(
2546 !source->GetResourceOptions().IsModule(),
2547 "v8::ScriptCompiler::CompileUnboundScript",
2548 "v8::ScriptCompiler::CompileModule must be used to compile modules");
2549 return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2550 }
2551
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2552 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2553 Source* source,
2554 CompileOptions options,
2555 NoCacheReason no_cache_reason) {
2556 Utils::ApiCheck(
2557 !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2558 "v8::ScriptCompiler::CompileModule must be used to compile modules");
2559 auto isolate = context->GetIsolate();
2560 MaybeLocal<UnboundScript> maybe =
2561 CompileUnboundInternal(isolate, source, options, no_cache_reason);
2562 Local<UnboundScript> result;
2563 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2564 v8::Context::Scope scope(context);
2565 return result->BindToCurrentContext();
2566 }
2567
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2568 MaybeLocal<Module> ScriptCompiler::CompileModule(
2569 Isolate* isolate, Source* source, CompileOptions options,
2570 NoCacheReason no_cache_reason) {
2571 Utils::ApiCheck(options == kNoCompileOptions || options == kConsumeCodeCache,
2572 "v8::ScriptCompiler::CompileModule",
2573 "Invalid CompileOptions");
2574 Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2575 "v8::ScriptCompiler::CompileModule",
2576 "Invalid ScriptOrigin: is_module must be true");
2577 MaybeLocal<UnboundScript> maybe =
2578 CompileUnboundInternal(isolate, source, options, no_cache_reason);
2579 Local<UnboundScript> unbound;
2580 if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2581 i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2582 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2583 return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2584 }
2585
2586 // static
CompileFunction(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason)2587 V8_WARN_UNUSED_RESULT MaybeLocal<Function> ScriptCompiler::CompileFunction(
2588 Local<Context> context, Source* source, size_t arguments_count,
2589 Local<String> arguments[], size_t context_extension_count,
2590 Local<Object> context_extensions[], CompileOptions options,
2591 NoCacheReason no_cache_reason) {
2592 return CompileFunctionInternal(context, source, arguments_count, arguments,
2593 context_extension_count, context_extensions,
2594 options, no_cache_reason, nullptr);
2595 }
2596
2597 // static
CompileFunctionInContext(Local<Context> context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2598 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2599 Local<Context> context, Source* source, size_t arguments_count,
2600 Local<String> arguments[], size_t context_extension_count,
2601 Local<Object> context_extensions[], CompileOptions options,
2602 NoCacheReason no_cache_reason,
2603 Local<ScriptOrModule>* script_or_module_out) {
2604 return CompileFunctionInternal(
2605 context, source, arguments_count, arguments, context_extension_count,
2606 context_extensions, options, no_cache_reason, script_or_module_out);
2607 }
2608
CompileFunctionInternal(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2609 MaybeLocal<Function> ScriptCompiler::CompileFunctionInternal(
2610 Local<Context> v8_context, Source* source, size_t arguments_count,
2611 Local<String> arguments[], size_t context_extension_count,
2612 Local<Object> context_extensions[], CompileOptions options,
2613 NoCacheReason no_cache_reason,
2614 Local<ScriptOrModule>* script_or_module_out) {
2615 Local<Function> result;
2616
2617 {
2618 PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunction,
2619 Function);
2620 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2621
2622 DCHECK(options == CompileOptions::kConsumeCodeCache ||
2623 options == CompileOptions::kEagerCompile ||
2624 options == CompileOptions::kNoCompileOptions);
2625
2626 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2627
2628 DCHECK(context->IsNativeContext());
2629
2630 i::Handle<i::FixedArray> arguments_list =
2631 isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2632 for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2633 i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2634 if (!i::String::IsIdentifier(isolate, argument)) return Local<Function>();
2635 arguments_list->set(i, *argument);
2636 }
2637
2638 for (size_t i = 0; i < context_extension_count; ++i) {
2639 i::Handle<i::JSReceiver> extension =
2640 Utils::OpenHandle(*context_extensions[i]);
2641 if (!extension->IsJSObject()) return Local<Function>();
2642 context = isolate->factory()->NewWithContext(
2643 context,
2644 i::ScopeInfo::CreateForWithScope(
2645 isolate,
2646 context->IsNativeContext()
2647 ? i::Handle<i::ScopeInfo>::null()
2648 : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2649 extension);
2650 }
2651
2652 i::ScriptDetails script_details = GetScriptDetails(
2653 isolate, source->resource_name, source->resource_line_offset,
2654 source->resource_column_offset, source->source_map_url,
2655 source->host_defined_options, source->resource_options);
2656
2657 std::unique_ptr<i::AlignedCachedData> cached_data;
2658 if (options == kConsumeCodeCache) {
2659 DCHECK(source->cached_data);
2660 // ScriptData takes care of pointer-aligning the data.
2661 cached_data.reset(new i::AlignedCachedData(source->cached_data->data,
2662 source->cached_data->length));
2663 }
2664
2665 i::Handle<i::JSFunction> scoped_result;
2666 has_pending_exception =
2667 !i::Compiler::GetWrappedFunction(
2668 Utils::OpenHandle(*source->source_string), arguments_list, context,
2669 script_details, cached_data.get(), options, no_cache_reason)
2670 .ToHandle(&scoped_result);
2671 if (options == kConsumeCodeCache) {
2672 source->cached_data->rejected = cached_data->rejected();
2673 }
2674 RETURN_ON_FAILED_EXECUTION(Function);
2675 result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2676 }
2677 // TODO(cbruni): remove script_or_module_out paramater
2678 if (script_or_module_out != nullptr) {
2679 i::Handle<i::JSFunction> function =
2680 i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2681 i::Isolate* isolate = function->GetIsolate();
2682 i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2683 i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2684 // TODO(cbruni, v8:12302): Avoid creating tempory ScriptOrModule objects.
2685 auto script_or_module = i::Handle<i::ScriptOrModule>::cast(
2686 isolate->factory()->NewStruct(i::SCRIPT_OR_MODULE_TYPE));
2687 script_or_module->set_resource_name(script->name());
2688 script_or_module->set_host_defined_options(script->host_defined_options());
2689 #ifdef V8_SCRIPTORMODULE_LEGACY_LIFETIME
2690 i::Handle<i::ArrayList> list =
2691 i::handle(script->script_or_modules(), isolate);
2692 list = i::ArrayList::Add(isolate, list, script_or_module);
2693 script->set_script_or_modules(*list);
2694 #endif // V8_SCRIPTORMODULE_LEGACY_LIFETIME
2695 *script_or_module_out = v8::Utils::ToLocal(script_or_module);
2696 }
2697 return result;
2698 }
2699
Run()2700 void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2701
StartStreaming(Isolate * v8_isolate,StreamedSource * source,v8::ScriptType type)2702 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2703 Isolate* v8_isolate, StreamedSource* source, v8::ScriptType type) {
2704 if (!i::FLAG_script_streaming) return nullptr;
2705 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2706 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2707 i::ScriptStreamingData* data = source->impl();
2708 std::unique_ptr<i::BackgroundCompileTask> task =
2709 std::make_unique<i::BackgroundCompileTask>(data, isolate, type);
2710 data->task = std::move(task);
2711 return new ScriptCompiler::ScriptStreamingTask(data);
2712 }
2713
ConsumeCodeCacheTask(std::unique_ptr<i::BackgroundDeserializeTask> impl)2714 ScriptCompiler::ConsumeCodeCacheTask::ConsumeCodeCacheTask(
2715 std::unique_ptr<i::BackgroundDeserializeTask> impl)
2716 : impl_(std::move(impl)) {}
2717
2718 ScriptCompiler::ConsumeCodeCacheTask::~ConsumeCodeCacheTask() = default;
2719
Run()2720 void ScriptCompiler::ConsumeCodeCacheTask::Run() { impl_->Run(); }
2721
StartConsumingCodeCache(Isolate * v8_isolate,std::unique_ptr<CachedData> cached_data)2722 ScriptCompiler::ConsumeCodeCacheTask* ScriptCompiler::StartConsumingCodeCache(
2723 Isolate* v8_isolate, std::unique_ptr<CachedData> cached_data) {
2724 if (!i::FLAG_concurrent_cache_deserialization) return nullptr;
2725 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2726 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
2727 return new ScriptCompiler::ConsumeCodeCacheTask(
2728 std::make_unique<i::BackgroundDeserializeTask>(isolate,
2729 std::move(cached_data)));
2730 }
2731
2732 namespace {
CompileStreamedSource(i::Isolate * isolate,ScriptCompiler::StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2733 i::MaybeHandle<i::SharedFunctionInfo> CompileStreamedSource(
2734 i::Isolate* isolate, ScriptCompiler::StreamedSource* v8_source,
2735 Local<String> full_source_string, const ScriptOrigin& origin) {
2736 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2737 i::ScriptDetails script_details =
2738 GetScriptDetails(isolate, origin.ResourceName(), origin.LineOffset(),
2739 origin.ColumnOffset(), origin.SourceMapUrl(),
2740 origin.GetHostDefinedOptions(), origin.Options());
2741 i::ScriptStreamingData* data = v8_source->impl();
2742 return i::Compiler::GetSharedFunctionInfoForStreamedScript(
2743 isolate, str, script_details, data);
2744 }
2745
2746 } // namespace
2747
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2748 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2749 StreamedSource* v8_source,
2750 Local<String> full_source_string,
2751 const ScriptOrigin& origin) {
2752 PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2753 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2754 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2755 "V8.CompileStreamedScript");
2756 i::Handle<i::SharedFunctionInfo> sfi;
2757 i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2758 CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2759 has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2760 if (has_pending_exception) isolate->ReportPendingMessages();
2761 RETURN_ON_FAILED_EXECUTION(Script);
2762 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(sfi);
2763 if (generic.IsEmpty()) return Local<Script>();
2764 Local<Script> bound = generic->BindToCurrentContext();
2765 if (bound.IsEmpty()) return Local<Script>();
2766 RETURN_ESCAPED(bound);
2767 }
2768
CompileModule(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2769 MaybeLocal<Module> ScriptCompiler::CompileModule(
2770 Local<Context> context, StreamedSource* v8_source,
2771 Local<String> full_source_string, const ScriptOrigin& origin) {
2772 PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Module);
2773 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2774 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2775 "V8.CompileStreamedModule");
2776 i::Handle<i::SharedFunctionInfo> sfi;
2777 i::MaybeHandle<i::SharedFunctionInfo> maybe_sfi =
2778 CompileStreamedSource(isolate, v8_source, full_source_string, origin);
2779 has_pending_exception = !maybe_sfi.ToHandle(&sfi);
2780 if (has_pending_exception) isolate->ReportPendingMessages();
2781 RETURN_ON_FAILED_EXECUTION(Module);
2782 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2783 RETURN_ESCAPED(
2784 ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(sfi)));
2785 }
2786
CachedDataVersionTag()2787 uint32_t ScriptCompiler::CachedDataVersionTag() {
2788 return static_cast<uint32_t>(base::hash_combine(
2789 internal::Version::Hash(), internal::FlagList::Hash(),
2790 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2791 }
2792
CreateCodeCache(Local<UnboundScript> unbound_script)2793 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2794 Local<UnboundScript> unbound_script) {
2795 i::Handle<i::SharedFunctionInfo> shared =
2796 i::Handle<i::SharedFunctionInfo>::cast(
2797 Utils::OpenHandle(*unbound_script));
2798 ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2799 DCHECK(shared->is_toplevel());
2800 return i::CodeSerializer::Serialize(shared);
2801 }
2802
2803 // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2804 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2805 Local<UnboundModuleScript> unbound_module_script) {
2806 i::Handle<i::SharedFunctionInfo> shared =
2807 i::Handle<i::SharedFunctionInfo>::cast(
2808 Utils::OpenHandle(*unbound_module_script));
2809 ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2810 DCHECK(shared->is_toplevel());
2811 return i::CodeSerializer::Serialize(shared);
2812 }
2813
CreateCodeCacheForFunction(Local<Function> function)2814 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2815 Local<Function> function) {
2816 auto js_function =
2817 i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2818 i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2819 js_function->GetIsolate());
2820 ASSERT_NO_SCRIPT_NO_EXCEPTION(shared->GetIsolate());
2821 Utils::ApiCheck(shared->is_wrapped(),
2822 "v8::ScriptCompiler::CreateCodeCacheForFunction",
2823 "Expected SharedFunctionInfo with wrapped source code.");
2824 return i::CodeSerializer::Serialize(shared);
2825 }
2826
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2827 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2828 ScriptOrigin* origin) {
2829 if (origin) {
2830 ScriptCompiler::Source script_source(source, *origin);
2831 return ScriptCompiler::Compile(context, &script_source);
2832 }
2833 ScriptCompiler::Source script_source(source);
2834 return ScriptCompiler::Compile(context, &script_source);
2835 }
2836
2837 // --- E x c e p t i o n s ---
2838
TryCatch(v8::Isolate * isolate)2839 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2840 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2841 next_(isolate_->try_catch_handler()),
2842 is_verbose_(false),
2843 can_continue_(true),
2844 capture_message_(true),
2845 rethrow_(false),
2846 has_terminated_(false) {
2847 ResetInternal();
2848 // Special handling for simulators which have a separate JS stack.
2849 js_stack_comparable_address_ = static_cast<internal::Address>(
2850 i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2851 isolate_->RegisterTryCatchHandler(this);
2852 }
2853
~TryCatch()2854 v8::TryCatch::~TryCatch() {
2855 if (rethrow_) {
2856 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2857 v8::HandleScope scope(isolate);
2858 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2859 if (HasCaught() && capture_message_) {
2860 // If an exception was caught and rethrow_ is indicated, the saved
2861 // message, script, and location need to be restored to Isolate TLS
2862 // for reuse. capture_message_ needs to be disabled so that Throw()
2863 // does not create a new message.
2864 isolate_->thread_local_top()->rethrowing_message_ = true;
2865 isolate_->RestorePendingMessageFromTryCatch(this);
2866 }
2867 isolate_->UnregisterTryCatchHandler(this);
2868 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2869 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2870 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2871 } else {
2872 if (HasCaught() && isolate_->has_scheduled_exception()) {
2873 // If an exception was caught but is still scheduled because no API call
2874 // promoted it, then it is canceled to prevent it from being propagated.
2875 // Note that this will not cancel termination exceptions.
2876 isolate_->CancelScheduledExceptionFromTryCatch(this);
2877 }
2878 isolate_->UnregisterTryCatchHandler(this);
2879 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2880 }
2881 }
2882
operator new(size_t)2883 void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2884 void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2885 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2886 void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2887
HasCaught() const2888 bool v8::TryCatch::HasCaught() const {
2889 return !i::Object(reinterpret_cast<i::Address>(exception_))
2890 .IsTheHole(isolate_);
2891 }
2892
CanContinue() const2893 bool v8::TryCatch::CanContinue() const { return can_continue_; }
2894
HasTerminated() const2895 bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2896
ReThrow()2897 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2898 if (!HasCaught()) return v8::Local<v8::Value>();
2899 rethrow_ = true;
2900 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2901 }
2902
Exception() const2903 v8::Local<Value> v8::TryCatch::Exception() const {
2904 if (HasCaught()) {
2905 // Check for out of memory exception.
2906 i::Object exception(reinterpret_cast<i::Address>(exception_));
2907 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2908 } else {
2909 return v8::Local<Value>();
2910 }
2911 }
2912
StackTrace(Local<Context> context,Local<Value> exception)2913 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2914 Local<Value> exception) {
2915 i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2916 if (!i_exception->IsJSObject()) return v8::Local<Value>();
2917 PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2918 auto obj = i::Handle<i::JSObject>::cast(i_exception);
2919 i::Handle<i::String> name = isolate->factory()->stack_string();
2920 Maybe<bool> maybe = i::JSReceiver::HasProperty(isolate, obj, name);
2921 has_pending_exception = maybe.IsNothing();
2922 RETURN_ON_FAILED_EXECUTION(Value);
2923 if (!maybe.FromJust()) return v8::Local<Value>();
2924 Local<Value> result;
2925 has_pending_exception =
2926 !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2927 RETURN_ON_FAILED_EXECUTION(Value);
2928 RETURN_ESCAPED(result);
2929 }
2930
StackTrace(Local<Context> context) const2931 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2932 if (!HasCaught()) return v8::Local<Value>();
2933 return StackTrace(context, Exception());
2934 }
2935
Message() const2936 v8::Local<v8::Message> v8::TryCatch::Message() const {
2937 i::Object message(reinterpret_cast<i::Address>(message_obj_));
2938 DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2939 if (HasCaught() && !message.IsTheHole(isolate_)) {
2940 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2941 } else {
2942 return v8::Local<v8::Message>();
2943 }
2944 }
2945
Reset()2946 void v8::TryCatch::Reset() {
2947 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2948 // If an exception was caught but is still scheduled because no API call
2949 // promoted it, then it is canceled to prevent it from being propagated.
2950 // Note that this will not cancel termination exceptions.
2951 isolate_->CancelScheduledExceptionFromTryCatch(this);
2952 }
2953 ResetInternal();
2954 }
2955
ResetInternal()2956 void v8::TryCatch::ResetInternal() {
2957 i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2958 exception_ = reinterpret_cast<void*>(the_hole.ptr());
2959 message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2960 }
2961
SetVerbose(bool value)2962 void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2963
IsVerbose() const2964 bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2965
SetCaptureMessage(bool value)2966 void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2967
2968 // --- M e s s a g e ---
2969
Get() const2970 Local<String> Message::Get() const {
2971 auto self = Utils::OpenHandle(this);
2972 i::Isolate* isolate = self->GetIsolate();
2973 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2975 i::Handle<i::String> raw_result =
2976 i::MessageHandler::GetMessage(isolate, self);
2977 Local<String> result = Utils::ToLocal(raw_result);
2978 return scope.Escape(result);
2979 }
2980
GetIsolate() const2981 v8::Isolate* Message::GetIsolate() const {
2982 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983 return reinterpret_cast<Isolate*>(isolate);
2984 }
2985
GetScriptOrigin() const2986 ScriptOrigin Message::GetScriptOrigin() const {
2987 auto self = Utils::OpenHandle(this);
2988 i::Isolate* isolate = self->GetIsolate();
2989 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2990 i::Handle<i::Script> script(self->script(), isolate);
2991 return GetScriptOriginForScript(isolate, script);
2992 }
2993
VerifyHostDefinedOptions() const2994 void ScriptOrigin::VerifyHostDefinedOptions() const {
2995 // TODO(cbruni, chromium:1244145): Remove checks once we allow arbitrary
2996 // host-defined options.
2997 USE(isolate_);
2998 if (host_defined_options_.IsEmpty()) return;
2999 Utils::ApiCheck(host_defined_options_->IsFixedArray(), "ScriptOrigin()",
3000 "Host-defined options has to be a PrimitiveArray");
3001 i::Handle<i::FixedArray> options =
3002 Utils::OpenHandle(*host_defined_options_.As<FixedArray>());
3003 for (int i = 0; i < options->length(); i++) {
3004 Utils::ApiCheck(options->get(i).IsPrimitive(), "ScriptOrigin()",
3005 "PrimitiveArray can only contain primtive values");
3006 }
3007 }
3008
GetScriptResourceName() const3009 v8::Local<Value> Message::GetScriptResourceName() const {
3010 ASSERT_NO_SCRIPT_NO_EXCEPTION(Utils::OpenHandle(this)->GetIsolate());
3011 return GetScriptOrigin().ResourceName();
3012 }
3013
GetStackTrace() const3014 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
3015 auto self = Utils::OpenHandle(this);
3016 i::Isolate* isolate = self->GetIsolate();
3017 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3018 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3019 i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
3020 if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
3021 auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
3022 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
3023 }
3024
GetLineNumber(Local<Context> context) const3025 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
3026 auto self = Utils::OpenHandle(this);
3027 i::Isolate* isolate = self->GetIsolate();
3028 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3029 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3030 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3031 return Just(self->GetLineNumber());
3032 }
3033
GetStartPosition() const3034 int Message::GetStartPosition() const {
3035 auto self = Utils::OpenHandle(this);
3036 i::Isolate* isolate = self->GetIsolate();
3037 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3038 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3039 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3040 return self->GetStartPosition();
3041 }
3042
GetEndPosition() const3043 int Message::GetEndPosition() const {
3044 auto self = Utils::OpenHandle(this);
3045 i::Isolate* isolate = self->GetIsolate();
3046 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3047 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3048 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3049 return self->GetEndPosition();
3050 }
3051
ErrorLevel() const3052 int Message::ErrorLevel() const {
3053 auto self = Utils::OpenHandle(this);
3054 ASSERT_NO_SCRIPT_NO_EXCEPTION(self->GetIsolate());
3055 return self->error_level();
3056 }
3057
GetStartColumn() const3058 int Message::GetStartColumn() const {
3059 auto self = Utils::OpenHandle(this);
3060 i::Isolate* isolate = self->GetIsolate();
3061 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3062 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3063 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3064 return self->GetColumnNumber();
3065 }
3066
GetWasmFunctionIndex() const3067 int Message::GetWasmFunctionIndex() const {
3068 #if V8_ENABLE_WEBASSEMBLY
3069 auto self = Utils::OpenHandle(this);
3070 i::Isolate* isolate = self->GetIsolate();
3071 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3072 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3073 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3074 int start_position = self->GetColumnNumber();
3075 if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
3076
3077 i::Handle<i::Script> script(self->script(), isolate);
3078
3079 if (script->type() != i::Script::TYPE_WASM) {
3080 return Message::kNoWasmFunctionIndexInfo;
3081 }
3082
3083 auto debug_script = ToApiHandle<debug::Script>(script);
3084 return Local<debug::WasmScript>::Cast(debug_script)
3085 ->GetContainingFunction(start_position);
3086 #else
3087 return Message::kNoWasmFunctionIndexInfo;
3088 #endif // V8_ENABLE_WEBASSEMBLY
3089 }
3090
GetStartColumn(Local<Context> context) const3091 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
3092 return Just(GetStartColumn());
3093 }
3094
GetEndColumn() const3095 int Message::GetEndColumn() const {
3096 auto self = Utils::OpenHandle(this);
3097 i::Isolate* isolate = self->GetIsolate();
3098 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3099 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3100 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3101 const int column_number = self->GetColumnNumber();
3102 if (column_number == -1) return -1;
3103 const int start = self->GetStartPosition();
3104 const int end = self->GetEndPosition();
3105 return column_number + (end - start);
3106 }
3107
GetEndColumn(Local<Context> context) const3108 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
3109 return Just(GetEndColumn());
3110 }
3111
IsSharedCrossOrigin() const3112 bool Message::IsSharedCrossOrigin() const {
3113 auto self = Utils::OpenHandle(this);
3114 i::Isolate* isolate = self->GetIsolate();
3115 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3116 return self->script().origin_options().IsSharedCrossOrigin();
3117 }
3118
IsOpaque() const3119 bool Message::IsOpaque() const {
3120 auto self = Utils::OpenHandle(this);
3121 i::Isolate* isolate = self->GetIsolate();
3122 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3123 return self->script().origin_options().IsOpaque();
3124 }
3125
GetSource(Local<Context> context) const3126 MaybeLocal<String> Message::GetSource(Local<Context> context) const {
3127 auto self = Utils::OpenHandle(this);
3128 i::Isolate* isolate = self->GetIsolate();
3129 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3130 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3131 i::Handle<i::String> source(self->GetSource(), isolate);
3132 RETURN_ESCAPED(Utils::ToLocal(source));
3133 }
3134
GetSourceLine(Local<Context> context) const3135 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3136 auto self = Utils::OpenHandle(this);
3137 i::Isolate* isolate = self->GetIsolate();
3138 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3139 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3140 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3141 RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3142 }
3143
PrintCurrentStackTrace(Isolate * isolate,std::ostream & out)3144 void Message::PrintCurrentStackTrace(Isolate* isolate, std::ostream& out) {
3145 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3146 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3147 i_isolate->PrintCurrentStackTrace(out);
3148 }
3149
3150 // --- S t a c k T r a c e ---
3151
GetFrame(Isolate * v8_isolate,uint32_t index) const3152 Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3153 uint32_t index) const {
3154 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3155 i::Handle<i::StackFrameInfo> info(
3156 i::StackFrameInfo::cast(Utils::OpenHandle(this)->get(index)), isolate);
3157 return Utils::StackFrameToLocal(info);
3158 }
3159
GetFrameCount() const3160 int StackTrace::GetFrameCount() const {
3161 return Utils::OpenHandle(this)->length();
3162 }
3163
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3164 Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3165 int frame_limit,
3166 StackTraceOptions options) {
3167 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3168 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3169 i::Handle<i::FixedArray> stackTrace =
3170 i_isolate->CaptureDetailedStackTrace(frame_limit, options);
3171 return Utils::StackTraceToLocal(stackTrace);
3172 }
3173
CurrentScriptNameOrSourceURL(Isolate * v8_isolate)3174 Local<String> StackTrace::CurrentScriptNameOrSourceURL(Isolate* v8_isolate) {
3175 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3176 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3177 i::Handle<i::String> name_or_source_url =
3178 isolate->CurrentScriptNameOrSourceURL();
3179 return Utils::ToLocal(name_or_source_url);
3180 }
3181
3182 // --- S t a c k F r a m e ---
3183
GetLocation() const3184 Location StackFrame::GetLocation() const {
3185 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3186 i::Isolate* isolate = self->GetIsolate();
3187 i::Handle<i::Script> script(self->script(), isolate);
3188 i::Script::PositionInfo info;
3189 CHECK(i::Script::GetPositionInfo(script,
3190 i::StackFrameInfo::GetSourcePosition(self),
3191 &info, i::Script::WITH_OFFSET));
3192 if (script->HasSourceURLComment()) {
3193 info.line -= script->line_offset();
3194 if (info.line == 0) {
3195 info.column -= script->column_offset();
3196 }
3197 }
3198 return {info.line, info.column};
3199 }
3200
GetScriptId() const3201 int StackFrame::GetScriptId() const {
3202 return Utils::OpenHandle(this)->script().id();
3203 }
3204
GetScriptName() const3205 Local<String> StackFrame::GetScriptName() const {
3206 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3207 i::Isolate* isolate = self->GetIsolate();
3208 i::Handle<i::Object> name(self->script().name(), isolate);
3209 if (!name->IsString()) return {};
3210 return Utils::ToLocal(i::Handle<i::String>::cast(name));
3211 }
3212
GetScriptNameOrSourceURL() const3213 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3214 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3215 i::Isolate* isolate = self->GetIsolate();
3216 i::Handle<i::Object> name_or_source_url(self->script().GetNameOrSourceURL(),
3217 isolate);
3218 if (!name_or_source_url->IsString()) return {};
3219 return Utils::ToLocal(i::Handle<i::String>::cast(name_or_source_url));
3220 }
3221
GetScriptSource() const3222 Local<String> StackFrame::GetScriptSource() const {
3223 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3224 i::Isolate* isolate = self->GetIsolate();
3225 if (!self->script().HasValidSource()) return {};
3226 i::Handle<i::PrimitiveHeapObject> source(self->script().source(), isolate);
3227 if (!source->IsString()) return {};
3228 return Utils::ToLocal(i::Handle<i::String>::cast(source));
3229 }
3230
GetScriptSourceMappingURL() const3231 Local<String> StackFrame::GetScriptSourceMappingURL() const {
3232 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3233 i::Isolate* isolate = self->GetIsolate();
3234 i::Handle<i::Object> source_mapping_url(self->script().source_mapping_url(),
3235 isolate);
3236 if (!source_mapping_url->IsString()) return {};
3237 return Utils::ToLocal(i::Handle<i::String>::cast(source_mapping_url));
3238 }
3239
GetFunctionName() const3240 Local<String> StackFrame::GetFunctionName() const {
3241 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3242 i::Isolate* isolate = self->GetIsolate();
3243 i::Handle<i::String> name(self->function_name(), isolate);
3244 if (name->length() == 0) return {};
3245 return Utils::ToLocal(name);
3246 }
3247
IsEval() const3248 bool StackFrame::IsEval() const {
3249 i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3250 return self->script().compilation_type() == i::Script::COMPILATION_TYPE_EVAL;
3251 }
3252
IsConstructor() const3253 bool StackFrame::IsConstructor() const {
3254 return Utils::OpenHandle(this)->is_constructor();
3255 }
3256
IsWasm() const3257 bool StackFrame::IsWasm() const { return !IsUserJavaScript(); }
3258
IsUserJavaScript() const3259 bool StackFrame::IsUserJavaScript() const {
3260 return Utils::OpenHandle(this)->script().IsUserJavaScript();
3261 }
3262
3263 // --- J S O N ---
3264
Parse(Local<Context> context,Local<String> json_string)3265 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3266 Local<String> json_string) {
3267 PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3268 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3269 i::Handle<i::String> source = i::String::Flatten(isolate, string);
3270 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3271 auto maybe = source->IsOneByteRepresentation()
3272 ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3273 : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3274 Local<Value> result;
3275 has_pending_exception = !ToLocal<Value>(maybe, &result);
3276 RETURN_ON_FAILED_EXECUTION(Value);
3277 RETURN_ESCAPED(result);
3278 }
3279
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3280 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3281 Local<Value> json_object,
3282 Local<String> gap) {
3283 PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3284 i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3285 i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3286 i::Handle<i::String> gap_string = gap.IsEmpty()
3287 ? isolate->factory()->empty_string()
3288 : Utils::OpenHandle(*gap);
3289 i::Handle<i::Object> maybe;
3290 has_pending_exception =
3291 !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3292 RETURN_ON_FAILED_EXECUTION(String);
3293 Local<String> result;
3294 has_pending_exception =
3295 !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3296 RETURN_ON_FAILED_EXECUTION(String);
3297 RETURN_ESCAPED(result);
3298 }
3299
3300 // --- V a l u e S e r i a l i z a t i o n ---
3301
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3302 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3303 Local<Object> object) {
3304 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3305 isolate->ScheduleThrow(*isolate->factory()->NewError(
3306 isolate->error_function(), i::MessageTemplate::kDataCloneError,
3307 Utils::OpenHandle(*object)));
3308 return Nothing<bool>();
3309 }
3310
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3311 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3312 Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3313 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3314 isolate->ScheduleThrow(*isolate->factory()->NewError(
3315 isolate->error_function(), i::MessageTemplate::kDataCloneError,
3316 Utils::OpenHandle(*shared_array_buffer)));
3317 return Nothing<uint32_t>();
3318 }
3319
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3320 Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3321 Isolate* v8_isolate, Local<WasmModuleObject> module) {
3322 return Nothing<uint32_t>();
3323 }
3324
SupportsSharedValues() const3325 bool ValueSerializer::Delegate::SupportsSharedValues() const { return false; }
3326
GetSharedValueId(Isolate * v8_isolate,Local<Value> shared_value)3327 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedValueId(
3328 Isolate* v8_isolate, Local<Value> shared_value) {
3329 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3330 isolate->ScheduleThrow(*isolate->factory()->NewError(
3331 isolate->error_function(), i::MessageTemplate::kDataCloneError,
3332 Utils::OpenHandle(*shared_value)));
3333 return Nothing<uint32_t>();
3334 }
3335
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3336 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3337 size_t size,
3338 size_t* actual_size) {
3339 *actual_size = size;
3340 return base::Realloc(old_buffer, size);
3341 }
3342
FreeBufferMemory(void * buffer)3343 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3344 return base::Free(buffer);
3345 }
3346
3347 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3348 explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3349 : isolate(i), serializer(i, delegate) {}
3350 i::Isolate* isolate;
3351 i::ValueSerializer serializer;
3352 };
3353
ValueSerializer(Isolate * isolate)3354 ValueSerializer::ValueSerializer(Isolate* isolate)
3355 : ValueSerializer(isolate, nullptr) {}
3356
ValueSerializer(Isolate * isolate,Delegate * delegate)3357 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3358 : private_(
3359 new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3360
~ValueSerializer()3361 ValueSerializer::~ValueSerializer() { delete private_; }
3362
WriteHeader()3363 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3364
SetTreatArrayBufferViewsAsHostObjects(bool mode)3365 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3366 private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3367 }
3368
WriteValue(Local<Context> context,Local<Value> value)3369 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3370 Local<Value> value) {
3371 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3372 ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3373 i::HandleScope);
3374 i::Handle<i::Object> object = Utils::OpenHandle(*value);
3375 Maybe<bool> result = private_->serializer.WriteObject(object);
3376 has_pending_exception = result.IsNothing();
3377 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3378 return result;
3379 }
3380
Release()3381 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3382 return private_->serializer.Release();
3383 }
3384
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3385 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3386 Local<ArrayBuffer> array_buffer) {
3387 private_->serializer.TransferArrayBuffer(transfer_id,
3388 Utils::OpenHandle(*array_buffer));
3389 }
3390
WriteUint32(uint32_t value)3391 void ValueSerializer::WriteUint32(uint32_t value) {
3392 private_->serializer.WriteUint32(value);
3393 }
3394
WriteUint64(uint64_t value)3395 void ValueSerializer::WriteUint64(uint64_t value) {
3396 private_->serializer.WriteUint64(value);
3397 }
3398
WriteDouble(double value)3399 void ValueSerializer::WriteDouble(double value) {
3400 private_->serializer.WriteDouble(value);
3401 }
3402
WriteRawBytes(const void * source,size_t length)3403 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3404 private_->serializer.WriteRawBytes(source, length);
3405 }
3406
ReadHostObject(Isolate * v8_isolate)3407 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3408 Isolate* v8_isolate) {
3409 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3410 isolate->ScheduleThrow(*isolate->factory()->NewError(
3411 isolate->error_function(),
3412 i::MessageTemplate::kDataCloneDeserializationError));
3413 return MaybeLocal<Object>();
3414 }
3415
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3416 MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3417 Isolate* v8_isolate, uint32_t id) {
3418 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3419 isolate->ScheduleThrow(*isolate->factory()->NewError(
3420 isolate->error_function(),
3421 i::MessageTemplate::kDataCloneDeserializationError));
3422 return MaybeLocal<WasmModuleObject>();
3423 }
3424
SupportsSharedValues() const3425 bool ValueDeserializer::Delegate::SupportsSharedValues() const { return false; }
3426
GetSharedValueFromId(Isolate * v8_isolate,uint32_t shared_value_id)3427 MaybeLocal<Value> ValueDeserializer::Delegate::GetSharedValueFromId(
3428 Isolate* v8_isolate, uint32_t shared_value_id) {
3429 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3430 isolate->ScheduleThrow(*isolate->factory()->NewError(
3431 isolate->error_function(),
3432 i::MessageTemplate::kDataCloneDeserializationError));
3433 return MaybeLocal<Value>();
3434 }
3435
3436 MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3437 ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3438 uint32_t id) {
3439 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3440 isolate->ScheduleThrow(*isolate->factory()->NewError(
3441 isolate->error_function(),
3442 i::MessageTemplate::kDataCloneDeserializationError));
3443 return MaybeLocal<SharedArrayBuffer>();
3444 }
3445
3446 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3447 PrivateData(i::Isolate* i, base::Vector<const uint8_t> data,
3448 Delegate* delegate)
3449 : isolate(i), deserializer(i, data, delegate) {}
3450 i::Isolate* isolate;
3451 i::ValueDeserializer deserializer;
3452 bool supports_legacy_wire_format = false;
3453 };
3454
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3455 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3456 size_t size)
3457 : ValueDeserializer(isolate, data, size, nullptr) {}
3458
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3459 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3460 size_t size, Delegate* delegate) {
3461 private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3462 base::Vector<const uint8_t>(data, size), delegate);
3463 }
3464
~ValueDeserializer()3465 ValueDeserializer::~ValueDeserializer() { delete private_; }
3466
ReadHeader(Local<Context> context)3467 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3468 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3469 ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3470 Nothing<bool>(), i::HandleScope);
3471
3472 bool read_header = false;
3473 has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3474 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3475 DCHECK(read_header);
3476
3477 static const uint32_t kMinimumNonLegacyVersion = 13;
3478 if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3479 !private_->supports_legacy_wire_format) {
3480 isolate->Throw(*isolate->factory()->NewError(
3481 i::MessageTemplate::kDataCloneDeserializationVersionError));
3482 has_pending_exception = true;
3483 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3484 }
3485
3486 return Just(true);
3487 }
3488
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3489 void ValueDeserializer::SetSupportsLegacyWireFormat(
3490 bool supports_legacy_wire_format) {
3491 private_->supports_legacy_wire_format = supports_legacy_wire_format;
3492 }
3493
GetWireFormatVersion() const3494 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3495 return private_->deserializer.GetWireFormatVersion();
3496 }
3497
ReadValue(Local<Context> context)3498 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3499 PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3500 i::MaybeHandle<i::Object> result;
3501 if (GetWireFormatVersion() > 0) {
3502 result = private_->deserializer.ReadObjectWrapper();
3503 } else {
3504 result =
3505 private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3506 }
3507 Local<Value> value;
3508 has_pending_exception = !ToLocal(result, &value);
3509 RETURN_ON_FAILED_EXECUTION(Value);
3510 RETURN_ESCAPED(value);
3511 }
3512
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3513 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3514 Local<ArrayBuffer> array_buffer) {
3515 private_->deserializer.TransferArrayBuffer(transfer_id,
3516 Utils::OpenHandle(*array_buffer));
3517 }
3518
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3519 void ValueDeserializer::TransferSharedArrayBuffer(
3520 uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3521 private_->deserializer.TransferArrayBuffer(
3522 transfer_id, Utils::OpenHandle(*shared_array_buffer));
3523 }
3524
ReadUint32(uint32_t * value)3525 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3526 return private_->deserializer.ReadUint32(value);
3527 }
3528
ReadUint64(uint64_t * value)3529 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3530 return private_->deserializer.ReadUint64(value);
3531 }
3532
ReadDouble(double * value)3533 bool ValueDeserializer::ReadDouble(double* value) {
3534 return private_->deserializer.ReadDouble(value);
3535 }
3536
ReadRawBytes(size_t length,const void ** data)3537 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3538 return private_->deserializer.ReadRawBytes(length, data);
3539 }
3540
3541 // --- D a t a ---
3542
FullIsUndefined() const3543 bool Value::FullIsUndefined() const {
3544 i::Handle<i::Object> object = Utils::OpenHandle(this);
3545 bool result = object->IsUndefined();
3546 DCHECK_EQ(result, QuickIsUndefined());
3547 return result;
3548 }
3549
FullIsNull() const3550 bool Value::FullIsNull() const {
3551 i::Handle<i::Object> object = Utils::OpenHandle(this);
3552 bool result = object->IsNull();
3553 DCHECK_EQ(result, QuickIsNull());
3554 return result;
3555 }
3556
IsTrue() const3557 bool Value::IsTrue() const {
3558 i::Object object = *Utils::OpenHandle(this);
3559 if (object.IsSmi()) return false;
3560 return object.IsTrue();
3561 }
3562
IsFalse() const3563 bool Value::IsFalse() const {
3564 i::Object object = *Utils::OpenHandle(this);
3565 if (object.IsSmi()) return false;
3566 return object.IsFalse();
3567 }
3568
IsFunction() const3569 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3570
IsName() const3571 bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3572
FullIsString() const3573 bool Value::FullIsString() const {
3574 bool result = Utils::OpenHandle(this)->IsString();
3575 DCHECK_EQ(result, QuickIsString());
3576 return result;
3577 }
3578
IsSymbol() const3579 bool Value::IsSymbol() const {
3580 return Utils::OpenHandle(this)->IsPublicSymbol();
3581 }
3582
IsArray() const3583 bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3584
IsArrayBuffer() const3585 bool Value::IsArrayBuffer() const {
3586 i::Object obj = *Utils::OpenHandle(this);
3587 if (!obj.IsJSArrayBuffer()) return false;
3588 return !i::JSArrayBuffer::cast(obj).is_shared();
3589 }
3590
IsArrayBufferView() const3591 bool Value::IsArrayBufferView() const {
3592 return Utils::OpenHandle(this)->IsJSArrayBufferView();
3593 }
3594
IsTypedArray() const3595 bool Value::IsTypedArray() const {
3596 return Utils::OpenHandle(this)->IsJSTypedArray();
3597 }
3598
3599 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype) \
3600 bool Value::Is##Type##Array() const { \
3601 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3602 return obj->IsJSTypedArray() && \
3603 i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3604 }
3605
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3606 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3607
3608 #undef VALUE_IS_TYPED_ARRAY
3609
3610 bool Value::IsDataView() const {
3611 return Utils::OpenHandle(this)->IsJSDataView();
3612 }
3613
IsSharedArrayBuffer() const3614 bool Value::IsSharedArrayBuffer() const {
3615 i::Object obj = *Utils::OpenHandle(this);
3616 if (!obj.IsJSArrayBuffer()) return false;
3617 return i::JSArrayBuffer::cast(obj).is_shared();
3618 }
3619
IsObject() const3620 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3621
IsNumber() const3622 bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3623
IsBigInt() const3624 bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3625
IsProxy() const3626 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3627
3628 #define VALUE_IS_SPECIFIC_TYPE(Type, Check) \
3629 bool Value::Is##Type() const { \
3630 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3631 return obj->Is##Check(); \
3632 }
3633
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3634 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3635 VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3636 VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3637 VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3638 VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3639 VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3640 VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3641 VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3642 VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3643 #if V8_ENABLE_WEBASSEMBLY
3644 VALUE_IS_SPECIFIC_TYPE(WasmMemoryObject, WasmMemoryObject)
3645 VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3646 #else
3647 bool Value::IsWasmMemoryObject() const { return false; }
3648 bool Value::IsWasmModuleObject() const { return false; }
3649 #endif // V8_ENABLE_WEBASSEMBLY
3650 VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3651 VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3652
3653 #undef VALUE_IS_SPECIFIC_TYPE
3654
3655 bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3656
IsExternal() const3657 bool Value::IsExternal() const {
3658 i::Object obj = *Utils::OpenHandle(this);
3659 return obj.IsJSExternalObject();
3660 }
3661
IsInt32() const3662 bool Value::IsInt32() const {
3663 i::Object obj = *Utils::OpenHandle(this);
3664 if (obj.IsSmi()) return true;
3665 if (obj.IsNumber()) {
3666 return i::IsInt32Double(obj.Number());
3667 }
3668 return false;
3669 }
3670
IsUint32() const3671 bool Value::IsUint32() const {
3672 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3673 if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3674 if (obj->IsNumber()) {
3675 double value = obj->Number();
3676 return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3677 value == i::FastUI2D(i::FastD2UI(value));
3678 }
3679 return false;
3680 }
3681
IsNativeError() const3682 bool Value::IsNativeError() const {
3683 return Utils::OpenHandle(this)->IsJSError();
3684 }
3685
IsRegExp() const3686 bool Value::IsRegExp() const {
3687 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3688 return obj->IsJSRegExp();
3689 }
3690
IsAsyncFunction() const3691 bool Value::IsAsyncFunction() const {
3692 i::Object obj = *Utils::OpenHandle(this);
3693 if (!obj.IsJSFunction()) return false;
3694 i::JSFunction func = i::JSFunction::cast(obj);
3695 return i::IsAsyncFunction(func.shared().kind());
3696 }
3697
IsGeneratorFunction() const3698 bool Value::IsGeneratorFunction() const {
3699 i::Object obj = *Utils::OpenHandle(this);
3700 if (!obj.IsJSFunction()) return false;
3701 i::JSFunction func = i::JSFunction::cast(obj);
3702 ASSERT_NO_SCRIPT_NO_EXCEPTION(func.GetIsolate());
3703 return i::IsGeneratorFunction(func.shared().kind());
3704 }
3705
IsGeneratorObject() const3706 bool Value::IsGeneratorObject() const {
3707 return Utils::OpenHandle(this)->IsJSGeneratorObject();
3708 }
3709
IsMapIterator() const3710 bool Value::IsMapIterator() const {
3711 return Utils::OpenHandle(this)->IsJSMapIterator();
3712 }
3713
IsSetIterator() const3714 bool Value::IsSetIterator() const {
3715 return Utils::OpenHandle(this)->IsJSSetIterator();
3716 }
3717
IsPromise() const3718 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3719
IsModuleNamespaceObject() const3720 bool Value::IsModuleNamespaceObject() const {
3721 return Utils::OpenHandle(this)->IsJSModuleNamespace();
3722 }
3723
ToString(Local<Context> context) const3724 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3725 auto obj = Utils::OpenHandle(this);
3726 if (obj->IsString()) return ToApiHandle<String>(obj);
3727 PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3728 Local<String> result;
3729 has_pending_exception =
3730 !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3731 RETURN_ON_FAILED_EXECUTION(String);
3732 RETURN_ESCAPED(result);
3733 }
3734
ToDetailString(Local<Context> context) const3735 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3736 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3737 if (obj->IsString()) return ToApiHandle<String>(obj);
3738 PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3739 Local<String> result =
3740 Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3741 RETURN_ON_FAILED_EXECUTION(String);
3742 RETURN_ESCAPED(result);
3743 }
3744
ToObject(Local<Context> context) const3745 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3746 auto obj = Utils::OpenHandle(this);
3747 if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3748 PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3749 Local<Object> result;
3750 has_pending_exception =
3751 !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3752 RETURN_ON_FAILED_EXECUTION(Object);
3753 RETURN_ESCAPED(result);
3754 }
3755
ToBigInt(Local<Context> context) const3756 MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3757 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3758 if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3759 PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3760 Local<BigInt> result;
3761 has_pending_exception =
3762 !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3763 RETURN_ON_FAILED_EXECUTION(BigInt);
3764 RETURN_ESCAPED(result);
3765 }
3766
BooleanValue(Isolate * v8_isolate) const3767 bool Value::BooleanValue(Isolate* v8_isolate) const {
3768 return Utils::OpenHandle(this)->BooleanValue(
3769 reinterpret_cast<i::Isolate*>(v8_isolate));
3770 }
3771
ToBoolean(Isolate * v8_isolate) const3772 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3773 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3774 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
3775 return ToApiHandle<Boolean>(
3776 isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3777 }
3778
ToNumber(Local<Context> context) const3779 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3780 auto obj = Utils::OpenHandle(this);
3781 if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3782 PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3783 Local<Number> result;
3784 has_pending_exception =
3785 !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3786 RETURN_ON_FAILED_EXECUTION(Number);
3787 RETURN_ESCAPED(result);
3788 }
3789
ToInteger(Local<Context> context) const3790 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3791 auto obj = Utils::OpenHandle(this);
3792 if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3793 PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3794 Local<Integer> result;
3795 has_pending_exception =
3796 !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3797 RETURN_ON_FAILED_EXECUTION(Integer);
3798 RETURN_ESCAPED(result);
3799 }
3800
ToInt32(Local<Context> context) const3801 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3802 auto obj = Utils::OpenHandle(this);
3803 if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3804 Local<Int32> result;
3805 PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3806 has_pending_exception =
3807 !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3808 RETURN_ON_FAILED_EXECUTION(Int32);
3809 RETURN_ESCAPED(result);
3810 }
3811
ToUint32(Local<Context> context) const3812 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3813 auto obj = Utils::OpenHandle(this);
3814 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3815 Local<Uint32> result;
3816 PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3817 has_pending_exception =
3818 !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3819 RETURN_ON_FAILED_EXECUTION(Uint32);
3820 RETURN_ESCAPED(result);
3821 }
3822
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3823 i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3824 i::ExternalPointer_t encoded_pointer,
3825 ExternalPointerTag tag) {
3826 return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3827 }
3828
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3829 i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3830 return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3831 }
3832
ShouldThrowOnError(i::Isolate * isolate)3833 bool i::ShouldThrowOnError(i::Isolate* isolate) {
3834 return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3835 i::ShouldThrow::kThrowOnError;
3836 }
3837
CanHaveInternalField(int instance_type)3838 bool i::CanHaveInternalField(int instance_type) {
3839 return instance_type == i::Internals::kJSObjectType ||
3840 instance_type == i::Internals::kJSSpecialApiObjectType ||
3841 v8::internal::InstanceTypeChecker::IsJSApiObject(
3842 static_cast<v8::internal::InstanceType>(instance_type));
3843 }
3844
CheckInitializedImpl(v8::Isolate * external_isolate)3845 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3846 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3847 Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3848 "v8::internal::Internals::CheckInitialized",
3849 "Isolate is not initialized or V8 has died");
3850 }
3851
CheckCast(Data * that)3852 void v8::Value::CheckCast(Data* that) {
3853 Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3854 }
3855
CheckCast(v8::Value * that)3856 void External::CheckCast(v8::Value* that) {
3857 Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3858 "Value is not an External");
3859 }
3860
CheckCast(Value * that)3861 void v8::Object::CheckCast(Value* that) {
3862 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3863 Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3864 "Value is not an Object");
3865 }
3866
CheckCast(Value * that)3867 void v8::Function::CheckCast(Value* that) {
3868 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3869 Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3870 "Value is not a Function");
3871 }
3872
CheckCast(v8::Data * that)3873 void v8::Boolean::CheckCast(v8::Data* that) {
3874 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3875 Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3876 "Value is not a Boolean");
3877 }
3878
CheckCast(v8::Data * that)3879 void v8::Name::CheckCast(v8::Data* that) {
3880 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3881 Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3882 }
3883
CheckCast(v8::Data * that)3884 void v8::String::CheckCast(v8::Data* that) {
3885 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3886 Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3887 }
3888
CheckCast(v8::Data * that)3889 void v8::Symbol::CheckCast(v8::Data* that) {
3890 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3891 Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3892 }
3893
CheckCast(v8::Data * that)3894 void v8::Private::CheckCast(v8::Data* that) {
3895 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3896 Utils::ApiCheck(
3897 obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3898 "v8::Private::Cast", "Value is not a Private");
3899 }
3900
CheckCast(v8::Data * that)3901 void v8::FixedArray::CheckCast(v8::Data* that) {
3902 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3903 Utils::ApiCheck(obj->IsFixedArray(), "v8::FixedArray::Cast",
3904 "Value is not a FixedArray");
3905 }
3906
CheckCast(v8::Data * that)3907 void v8::ModuleRequest::CheckCast(v8::Data* that) {
3908 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3909 Utils::ApiCheck(obj->IsModuleRequest(), "v8::ModuleRequest::Cast",
3910 "Value is not a ModuleRequest");
3911 }
3912
CheckCast(v8::Data * that)3913 void v8::Module::CheckCast(v8::Data* that) {
3914 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3915 Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3916 }
3917
CheckCast(v8::Data * that)3918 void v8::Number::CheckCast(v8::Data* that) {
3919 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3920 Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3921 "Value is not a Number");
3922 }
3923
CheckCast(v8::Data * that)3924 void v8::Integer::CheckCast(v8::Data* that) {
3925 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3926 Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3927 "Value is not an Integer");
3928 }
3929
CheckCast(v8::Data * that)3930 void v8::Int32::CheckCast(v8::Data* that) {
3931 Utils::ApiCheck(Value::Cast(that)->IsInt32(), "v8::Int32::Cast",
3932 "Value is not a 32-bit signed integer");
3933 }
3934
CheckCast(v8::Data * that)3935 void v8::Uint32::CheckCast(v8::Data* that) {
3936 Utils::ApiCheck(Value::Cast(that)->IsUint32(), "v8::Uint32::Cast",
3937 "Value is not a 32-bit unsigned integer");
3938 }
3939
CheckCast(v8::Data * that)3940 void v8::BigInt::CheckCast(v8::Data* that) {
3941 Utils::ApiCheck(Value::Cast(that)->IsBigInt(), "v8::BigInt::Cast",
3942 "Value is not a BigInt");
3943 }
3944
CheckCast(v8::Data * that)3945 void v8::Context::CheckCast(v8::Data* that) {
3946 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3947 Utils::ApiCheck(obj->IsContext(), "v8::Context::Cast",
3948 "Value is not a Context");
3949 }
3950
CheckCast(Value * that)3951 void v8::Array::CheckCast(Value* that) {
3952 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3953 Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3954 }
3955
CheckCast(Value * that)3956 void v8::Map::CheckCast(Value* that) {
3957 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3958 Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3959 }
3960
CheckCast(Value * that)3961 void v8::Set::CheckCast(Value* that) {
3962 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3963 Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3964 }
3965
CheckCast(Value * that)3966 void v8::Promise::CheckCast(Value* that) {
3967 Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3968 "Value is not a Promise");
3969 }
3970
CheckCast(Value * that)3971 void v8::Promise::Resolver::CheckCast(Value* that) {
3972 Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3973 "Value is not a Promise::Resolver");
3974 }
3975
CheckCast(Value * that)3976 void v8::Proxy::CheckCast(Value* that) {
3977 Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3978 }
3979
CheckCast(Value * that)3980 void v8::WasmMemoryObject::CheckCast(Value* that) {
3981 Utils::ApiCheck(that->IsWasmMemoryObject(), "v8::WasmMemoryObject::Cast",
3982 "Value is not a WasmMemoryObject");
3983 }
3984
CheckCast(Value * that)3985 void v8::WasmModuleObject::CheckCast(Value* that) {
3986 Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3987 "Value is not a WasmModuleObject");
3988 }
3989
~BackingStore()3990 v8::BackingStore::~BackingStore() {
3991 auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3992 i_this->~BackingStore(); // manually call internal destructor
3993 }
3994
Data() const3995 void* v8::BackingStore::Data() const {
3996 return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3997 }
3998
ByteLength() const3999 size_t v8::BackingStore::ByteLength() const {
4000 return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
4001 }
4002
IsShared() const4003 bool v8::BackingStore::IsShared() const {
4004 return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
4005 }
4006
4007 // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)4008 std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
4009 v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
4010 size_t byte_length) {
4011 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
4012 API_RCS_SCOPE(i_isolate, ArrayBuffer, BackingStore_Reallocate);
4013 Utils::ApiCheck(byte_length <= i::JSArrayBuffer::kMaxByteLength,
4014 "v8::BackingStore::Reallocate", "byte_lenght is too large");
4015 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
4016 i::BackingStore* i_backing_store =
4017 reinterpret_cast<i::BackingStore*>(backing_store.get());
4018 if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
4019 i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
4020 }
4021 return backing_store;
4022 }
4023
4024 // static
EmptyDeleter(void * data,size_t length,void * deleter_data)4025 void v8::BackingStore::EmptyDeleter(void* data, size_t length,
4026 void* deleter_data) {
4027 DCHECK_NULL(deleter_data);
4028 }
4029
GetBackingStore()4030 std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
4031 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4032 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4033 if (!backing_store) {
4034 backing_store =
4035 i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
4036 }
4037 std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4038 return std::static_pointer_cast<v8::BackingStore>(bs_base);
4039 }
4040
Data() const4041 void* v8::ArrayBuffer::Data() const {
4042 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4043 return self->backing_store();
4044 }
4045
GetBackingStore()4046 std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
4047 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4048 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
4049 if (!backing_store) {
4050 backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
4051 }
4052 std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
4053 return std::static_pointer_cast<v8::BackingStore>(bs_base);
4054 }
4055
Data() const4056 void* v8::SharedArrayBuffer::Data() const {
4057 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
4058 return self->backing_store();
4059 }
4060
CheckCast(Value * that)4061 void v8::ArrayBuffer::CheckCast(Value* that) {
4062 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4063 Utils::ApiCheck(
4064 obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
4065 "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
4066 }
4067
CheckCast(Value * that)4068 void v8::ArrayBufferView::CheckCast(Value* that) {
4069 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4070 Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
4071 "Value is not an ArrayBufferView");
4072 }
4073
4074 constexpr size_t v8::TypedArray::kMaxLength;
4075
CheckCast(Value * that)4076 void v8::TypedArray::CheckCast(Value* that) {
4077 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4078 Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
4079 "Value is not a TypedArray");
4080 }
4081
4082 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype) \
4083 void v8::Type##Array::CheckCast(Value* that) { \
4084 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
4085 Utils::ApiCheck( \
4086 obj->IsJSTypedArray() && \
4087 i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
4088 "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array"); \
4089 }
4090
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)4091 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4092
4093 #undef CHECK_TYPED_ARRAY_CAST
4094
4095 void v8::DataView::CheckCast(Value* that) {
4096 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4097 Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
4098 "Value is not a DataView");
4099 }
4100
CheckCast(Value * that)4101 void v8::SharedArrayBuffer::CheckCast(Value* that) {
4102 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4103 Utils::ApiCheck(
4104 obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
4105 "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
4106 }
4107
CheckCast(v8::Value * that)4108 void v8::Date::CheckCast(v8::Value* that) {
4109 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4110 Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
4111 }
4112
CheckCast(v8::Value * that)4113 void v8::StringObject::CheckCast(v8::Value* that) {
4114 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4115 Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
4116 "Value is not a StringObject");
4117 }
4118
CheckCast(v8::Value * that)4119 void v8::SymbolObject::CheckCast(v8::Value* that) {
4120 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4121 Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
4122 "Value is not a SymbolObject");
4123 }
4124
CheckCast(v8::Value * that)4125 void v8::NumberObject::CheckCast(v8::Value* that) {
4126 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4127 Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
4128 "Value is not a NumberObject");
4129 }
4130
CheckCast(v8::Value * that)4131 void v8::BigIntObject::CheckCast(v8::Value* that) {
4132 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4133 Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
4134 "Value is not a BigIntObject");
4135 }
4136
CheckCast(v8::Value * that)4137 void v8::BooleanObject::CheckCast(v8::Value* that) {
4138 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4139 Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
4140 "Value is not a BooleanObject");
4141 }
4142
CheckCast(v8::Value * that)4143 void v8::RegExp::CheckCast(v8::Value* that) {
4144 i::Handle<i::Object> obj = Utils::OpenHandle(that);
4145 Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
4146 "Value is not a RegExp");
4147 }
4148
NumberValue(Local<Context> context) const4149 Maybe<double> Value::NumberValue(Local<Context> context) const {
4150 auto obj = Utils::OpenHandle(this);
4151 if (obj->IsNumber()) return Just(obj->Number());
4152 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4153 ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4154 i::HandleScope);
4155 i::Handle<i::Object> num;
4156 has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
4157 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4158 return Just(num->Number());
4159 }
4160
IntegerValue(Local<Context> context) const4161 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4162 auto obj = Utils::OpenHandle(this);
4163 if (obj->IsNumber()) {
4164 return Just(NumberToInt64(*obj));
4165 }
4166 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4167 ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4168 i::HandleScope);
4169 i::Handle<i::Object> num;
4170 has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4171 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4172 return Just(NumberToInt64(*num));
4173 }
4174
Int32Value(Local<Context> context) const4175 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4176 auto obj = Utils::OpenHandle(this);
4177 if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4178 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4179 ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4180 i::HandleScope);
4181 i::Handle<i::Object> num;
4182 has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4183 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4184 return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4185 : static_cast<int32_t>(num->Number()));
4186 }
4187
Uint32Value(Local<Context> context) const4188 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4189 auto obj = Utils::OpenHandle(this);
4190 if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4191 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4192 ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4193 i::HandleScope);
4194 i::Handle<i::Object> num;
4195 has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4196 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4197 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4198 : static_cast<uint32_t>(num->Number()));
4199 }
4200
ToArrayIndex(Local<Context> context) const4201 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4202 auto self = Utils::OpenHandle(this);
4203 if (self->IsSmi()) {
4204 if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4205 return Local<Uint32>();
4206 }
4207 PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4208 i::Handle<i::Object> string_obj;
4209 has_pending_exception =
4210 !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4211 RETURN_ON_FAILED_EXECUTION(Uint32);
4212 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4213 uint32_t index;
4214 if (str->AsArrayIndex(&index)) {
4215 i::Handle<i::Object> value;
4216 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4217 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4218 } else {
4219 value = isolate->factory()->NewNumber(index);
4220 }
4221 RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4222 }
4223 return Local<Uint32>();
4224 }
4225
Equals(Local<Context> context,Local<Value> that) const4226 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4227 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4228 ENTER_V8(isolate, context, Value, Equals, Nothing<bool>(), i::HandleScope);
4229 auto self = Utils::OpenHandle(this);
4230 auto other = Utils::OpenHandle(*that);
4231 Maybe<bool> result = i::Object::Equals(isolate, self, other);
4232 has_pending_exception = result.IsNothing();
4233 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4234 return result;
4235 }
4236
StrictEquals(Local<Value> that) const4237 bool Value::StrictEquals(Local<Value> that) const {
4238 auto self = Utils::OpenHandle(this);
4239 auto other = Utils::OpenHandle(*that);
4240 return self->StrictEquals(*other);
4241 }
4242
SameValue(Local<Value> that) const4243 bool Value::SameValue(Local<Value> that) const {
4244 auto self = Utils::OpenHandle(this);
4245 auto other = Utils::OpenHandle(*that);
4246 return self->SameValue(*other);
4247 }
4248
TypeOf(v8::Isolate * external_isolate)4249 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4250 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4251 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4252 API_RCS_SCOPE(isolate, Value, TypeOf);
4253 return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4254 }
4255
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4256 Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4257 v8::Local<v8::Object> object) {
4258 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4259 ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4260 i::HandleScope);
4261 auto left = Utils::OpenHandle(this);
4262 auto right = Utils::OpenHandle(*object);
4263 i::Handle<i::Object> result;
4264 has_pending_exception =
4265 !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4266 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4267 return Just(result->IsTrue(isolate));
4268 }
4269
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4270 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4271 v8::Local<Value> key, v8::Local<Value> value) {
4272 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4273 ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4274 auto self = Utils::OpenHandle(this);
4275 auto key_obj = Utils::OpenHandle(*key);
4276 auto value_obj = Utils::OpenHandle(*value);
4277 has_pending_exception =
4278 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4279 i::StoreOrigin::kMaybeKeyed,
4280 Just(i::ShouldThrow::kDontThrow))
4281 .is_null();
4282 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4283 return Just(true);
4284 }
4285
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4286 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4287 v8::Local<Value> value) {
4288 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4289 ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4290 auto self = Utils::OpenHandle(this);
4291 auto value_obj = Utils::OpenHandle(*value);
4292 has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4293 i::ShouldThrow::kDontThrow)
4294 .is_null();
4295 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4296 return Just(true);
4297 }
4298
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4299 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4300 v8::Local<Name> key,
4301 v8::Local<Value> value) {
4302 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4303 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4304 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4305 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4306
4307 i::PropertyKey lookup_key(isolate, key_obj);
4308 i::LookupIterator it(isolate, self, lookup_key, i::LookupIterator::OWN);
4309 if (self->IsJSProxy()) {
4310 ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4311 i::HandleScope);
4312 Maybe<bool> result =
4313 i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4314 has_pending_exception = result.IsNothing();
4315 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4316 return result;
4317 } else {
4318 ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4319 Nothing<bool>(), i::HandleScope);
4320 Maybe<bool> result =
4321 i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4322 has_pending_exception = result.IsNothing();
4323 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4324 return result;
4325 }
4326 }
4327
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4328 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4329 uint32_t index,
4330 v8::Local<Value> value) {
4331 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4332 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4333 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4334
4335 i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4336 if (self->IsJSProxy()) {
4337 ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4338 i::HandleScope);
4339 Maybe<bool> result =
4340 i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4341 has_pending_exception = result.IsNothing();
4342 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4343 return result;
4344 } else {
4345 ENTER_V8_NO_SCRIPT(isolate, context, Object, CreateDataProperty,
4346 Nothing<bool>(), i::HandleScope);
4347 Maybe<bool> result =
4348 i::JSObject::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4349 has_pending_exception = result.IsNothing();
4350 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4351 return result;
4352 }
4353 }
4354
4355 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4356 PrivateData() : desc() {}
4357 i::PropertyDescriptor desc;
4358 };
4359
PropertyDescriptor()4360 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4361
4362 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4363 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4364 : private_(new PrivateData()) {
4365 private_->desc.set_value(Utils::OpenHandle(*value, true));
4366 }
4367
4368 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4369 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4370 bool writable)
4371 : private_(new PrivateData()) {
4372 private_->desc.set_value(Utils::OpenHandle(*value, true));
4373 private_->desc.set_writable(writable);
4374 }
4375
4376 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4377 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4378 v8::Local<v8::Value> set)
4379 : private_(new PrivateData()) {
4380 DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4381 DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4382 private_->desc.set_get(Utils::OpenHandle(*get, true));
4383 private_->desc.set_set(Utils::OpenHandle(*set, true));
4384 }
4385
~PropertyDescriptor()4386 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4387
value() const4388 v8::Local<Value> v8::PropertyDescriptor::value() const {
4389 DCHECK(private_->desc.has_value());
4390 return Utils::ToLocal(private_->desc.value());
4391 }
4392
get() const4393 v8::Local<Value> v8::PropertyDescriptor::get() const {
4394 DCHECK(private_->desc.has_get());
4395 return Utils::ToLocal(private_->desc.get());
4396 }
4397
set() const4398 v8::Local<Value> v8::PropertyDescriptor::set() const {
4399 DCHECK(private_->desc.has_set());
4400 return Utils::ToLocal(private_->desc.set());
4401 }
4402
has_value() const4403 bool v8::PropertyDescriptor::has_value() const {
4404 return private_->desc.has_value();
4405 }
has_get() const4406 bool v8::PropertyDescriptor::has_get() const {
4407 return private_->desc.has_get();
4408 }
has_set() const4409 bool v8::PropertyDescriptor::has_set() const {
4410 return private_->desc.has_set();
4411 }
4412
writable() const4413 bool v8::PropertyDescriptor::writable() const {
4414 DCHECK(private_->desc.has_writable());
4415 return private_->desc.writable();
4416 }
4417
has_writable() const4418 bool v8::PropertyDescriptor::has_writable() const {
4419 return private_->desc.has_writable();
4420 }
4421
set_enumerable(bool enumerable)4422 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4423 private_->desc.set_enumerable(enumerable);
4424 }
4425
enumerable() const4426 bool v8::PropertyDescriptor::enumerable() const {
4427 DCHECK(private_->desc.has_enumerable());
4428 return private_->desc.enumerable();
4429 }
4430
has_enumerable() const4431 bool v8::PropertyDescriptor::has_enumerable() const {
4432 return private_->desc.has_enumerable();
4433 }
4434
set_configurable(bool configurable)4435 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4436 private_->desc.set_configurable(configurable);
4437 }
4438
configurable() const4439 bool v8::PropertyDescriptor::configurable() const {
4440 DCHECK(private_->desc.has_configurable());
4441 return private_->desc.configurable();
4442 }
4443
has_configurable() const4444 bool v8::PropertyDescriptor::has_configurable() const {
4445 return private_->desc.has_configurable();
4446 }
4447
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4448 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4449 v8::Local<Name> key,
4450 v8::Local<Value> value,
4451 v8::PropertyAttribute attributes) {
4452 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4453 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4454 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4455 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4456
4457 i::PropertyDescriptor desc;
4458 desc.set_writable(!(attributes & v8::ReadOnly));
4459 desc.set_enumerable(!(attributes & v8::DontEnum));
4460 desc.set_configurable(!(attributes & v8::DontDelete));
4461 desc.set_value(value_obj);
4462
4463 if (self->IsJSProxy()) {
4464 ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4465 i::HandleScope);
4466 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4467 isolate, self, key_obj, &desc, Just(i::kDontThrow));
4468 // Even though we said kDontThrow, there might be accessors that do throw.
4469 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4470 return success;
4471 } else {
4472 // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4473 // a script.
4474 ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4475 Nothing<bool>(), i::HandleScope);
4476 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4477 isolate, self, key_obj, &desc, Just(i::kDontThrow));
4478 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4479 return success;
4480 }
4481 }
4482
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4483 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4484 v8::Local<Name> key,
4485 PropertyDescriptor& descriptor) {
4486 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4487 ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4488 i::HandleScope);
4489 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4490 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4491
4492 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4493 isolate, self, key_obj, &descriptor.get_private()->desc,
4494 Just(i::kDontThrow));
4495 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4496 return success;
4497 }
4498
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4499 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4500 Local<Value> value) {
4501 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4502 ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4503 i::HandleScope);
4504 auto self = Utils::OpenHandle(this);
4505 auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4506 auto value_obj = Utils::OpenHandle(*value);
4507 if (self->IsJSProxy()) {
4508 i::PropertyDescriptor desc;
4509 desc.set_writable(true);
4510 desc.set_enumerable(false);
4511 desc.set_configurable(true);
4512 desc.set_value(value_obj);
4513 return i::JSProxy::SetPrivateSymbol(
4514 isolate, i::Handle<i::JSProxy>::cast(self),
4515 i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4516 }
4517 auto js_object = i::Handle<i::JSObject>::cast(self);
4518 i::LookupIterator it(isolate, js_object, key_obj, js_object);
4519 has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4520 &it, value_obj, i::DONT_ENUM)
4521 .is_null();
4522 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4523 return Just(true);
4524 }
4525
Get(Local<v8::Context> context,Local<Value> key)4526 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4527 Local<Value> key) {
4528 PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4529 auto self = Utils::OpenHandle(this);
4530 auto key_obj = Utils::OpenHandle(*key);
4531 i::Handle<i::Object> result;
4532 has_pending_exception =
4533 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4534 RETURN_ON_FAILED_EXECUTION(Value);
4535 RETURN_ESCAPED(Utils::ToLocal(result));
4536 }
4537
Get(Local<Context> context,uint32_t index)4538 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4539 PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4540 auto self = Utils::OpenHandle(this);
4541 i::Handle<i::Object> result;
4542 has_pending_exception =
4543 !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4544 RETURN_ON_FAILED_EXECUTION(Value);
4545 RETURN_ESCAPED(Utils::ToLocal(result));
4546 }
4547
GetPrivate(Local<Context> context,Local<Private> key)4548 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4549 Local<Private> key) {
4550 return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4551 }
4552
GetPropertyAttributes(Local<Context> context,Local<Value> key)4553 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4554 Local<Context> context, Local<Value> key) {
4555 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4556 ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4557 Nothing<PropertyAttribute>(), i::HandleScope);
4558 auto self = Utils::OpenHandle(this);
4559 auto key_obj = Utils::OpenHandle(*key);
4560 if (!key_obj->IsName()) {
4561 has_pending_exception =
4562 !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4563 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4564 }
4565 auto key_name = i::Handle<i::Name>::cast(key_obj);
4566 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4567 has_pending_exception = result.IsNothing();
4568 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4569 if (result.FromJust() == i::ABSENT) {
4570 return Just(static_cast<PropertyAttribute>(i::NONE));
4571 }
4572 return Just(static_cast<PropertyAttribute>(result.FromJust()));
4573 }
4574
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4575 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4576 Local<Name> key) {
4577 PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4578 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4579 i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4580
4581 i::PropertyDescriptor desc;
4582 Maybe<bool> found =
4583 i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4584 has_pending_exception = found.IsNothing();
4585 RETURN_ON_FAILED_EXECUTION(Value);
4586 if (!found.FromJust()) {
4587 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4588 }
4589 RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4590 }
4591
GetPrototype()4592 Local<Value> v8::Object::GetPrototype() {
4593 auto self = Utils::OpenHandle(this);
4594 auto isolate = self->GetIsolate();
4595 i::PrototypeIterator iter(isolate, self);
4596 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4597 }
4598
SetPrototype(Local<Context> context,Local<Value> value)4599 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4600 Local<Value> value) {
4601 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4602 auto self = Utils::OpenHandle(this);
4603 auto value_obj = Utils::OpenHandle(*value);
4604 if (self->IsJSProxy()) {
4605 ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4606 i::HandleScope);
4607 // We do not allow exceptions thrown while setting the prototype
4608 // to propagate outside.
4609 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4610 auto result =
4611 i::JSProxy::SetPrototype(isolate, i::Handle<i::JSProxy>::cast(self),
4612 value_obj, false, i::kThrowOnError);
4613 has_pending_exception = result.IsNothing();
4614 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4615 } else {
4616 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4617 auto result =
4618 i::JSObject::SetPrototype(isolate, i::Handle<i::JSObject>::cast(self),
4619 value_obj, false, i::kThrowOnError);
4620 if (result.IsNothing()) {
4621 isolate->clear_pending_exception();
4622 return Nothing<bool>();
4623 }
4624 }
4625 return Just(true);
4626 }
4627
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4628 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4629 v8::Local<FunctionTemplate> tmpl) {
4630 auto self = Utils::OpenHandle(this);
4631 auto isolate = self->GetIsolate();
4632 i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4633 auto tmpl_info = *Utils::OpenHandle(*tmpl);
4634 while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4635 iter.Advance();
4636 if (iter.IsAtEnd()) return Local<Object>();
4637 if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4638 }
4639 // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4640 return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4641 }
4642
GetPropertyNames(Local<Context> context)4643 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4644 return GetPropertyNames(
4645 context, v8::KeyCollectionMode::kIncludePrototypes,
4646 static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4647 v8::IndexFilter::kIncludeIndices);
4648 }
4649
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4650 MaybeLocal<Array> v8::Object::GetPropertyNames(
4651 Local<Context> context, KeyCollectionMode mode,
4652 PropertyFilter property_filter, IndexFilter index_filter,
4653 KeyConversionMode key_conversion) {
4654 PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4655 auto self = Utils::OpenHandle(this);
4656 i::Handle<i::FixedArray> value;
4657 i::KeyAccumulator accumulator(
4658 isolate, static_cast<i::KeyCollectionMode>(mode),
4659 static_cast<i::PropertyFilter>(property_filter));
4660 accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4661 has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4662 RETURN_ON_FAILED_EXECUTION(Array);
4663 value =
4664 accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4665 DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4666 self->map().EnumLength() == 0 ||
4667 self->map().instance_descriptors(isolate).enum_cache().keys() !=
4668 *value);
4669 auto result = isolate->factory()->NewJSArrayWithElements(value);
4670 RETURN_ESCAPED(Utils::ToLocal(result));
4671 }
4672
GetOwnPropertyNames(Local<Context> context)4673 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4674 return GetOwnPropertyNames(
4675 context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4676 }
4677
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4678 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4679 Local<Context> context, PropertyFilter filter,
4680 KeyConversionMode key_conversion) {
4681 return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4682 v8::IndexFilter::kIncludeIndices, key_conversion);
4683 }
4684
ObjectProtoToString(Local<Context> context)4685 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4686 PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4687 auto self = Utils::OpenHandle(this);
4688 Local<Value> result;
4689 has_pending_exception = !ToLocal<Value>(
4690 i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4691 nullptr),
4692 &result);
4693 RETURN_ON_FAILED_EXECUTION(String);
4694 RETURN_ESCAPED(Local<String>::Cast(result));
4695 }
4696
GetConstructorName()4697 Local<String> v8::Object::GetConstructorName() {
4698 auto self = Utils::OpenHandle(this);
4699 // TODO(v8:12547): Support shared objects.
4700 DCHECK(!self->InSharedHeap());
4701 i::Handle<i::String> name =
4702 i::JSReceiver::GetConstructorName(self->GetIsolate(), self);
4703 return Utils::ToLocal(name);
4704 }
4705
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4706 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4707 IntegrityLevel level) {
4708 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4709 ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4710 i::HandleScope);
4711 auto self = Utils::OpenHandle(this);
4712 i::JSReceiver::IntegrityLevel i_level =
4713 level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4714 Maybe<bool> result =
4715 i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4716 has_pending_exception = result.IsNothing();
4717 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4718 return result;
4719 }
4720
Delete(Local<Context> context,Local<Value> key)4721 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4722 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4723 auto self = Utils::OpenHandle(this);
4724 auto key_obj = Utils::OpenHandle(*key);
4725 if (self->IsJSProxy()) {
4726 ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4727 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4728 isolate, self, key_obj, i::LanguageMode::kSloppy);
4729 has_pending_exception = result.IsNothing();
4730 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4731 return result;
4732 } else {
4733 // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4734 // a script.
4735 ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4736 i::HandleScope);
4737 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4738 isolate, self, key_obj, i::LanguageMode::kSloppy);
4739 has_pending_exception = result.IsNothing();
4740 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4741 return result;
4742 }
4743 }
4744
DeletePrivate(Local<Context> context,Local<Private> key)4745 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4746 Local<Private> key) {
4747 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4748 // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4749 // any author script.
4750 ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4751 i::HandleScope);
4752 auto self = Utils::OpenHandle(this);
4753 auto key_obj = Utils::OpenHandle(*key);
4754 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4755 isolate, self, key_obj, i::LanguageMode::kSloppy);
4756 has_pending_exception = result.IsNothing();
4757 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4758 return result;
4759 }
4760
Has(Local<Context> context,Local<Value> key)4761 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4762 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4763 ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4764 auto self = Utils::OpenHandle(this);
4765 auto key_obj = Utils::OpenHandle(*key);
4766 Maybe<bool> maybe = Nothing<bool>();
4767 // Check if the given key is an array index.
4768 uint32_t index = 0;
4769 if (key_obj->ToArrayIndex(&index)) {
4770 maybe = i::JSReceiver::HasElement(isolate, self, index);
4771 } else {
4772 // Convert the key to a name - possibly by calling back into JavaScript.
4773 i::Handle<i::Name> name;
4774 if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4775 maybe = i::JSReceiver::HasProperty(isolate, self, name);
4776 }
4777 }
4778 has_pending_exception = maybe.IsNothing();
4779 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4780 return maybe;
4781 }
4782
HasPrivate(Local<Context> context,Local<Private> key)4783 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4784 return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4785 }
4786
Delete(Local<Context> context,uint32_t index)4787 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4788 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4789 ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4790 auto self = Utils::OpenHandle(this);
4791 Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4792 has_pending_exception = result.IsNothing();
4793 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4794 return result;
4795 }
4796
Has(Local<Context> context,uint32_t index)4797 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4798 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4799 ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4800 auto self = Utils::OpenHandle(this);
4801 auto maybe = i::JSReceiver::HasElement(isolate, self, index);
4802 has_pending_exception = maybe.IsNothing();
4803 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4804 return maybe;
4805 }
4806
4807 template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4808 static Maybe<bool> ObjectSetAccessor(
4809 Local<Context> context, Object* self, Local<Name> name, Getter getter,
4810 Setter setter, Data data, AccessControl settings,
4811 PropertyAttribute attributes, bool is_special_data_property,
4812 bool replace_on_access, SideEffectType getter_side_effect_type,
4813 SideEffectType setter_side_effect_type) {
4814 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4815 ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4816 i::HandleScope);
4817 if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4818 i::Handle<i::JSObject> obj =
4819 i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4820 v8::Local<AccessorSignature> signature;
4821 i::Handle<i::AccessorInfo> info =
4822 MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4823 is_special_data_property, replace_on_access);
4824 info->set_getter_side_effect_type(getter_side_effect_type);
4825 info->set_setter_side_effect_type(setter_side_effect_type);
4826 if (info.is_null()) return Nothing<bool>();
4827 bool fast = obj->HasFastProperties();
4828 i::Handle<i::Object> result;
4829
4830 i::Handle<i::Name> accessor_name(info->name(), isolate);
4831 i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4832 has_pending_exception =
4833 !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4834 .ToHandle(&result);
4835 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4836 if (result->IsUndefined(isolate)) return Just(false);
4837 if (fast) {
4838 i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4839 }
4840 return Just(true);
4841 }
4842
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4843 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4844 AccessorNameGetterCallback getter,
4845 AccessorNameSetterCallback setter,
4846 MaybeLocal<Value> data, AccessControl settings,
4847 PropertyAttribute attribute,
4848 SideEffectType getter_side_effect_type,
4849 SideEffectType setter_side_effect_type) {
4850 return ObjectSetAccessor(context, this, name, getter, setter,
4851 data.FromMaybe(Local<Value>()), settings, attribute,
4852 i::FLAG_disable_old_api_accessors, false,
4853 getter_side_effect_type, setter_side_effect_type);
4854 }
4855
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4856 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4857 Local<Function> setter,
4858 PropertyAttribute attribute,
4859 AccessControl settings) {
4860 // TODO(verwaest): Remove |settings|.
4861 DCHECK_EQ(v8::DEFAULT, settings);
4862 auto self = Utils::OpenHandle(this);
4863 i::Isolate* isolate = self->GetIsolate();
4864 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4865 i::HandleScope scope(isolate);
4866 if (!self->IsJSObject()) return;
4867 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4868 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4869 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4870 i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4871 v8::Utils::OpenHandle(*name), getter_i, setter_i,
4872 static_cast<i::PropertyAttributes>(attribute));
4873 }
4874
SetNativeDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4875 Maybe<bool> Object::SetNativeDataProperty(
4876 v8::Local<v8::Context> context, v8::Local<Name> name,
4877 AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4878 v8::Local<Value> data, PropertyAttribute attributes,
4879 SideEffectType getter_side_effect_type,
4880 SideEffectType setter_side_effect_type) {
4881 return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4882 attributes, true, false, getter_side_effect_type,
4883 setter_side_effect_type);
4884 }
4885
SetLazyDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4886 Maybe<bool> Object::SetLazyDataProperty(
4887 v8::Local<v8::Context> context, v8::Local<Name> name,
4888 AccessorNameGetterCallback getter, v8::Local<Value> data,
4889 PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4890 SideEffectType setter_side_effect_type) {
4891 return ObjectSetAccessor(context, this, name, getter,
4892 static_cast<AccessorNameSetterCallback>(nullptr),
4893 data, DEFAULT, attributes, true, true,
4894 getter_side_effect_type, setter_side_effect_type);
4895 }
4896
HasOwnProperty(Local<Context> context,Local<Name> key)4897 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4898 Local<Name> key) {
4899 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4900 ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4901 i::HandleScope);
4902 auto self = Utils::OpenHandle(this);
4903 auto key_val = Utils::OpenHandle(*key);
4904 auto result = i::JSReceiver::HasOwnProperty(isolate, self, key_val);
4905 has_pending_exception = result.IsNothing();
4906 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4907 return result;
4908 }
4909
HasOwnProperty(Local<Context> context,uint32_t index)4910 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4911 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4912 ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4913 i::HandleScope);
4914 auto self = Utils::OpenHandle(this);
4915 auto result = i::JSReceiver::HasOwnProperty(isolate, self, index);
4916 has_pending_exception = result.IsNothing();
4917 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4918 return result;
4919 }
4920
HasRealNamedProperty(Local<Context> context,Local<Name> key)4921 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4922 Local<Name> key) {
4923 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4924 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4925 Nothing<bool>(), i::HandleScope);
4926 auto self = Utils::OpenHandle(this);
4927 if (!self->IsJSObject()) return Just(false);
4928 auto key_val = Utils::OpenHandle(*key);
4929 auto result = i::JSObject::HasRealNamedProperty(
4930 isolate, i::Handle<i::JSObject>::cast(self), key_val);
4931 has_pending_exception = result.IsNothing();
4932 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4933 return result;
4934 }
4935
HasRealIndexedProperty(Local<Context> context,uint32_t index)4936 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4937 uint32_t index) {
4938 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4939 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4940 Nothing<bool>(), i::HandleScope);
4941 auto self = Utils::OpenHandle(this);
4942 if (!self->IsJSObject()) return Just(false);
4943 auto result = i::JSObject::HasRealElementProperty(
4944 isolate, i::Handle<i::JSObject>::cast(self), index);
4945 has_pending_exception = result.IsNothing();
4946 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4947 return result;
4948 }
4949
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4950 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4951 Local<Name> key) {
4952 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4953 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
4954 Nothing<bool>(), i::HandleScope);
4955 auto self = Utils::OpenHandle(this);
4956 if (!self->IsJSObject()) return Just(false);
4957 auto key_val = Utils::OpenHandle(*key);
4958 auto result = i::JSObject::HasRealNamedCallbackProperty(
4959 isolate, i::Handle<i::JSObject>::cast(self), key_val);
4960 has_pending_exception = result.IsNothing();
4961 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4962 return result;
4963 }
4964
HasNamedLookupInterceptor() const4965 bool v8::Object::HasNamedLookupInterceptor() const {
4966 auto self = *Utils::OpenHandle(this);
4967 if (self.IsJSObject()) return false;
4968 return i::JSObject::cast(self).HasNamedInterceptor();
4969 }
4970
HasIndexedLookupInterceptor() const4971 bool v8::Object::HasIndexedLookupInterceptor() const {
4972 auto self = *Utils::OpenHandle(this);
4973 if (self.IsJSObject()) return false;
4974 return i::JSObject::cast(self).HasIndexedInterceptor();
4975 }
4976
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4977 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4978 Local<Context> context, Local<Name> key) {
4979 PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4980 Value);
4981 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4982 if (!self->IsJSObject()) return MaybeLocal<Value>();
4983 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4984 i::PrototypeIterator iter(isolate, self);
4985 if (iter.IsAtEnd()) return MaybeLocal<Value>();
4986 i::Handle<i::JSReceiver> proto =
4987 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4988 i::PropertyKey lookup_key(isolate, key_obj);
4989 i::LookupIterator it(isolate, self, lookup_key, proto,
4990 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4991 Local<Value> result;
4992 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4993 RETURN_ON_FAILED_EXECUTION(Value);
4994 if (!it.IsFound()) return MaybeLocal<Value>();
4995 RETURN_ESCAPED(result);
4996 }
4997
4998 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4999 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
5000 Local<Context> context, Local<Name> key) {
5001 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5002 ENTER_V8(isolate, context, Object,
5003 GetRealNamedPropertyAttributesInPrototypeChain,
5004 Nothing<PropertyAttribute>(), i::HandleScope);
5005 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5006 if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
5007 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5008 i::PrototypeIterator iter(isolate, self);
5009 if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
5010 i::Handle<i::JSReceiver> proto =
5011 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5012 i::PropertyKey lookup_key(isolate, key_obj);
5013 i::LookupIterator it(isolate, self, lookup_key, proto,
5014 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5015 Maybe<i::PropertyAttributes> result =
5016 i::JSReceiver::GetPropertyAttributes(&it);
5017 has_pending_exception = result.IsNothing();
5018 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5019 if (!it.IsFound()) return Nothing<PropertyAttribute>();
5020 if (result.FromJust() == i::ABSENT) return Just(None);
5021 return Just(static_cast<PropertyAttribute>(result.FromJust()));
5022 }
5023
GetRealNamedProperty(Local<Context> context,Local<Name> key)5024 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
5025 Local<Name> key) {
5026 PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
5027 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5028 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5029 i::PropertyKey lookup_key(isolate, key_obj);
5030 i::LookupIterator it(isolate, self, lookup_key, self,
5031 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5032 Local<Value> result;
5033 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5034 RETURN_ON_FAILED_EXECUTION(Value);
5035 if (!it.IsFound()) return MaybeLocal<Value>();
5036 RETURN_ESCAPED(result);
5037 }
5038
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)5039 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5040 Local<Context> context, Local<Name> key) {
5041 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5042 ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
5043 Nothing<PropertyAttribute>(), i::HandleScope);
5044 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5045 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5046 i::PropertyKey lookup_key(isolate, key_obj);
5047 i::LookupIterator it(isolate, self, lookup_key, self,
5048 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5049 auto result = i::JSReceiver::GetPropertyAttributes(&it);
5050 has_pending_exception = result.IsNothing();
5051 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5052 if (!it.IsFound()) return Nothing<PropertyAttribute>();
5053 if (result.FromJust() == i::ABSENT) {
5054 return Just(static_cast<PropertyAttribute>(i::NONE));
5055 }
5056 return Just<PropertyAttribute>(
5057 static_cast<PropertyAttribute>(result.FromJust()));
5058 }
5059
Clone()5060 Local<v8::Object> v8::Object::Clone() {
5061 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5062 auto isolate = self->GetIsolate();
5063 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5064 i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
5065 return Utils::ToLocal(result);
5066 }
5067
5068 namespace {
CreationContextImpl(i::Handle<i::JSReceiver> self)5069 Local<v8::Context> CreationContextImpl(i::Handle<i::JSReceiver> self) {
5070 i::Handle<i::Context> context;
5071 if (self->GetCreationContext().ToHandle(&context)) {
5072 return Utils::ToLocal(context);
5073 }
5074
5075 return Local<v8::Context>();
5076 }
5077 } // namespace
5078
CreationContext()5079 Local<v8::Context> v8::Object::CreationContext() {
5080 auto self = Utils::OpenHandle(this);
5081 return CreationContextImpl(self);
5082 }
5083
CreationContext(const PersistentBase<Object> & object)5084 Local<v8::Context> v8::Object::CreationContext(
5085 const PersistentBase<Object>& object) {
5086 auto self = Utils::OpenHandle(object.val_);
5087 return CreationContextImpl(self);
5088 }
5089
GetCreationContext()5090 MaybeLocal<v8::Context> v8::Object::GetCreationContext() {
5091 auto self = Utils::OpenHandle(this);
5092 i::Handle<i::Context> context;
5093 if (self->GetCreationContext().ToHandle(&context)) {
5094 return Utils::ToLocal(context);
5095 }
5096 return MaybeLocal<v8::Context>();
5097 }
5098
GetCreationContextChecked()5099 Local<v8::Context> v8::Object::GetCreationContextChecked() {
5100 Local<Context> context;
5101 Utils::ApiCheck(GetCreationContext().ToLocal(&context),
5102 "v8::Object::GetCreationContextChecked",
5103 "No creation context available");
5104 return context;
5105 }
5106
GetIdentityHash()5107 int v8::Object::GetIdentityHash() {
5108 i::DisallowGarbageCollection no_gc;
5109 auto self = Utils::OpenHandle(this);
5110 auto isolate = self->GetIsolate();
5111 ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
5112 i::HandleScope scope(isolate);
5113 return self->GetOrCreateIdentityHash(isolate).value();
5114 }
5115
IsCallable() const5116 bool v8::Object::IsCallable() const {
5117 auto self = Utils::OpenHandle(this);
5118 return self->IsCallable();
5119 }
5120
IsConstructor() const5121 bool v8::Object::IsConstructor() const {
5122 auto self = Utils::OpenHandle(this);
5123 return self->IsConstructor();
5124 }
5125
IsApiWrapper() const5126 bool v8::Object::IsApiWrapper() const {
5127 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5128 // Objects with embedder fields can wrap API objects.
5129 return self->MayHaveEmbedderFields();
5130 }
5131
IsUndetectable() const5132 bool v8::Object::IsUndetectable() const {
5133 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5134 return self->IsUndetectable();
5135 }
5136
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])5137 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5138 Local<Value> recv, int argc,
5139 Local<Value> argv[]) {
5140 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5141 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5142 ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5143 InternalEscapableScope);
5144 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5145 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5146 isolate);
5147 auto self = Utils::OpenHandle(this);
5148 auto recv_obj = Utils::OpenHandle(*recv);
5149 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5150 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5151 Local<Value> result;
5152 has_pending_exception = !ToLocal<Value>(
5153 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5154 RETURN_ON_FAILED_EXECUTION(Value);
5155 RETURN_ESCAPED(result);
5156 }
5157
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])5158 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5159 Local<Value> argv[]) {
5160 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5161 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5162 ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5163 InternalEscapableScope);
5164 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5165 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5166 isolate);
5167 auto self = Utils::OpenHandle(this);
5168 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5169 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5170 Local<Value> result;
5171 has_pending_exception = !ToLocal<Value>(
5172 i::Execution::New(isolate, self, self, argc, args), &result);
5173 RETURN_ON_FAILED_EXECUTION(Value);
5174 RETURN_ESCAPED(result);
5175 }
5176
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)5177 MaybeLocal<Function> Function::New(Local<Context> context,
5178 FunctionCallback callback, Local<Value> data,
5179 int length, ConstructorBehavior behavior,
5180 SideEffectType side_effect_type) {
5181 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5182 API_RCS_SCOPE(isolate, Function, New);
5183 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5184 auto templ =
5185 FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
5186 behavior, true, Local<Private>(), side_effect_type);
5187 return templ->GetFunction(context);
5188 }
5189
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const5190 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5191 v8::Local<v8::Value> argv[]) const {
5192 return NewInstanceWithSideEffectType(context, argc, argv,
5193 SideEffectType::kHasSideEffect);
5194 }
5195
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const5196 MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
5197 Local<Context> context, int argc, v8::Local<v8::Value> argv[],
5198 SideEffectType side_effect_type) const {
5199 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5200 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5201 ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5202 InternalEscapableScope);
5203 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5204 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5205 isolate);
5206 auto self = Utils::OpenHandle(this);
5207 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5208 bool should_set_has_no_side_effect =
5209 side_effect_type == SideEffectType::kHasNoSideEffect &&
5210 isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
5211 if (should_set_has_no_side_effect) {
5212 CHECK(self->IsJSFunction() &&
5213 i::JSFunction::cast(*self).shared().IsApiFunction());
5214 i::Object obj =
5215 i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5216 kAcquireLoad);
5217 if (obj.IsCallHandlerInfo()) {
5218 i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5219 if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
5220 handler_info.SetNextCallHasNoSideEffect();
5221 }
5222 }
5223 }
5224 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5225 Local<Object> result;
5226 has_pending_exception = !ToLocal<Object>(
5227 i::Execution::New(isolate, self, self, argc, args), &result);
5228 if (should_set_has_no_side_effect) {
5229 i::Object obj =
5230 i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
5231 kAcquireLoad);
5232 if (obj.IsCallHandlerInfo()) {
5233 i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
5234 if (has_pending_exception) {
5235 // Restore the map if an exception prevented restoration.
5236 handler_info.NextCallHasNoSideEffect();
5237 } else {
5238 DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
5239 handler_info.IsSideEffectFreeCallHandlerInfo());
5240 }
5241 }
5242 }
5243 RETURN_ON_FAILED_EXECUTION(Object);
5244 RETURN_ESCAPED(result);
5245 }
5246
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])5247 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5248 v8::Local<v8::Value> recv, int argc,
5249 v8::Local<v8::Value> argv[]) {
5250 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5251 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5252 ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5253 InternalEscapableScope);
5254 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5255 i::NestedTimedHistogramScope execute_timer(isolate->counters()->execute(),
5256 isolate);
5257 auto self = Utils::OpenHandle(this);
5258 Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
5259 "Function to be called is a null pointer");
5260 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5261 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
5262 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5263 Local<Value> result;
5264 has_pending_exception = !ToLocal<Value>(
5265 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5266 RETURN_ON_FAILED_EXECUTION(Value);
5267 RETURN_ESCAPED(result);
5268 }
5269
SetName(v8::Local<v8::String> name)5270 void Function::SetName(v8::Local<v8::String> name) {
5271 auto self = Utils::OpenHandle(this);
5272 if (!self->IsJSFunction()) return;
5273 auto func = i::Handle<i::JSFunction>::cast(self);
5274 ASSERT_NO_SCRIPT_NO_EXCEPTION(func->GetIsolate());
5275 func->shared().SetName(*Utils::OpenHandle(*name));
5276 }
5277
GetName() const5278 Local<Value> Function::GetName() const {
5279 auto self = Utils::OpenHandle(this);
5280 i::Isolate* isolate = self->GetIsolate();
5281 if (self->IsJSBoundFunction()) {
5282 auto func = i::Handle<i::JSBoundFunction>::cast(self);
5283 i::Handle<i::Object> name;
5284 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5285 i::JSBoundFunction::GetName(isolate, func),
5286 Local<Value>());
5287 return Utils::ToLocal(name);
5288 }
5289 if (self->IsJSFunction()) {
5290 auto func = i::Handle<i::JSFunction>::cast(self);
5291 return Utils::ToLocal(handle(func->shared().Name(), isolate));
5292 }
5293 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5294 }
5295
GetInferredName() const5296 Local<Value> Function::GetInferredName() const {
5297 auto self = Utils::OpenHandle(this);
5298 if (!self->IsJSFunction()) {
5299 return ToApiHandle<Primitive>(
5300 self->GetIsolate()->factory()->undefined_value());
5301 }
5302 auto func = i::Handle<i::JSFunction>::cast(self);
5303 return Utils::ToLocal(
5304 i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5305 }
5306
GetDebugName() const5307 Local<Value> Function::GetDebugName() const {
5308 auto self = Utils::OpenHandle(this);
5309 if (!self->IsJSFunction()) {
5310 return ToApiHandle<Primitive>(
5311 self->GetIsolate()->factory()->undefined_value());
5312 }
5313 auto func = i::Handle<i::JSFunction>::cast(self);
5314 i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5315 return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5316 }
5317
GetScriptOrigin() const5318 ScriptOrigin Function::GetScriptOrigin() const {
5319 auto self = Utils::OpenHandle(this);
5320 auto isolate = reinterpret_cast<v8::Isolate*>(self->GetIsolate());
5321 if (!self->IsJSFunction()) return v8::ScriptOrigin(isolate, Local<Value>());
5322 auto func = i::Handle<i::JSFunction>::cast(self);
5323 if (func->shared().script().IsScript()) {
5324 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5325 func->GetIsolate());
5326 return GetScriptOriginForScript(func->GetIsolate(), script);
5327 }
5328 return v8::ScriptOrigin(isolate, Local<Value>());
5329 }
5330
5331 const int Function::kLineOffsetNotFound = -1;
5332
GetScriptLineNumber() const5333 int Function::GetScriptLineNumber() const {
5334 auto self = Utils::OpenHandle(this);
5335 if (!self->IsJSFunction()) {
5336 return kLineOffsetNotFound;
5337 }
5338 auto func = i::Handle<i::JSFunction>::cast(self);
5339 if (func->shared().script().IsScript()) {
5340 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5341 func->GetIsolate());
5342 return i::Script::GetLineNumber(script, func->shared().StartPosition());
5343 }
5344 return kLineOffsetNotFound;
5345 }
5346
GetScriptColumnNumber() const5347 int Function::GetScriptColumnNumber() const {
5348 auto self = Utils::OpenHandle(this);
5349 if (!self->IsJSFunction()) {
5350 return kLineOffsetNotFound;
5351 }
5352 auto func = i::Handle<i::JSFunction>::cast(self);
5353 if (func->shared().script().IsScript()) {
5354 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5355 func->GetIsolate());
5356 return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5357 }
5358 return kLineOffsetNotFound;
5359 }
5360
GetUnboundScript() const5361 MaybeLocal<UnboundScript> Function::GetUnboundScript() const {
5362 i::Handle<i::Object> self = Utils::OpenHandle(this);
5363 if (!self->IsJSFunction()) return MaybeLocal<UnboundScript>();
5364 i::SharedFunctionInfo sfi = i::JSFunction::cast(*self).shared();
5365 i::Isolate* isolate = sfi.GetIsolate();
5366 return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
5367 }
5368
ScriptId() const5369 int Function::ScriptId() const {
5370 i::JSReceiver self = *Utils::OpenHandle(this);
5371 if (!self.IsJSFunction()) return v8::UnboundScript::kNoScriptId;
5372 auto func = i::JSFunction::cast(self);
5373 if (!func.shared().script().IsScript()) return v8::UnboundScript::kNoScriptId;
5374 return i::Script::cast(func.shared().script()).id();
5375 }
5376
GetBoundFunction() const5377 Local<v8::Value> Function::GetBoundFunction() const {
5378 auto self = Utils::OpenHandle(this);
5379 if (self->IsJSBoundFunction()) {
5380 auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5381 auto bound_target_function = i::handle(
5382 bound_function->bound_target_function(), bound_function->GetIsolate());
5383 return Utils::CallableToLocal(bound_target_function);
5384 }
5385 return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5386 }
5387
FunctionProtoToString(Local<Context> context)5388 MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5389 PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5390 auto self = Utils::OpenHandle(this);
5391 Local<Value> result;
5392 has_pending_exception = !ToLocal<Value>(
5393 i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5394 nullptr),
5395 &result);
5396 RETURN_ON_FAILED_EXECUTION(String);
5397 RETURN_ESCAPED(Local<String>::Cast(result));
5398 }
5399
GetIdentityHash()5400 int Name::GetIdentityHash() {
5401 auto self = Utils::OpenHandle(this);
5402 return static_cast<int>(self->EnsureHash());
5403 }
5404
Length() const5405 int String::Length() const {
5406 i::Handle<i::String> str = Utils::OpenHandle(this);
5407 return str->length();
5408 }
5409
IsOneByte() const5410 bool String::IsOneByte() const {
5411 i::Handle<i::String> str = Utils::OpenHandle(this);
5412 return str->IsOneByteRepresentation();
5413 }
5414
5415 // Helpers for ContainsOnlyOneByteHelper
5416 template <size_t size>
5417 struct OneByteMask;
5418 template <>
5419 struct OneByteMask<4> {
5420 static const uint32_t value = 0xFF00FF00;
5421 };
5422 template <>
5423 struct OneByteMask<8> {
5424 static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5425 };
5426 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5427 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5428 static inline bool Unaligned(const uint16_t* chars) {
5429 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5430 }
5431
Align(const uint16_t * chars)5432 static inline const uint16_t* Align(const uint16_t* chars) {
5433 return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5434 ~kAlignmentMask);
5435 }
5436
5437 class ContainsOnlyOneByteHelper {
5438 public:
ContainsOnlyOneByteHelper()5439 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5440 ContainsOnlyOneByteHelper(const ContainsOnlyOneByteHelper&) = delete;
5441 ContainsOnlyOneByteHelper& operator=(const ContainsOnlyOneByteHelper&) =
5442 delete;
Check(i::String string)5443 bool Check(i::String string) {
5444 i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5445 if (cons_string.is_null()) return is_one_byte_;
5446 return CheckCons(cons_string);
5447 }
VisitOneByteString(const uint8_t * chars,int length)5448 void VisitOneByteString(const uint8_t* chars, int length) {
5449 // Nothing to do.
5450 }
VisitTwoByteString(const uint16_t * chars,int length)5451 void VisitTwoByteString(const uint16_t* chars, int length) {
5452 // Accumulated bits.
5453 uintptr_t acc = 0;
5454 // Align to uintptr_t.
5455 const uint16_t* end = chars + length;
5456 while (Unaligned(chars) && chars != end) {
5457 acc |= *chars++;
5458 }
5459 // Read word aligned in blocks,
5460 // checking the return value at the end of each block.
5461 const uint16_t* aligned_end = Align(end);
5462 const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5463 const int inner_loops = 16;
5464 while (chars + inner_loops * increment < aligned_end) {
5465 for (int i = 0; i < inner_loops; i++) {
5466 acc |= *reinterpret_cast<const uintptr_t*>(chars);
5467 chars += increment;
5468 }
5469 // Check for early return.
5470 if ((acc & kOneByteMask) != 0) {
5471 is_one_byte_ = false;
5472 return;
5473 }
5474 }
5475 // Read the rest.
5476 while (chars != end) {
5477 acc |= *chars++;
5478 }
5479 // Check result.
5480 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5481 }
5482
5483 private:
CheckCons(i::ConsString cons_string)5484 bool CheckCons(i::ConsString cons_string) {
5485 while (true) {
5486 // Check left side if flat.
5487 i::String left = cons_string.first();
5488 i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5489 if (!is_one_byte_) return false;
5490 // Check right side if flat.
5491 i::String right = cons_string.second();
5492 i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5493 if (!is_one_byte_) return false;
5494 // Standard recurse/iterate trick.
5495 if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5496 if (left.length() < right.length()) {
5497 CheckCons(left_as_cons);
5498 cons_string = right_as_cons;
5499 } else {
5500 CheckCons(right_as_cons);
5501 cons_string = left_as_cons;
5502 }
5503 // Check fast return.
5504 if (!is_one_byte_) return false;
5505 continue;
5506 }
5507 // Descend left in place.
5508 if (!left_as_cons.is_null()) {
5509 cons_string = left_as_cons;
5510 continue;
5511 }
5512 // Descend right in place.
5513 if (!right_as_cons.is_null()) {
5514 cons_string = right_as_cons;
5515 continue;
5516 }
5517 // Terminate.
5518 break;
5519 }
5520 return is_one_byte_;
5521 }
5522 bool is_one_byte_;
5523 };
5524
ContainsOnlyOneByte() const5525 bool String::ContainsOnlyOneByte() const {
5526 i::Handle<i::String> str = Utils::OpenHandle(this);
5527 if (str->IsOneByteRepresentation()) return true;
5528 ContainsOnlyOneByteHelper helper;
5529 return helper.Check(*str);
5530 }
5531
Utf8Length(Isolate * isolate) const5532 int String::Utf8Length(Isolate* isolate) const {
5533 i::Handle<i::String> str = Utils::OpenHandle(this);
5534 str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5535 int length = str->length();
5536 if (length == 0) return 0;
5537 i::DisallowGarbageCollection no_gc;
5538 i::String::FlatContent flat = str->GetFlatContent(no_gc);
5539 DCHECK(flat.IsFlat());
5540 int utf8_length = 0;
5541 if (flat.IsOneByte()) {
5542 for (uint8_t c : flat.ToOneByteVector()) {
5543 utf8_length += c >> 7;
5544 }
5545 utf8_length += length;
5546 } else {
5547 int last_character = unibrow::Utf16::kNoPreviousCharacter;
5548 for (uint16_t c : flat.ToUC16Vector()) {
5549 utf8_length += unibrow::Utf8::Length(c, last_character);
5550 last_character = c;
5551 }
5552 }
5553 return utf8_length;
5554 }
5555
5556 namespace {
5557 // Writes the flat content of a string to a buffer. This is done in two phases.
5558 // The first phase calculates a pessimistic estimate (writable_length) on how
5559 // many code units can be safely written without exceeding the buffer capacity
5560 // and without leaving at a lone surrogate. The estimated number of code units
5561 // is then written out in one go, and the reported byte usage is used to
5562 // correct the estimate. This is repeated until the estimate becomes <= 0 or
5563 // all code units have been written out. The second phase writes out code
5564 // units until the buffer capacity is reached, would be exceeded by the next
5565 // unit, or all code units have been written out.
5566 template <typename Char>
WriteUtf8Impl(base::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5567 static int WriteUtf8Impl(base::Vector<const Char> string, char* write_start,
5568 int write_capacity, int options,
5569 int* utf16_chars_read_out) {
5570 bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5571 bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5572 char* current_write = write_start;
5573 const Char* read_start = string.begin();
5574 int read_index = 0;
5575 int read_length = string.length();
5576 int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5577 // Do a fast loop where there is no exit capacity check.
5578 // Need enough space to write everything but one character.
5579 STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5580 static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5581 while (read_index < read_length) {
5582 int up_to = read_length;
5583 if (write_capacity != -1) {
5584 int remaining_capacity =
5585 write_capacity - static_cast<int>(current_write - write_start);
5586 int writable_length =
5587 (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5588 // Need to drop into slow loop.
5589 if (writable_length <= 0) break;
5590 up_to = std::min(up_to, read_index + writable_length);
5591 }
5592 // Write the characters to the stream.
5593 if (sizeof(Char) == 1) {
5594 // Simply memcpy if we only have ASCII characters.
5595 uint8_t char_mask = 0;
5596 for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5597 if ((char_mask & 0x80) == 0) {
5598 int copy_length = up_to - read_index;
5599 memcpy(current_write, read_start + read_index, copy_length);
5600 current_write += copy_length;
5601 read_index = up_to;
5602 } else {
5603 for (; read_index < up_to; read_index++) {
5604 current_write += unibrow::Utf8::EncodeOneByte(
5605 current_write, static_cast<uint8_t>(read_start[read_index]));
5606 DCHECK(write_capacity == -1 ||
5607 (current_write - write_start) <= write_capacity);
5608 }
5609 }
5610 } else {
5611 for (; read_index < up_to; read_index++) {
5612 uint16_t character = read_start[read_index];
5613 current_write += unibrow::Utf8::Encode(current_write, character,
5614 prev_char, replace_invalid_utf8);
5615 prev_char = character;
5616 DCHECK(write_capacity == -1 ||
5617 (current_write - write_start) <= write_capacity);
5618 }
5619 }
5620 }
5621 if (read_index < read_length) {
5622 DCHECK_NE(-1, write_capacity);
5623 // Aborted due to limited capacity. Check capacity on each iteration.
5624 int remaining_capacity =
5625 write_capacity - static_cast<int>(current_write - write_start);
5626 DCHECK_GE(remaining_capacity, 0);
5627 for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5628 uint32_t character = read_start[read_index];
5629 int written = 0;
5630 // We can't use a local buffer here because Encode needs to modify
5631 // previous characters in the stream. We know, however, that
5632 // exactly one character will be advanced.
5633 if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5634 written = unibrow::Utf8::Encode(current_write, character, prev_char,
5635 replace_invalid_utf8);
5636 DCHECK_EQ(written, 1);
5637 } else {
5638 // Use a scratch buffer to check the required characters.
5639 char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5640 // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5641 static const int kSurrogatePairEncodedSize =
5642 static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5643 // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5644 // middle of a surrogate pair. Abort before encoding the pair instead.
5645 if (replace_invalid_utf8 &&
5646 remaining_capacity < kSurrogatePairEncodedSize &&
5647 unibrow::Utf16::IsLeadSurrogate(character) &&
5648 read_index + 1 < read_length &&
5649 unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5650 write_null = false;
5651 break;
5652 }
5653 // Can't encode using prev_char as gcc has array bounds issues.
5654 written = unibrow::Utf8::Encode(temp_buffer, character,
5655 unibrow::Utf16::kNoPreviousCharacter,
5656 replace_invalid_utf8);
5657 if (written > remaining_capacity) {
5658 // Won't fit. Abort and do not null-terminate the result.
5659 write_null = false;
5660 break;
5661 }
5662 // Copy over the character from temp_buffer.
5663 for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5664 }
5665
5666 current_write += written;
5667 remaining_capacity -= written;
5668 prev_char = character;
5669 }
5670 }
5671
5672 // Write out number of utf16 characters written to the stream.
5673 if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5674
5675 // Only null-terminate if there's space.
5676 if (write_null && (write_capacity == -1 ||
5677 (current_write - write_start) < write_capacity)) {
5678 *current_write++ = '\0';
5679 }
5680 return static_cast<int>(current_write - write_start);
5681 }
5682 } // anonymous namespace
5683
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5684 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5685 int* nchars_ref, int options) const {
5686 i::Handle<i::String> str = Utils::OpenHandle(this);
5687 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5688 API_RCS_SCOPE(isolate, String, WriteUtf8);
5689 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5690 str = i::String::Flatten(isolate, str);
5691 i::DisallowGarbageCollection no_gc;
5692 i::String::FlatContent content = str->GetFlatContent(no_gc);
5693 if (content.IsOneByte()) {
5694 return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5695 options, nchars_ref);
5696 } else {
5697 return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5698 options, nchars_ref);
5699 }
5700 }
5701
5702 template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5703 static inline int WriteHelper(i::Isolate* isolate, const String* string,
5704 CharType* buffer, int start, int length,
5705 int options) {
5706 API_RCS_SCOPE(isolate, String, Write);
5707 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5708 DCHECK(start >= 0 && length >= -1);
5709 i::Handle<i::String> str = Utils::OpenHandle(string);
5710 str = i::String::Flatten(isolate, str);
5711 int end = start + length;
5712 if ((length == -1) || (length > str->length() - start)) end = str->length();
5713 if (end < 0) return 0;
5714 int write_length = end - start;
5715 if (start < end) i::String::WriteToFlat(*str, buffer, start, write_length);
5716 if (!(options & String::NO_NULL_TERMINATION) &&
5717 (length == -1 || write_length < length)) {
5718 buffer[write_length] = '\0';
5719 }
5720 return write_length;
5721 }
5722
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5723 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5724 int length, int options) const {
5725 return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5726 start, length, options);
5727 }
5728
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5729 int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5730 int options) const {
5731 return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5732 start, length, options);
5733 }
5734
IsExternal() const5735 bool v8::String::IsExternal() const {
5736 i::Handle<i::String> str = Utils::OpenHandle(this);
5737 return i::StringShape(*str).IsExternal();
5738 }
5739
IsExternalTwoByte() const5740 bool v8::String::IsExternalTwoByte() const {
5741 i::Handle<i::String> str = Utils::OpenHandle(this);
5742 return i::StringShape(*str).IsExternalTwoByte();
5743 }
5744
IsExternalOneByte() const5745 bool v8::String::IsExternalOneByte() const {
5746 i::Handle<i::String> str = Utils::OpenHandle(this);
5747 return i::StringShape(*str).IsExternalOneByte();
5748 }
5749
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5750 void v8::String::VerifyExternalStringResource(
5751 v8::String::ExternalStringResource* value) const {
5752 i::DisallowGarbageCollection no_gc;
5753 i::String str = *Utils::OpenHandle(this);
5754 const v8::String::ExternalStringResource* expected;
5755
5756 if (str.IsThinString()) {
5757 str = i::ThinString::cast(str).actual();
5758 }
5759
5760 if (i::StringShape(str).IsExternalTwoByte()) {
5761 const void* resource = i::ExternalTwoByteString::cast(str).resource();
5762 expected = reinterpret_cast<const ExternalStringResource*>(resource);
5763 } else {
5764 expected = nullptr;
5765 }
5766 CHECK_EQ(expected, value);
5767 }
5768
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5769 void v8::String::VerifyExternalStringResourceBase(
5770 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5771 i::DisallowGarbageCollection no_gc;
5772 i::String str = *Utils::OpenHandle(this);
5773 const v8::String::ExternalStringResourceBase* expected;
5774 Encoding expectedEncoding;
5775
5776 if (str.IsThinString()) {
5777 str = i::ThinString::cast(str).actual();
5778 }
5779
5780 if (i::StringShape(str).IsExternalOneByte()) {
5781 const void* resource = i::ExternalOneByteString::cast(str).resource();
5782 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5783 expectedEncoding = ONE_BYTE_ENCODING;
5784 } else if (i::StringShape(str).IsExternalTwoByte()) {
5785 const void* resource = i::ExternalTwoByteString::cast(str).resource();
5786 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5787 expectedEncoding = TWO_BYTE_ENCODING;
5788 } else {
5789 expected = nullptr;
5790 expectedEncoding =
5791 str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5792 }
5793 CHECK_EQ(expected, value);
5794 CHECK_EQ(expectedEncoding, encoding);
5795 }
5796
GetExternalStringResourceSlow() const5797 String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5798 i::DisallowGarbageCollection no_gc;
5799 using I = internal::Internals;
5800 i::String str = *Utils::OpenHandle(this);
5801
5802 if (str.IsThinString()) {
5803 str = i::ThinString::cast(str).actual();
5804 }
5805
5806 if (i::StringShape(str).IsExternalTwoByte()) {
5807 internal::Isolate* isolate = I::GetIsolateForSandbox(str.ptr());
5808 internal::Address value = I::ReadExternalPointerField(
5809 isolate, str.ptr(), I::kStringResourceOffset,
5810 internal::kExternalStringResourceTag);
5811 return reinterpret_cast<String::ExternalStringResource*>(value);
5812 }
5813 return nullptr;
5814 }
5815
UpdateDataCache()5816 void String::ExternalStringResource::UpdateDataCache() {
5817 DCHECK(IsCacheable());
5818 cached_data_ = data();
5819 }
5820
CheckCachedDataInvariants() const5821 void String::ExternalStringResource::CheckCachedDataInvariants() const {
5822 DCHECK(IsCacheable() && cached_data_ != nullptr);
5823 }
5824
UpdateDataCache()5825 void String::ExternalOneByteStringResource::UpdateDataCache() {
5826 DCHECK(IsCacheable());
5827 cached_data_ = data();
5828 }
5829
CheckCachedDataInvariants() const5830 void String::ExternalOneByteStringResource::CheckCachedDataInvariants() const {
5831 DCHECK(IsCacheable() && cached_data_ != nullptr);
5832 }
5833
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5834 String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5835 String::Encoding* encoding_out) const {
5836 i::DisallowGarbageCollection no_gc;
5837 using I = internal::Internals;
5838 ExternalStringResourceBase* resource = nullptr;
5839 i::String str = *Utils::OpenHandle(this);
5840
5841 if (str.IsThinString()) {
5842 str = i::ThinString::cast(str).actual();
5843 }
5844
5845 internal::Address string = str.ptr();
5846 int type =
5847 I::GetInstanceType(string) & I::kStringRepresentationAndEncodingMask;
5848 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5849 if (i::StringShape(str).IsExternalOneByte() ||
5850 i::StringShape(str).IsExternalTwoByte()) {
5851 internal::Isolate* isolate = I::GetIsolateForSandbox(string);
5852 internal::Address value =
5853 I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5854 internal::kExternalStringResourceTag);
5855 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5856 }
5857 return resource;
5858 }
5859
5860 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5861 v8::String::GetExternalOneByteStringResource() const {
5862 i::DisallowGarbageCollection no_gc;
5863 i::String str = *Utils::OpenHandle(this);
5864 if (i::StringShape(str).IsExternalOneByte()) {
5865 return i::ExternalOneByteString::cast(str).resource();
5866 } else if (str.IsThinString()) {
5867 str = i::ThinString::cast(str).actual();
5868 if (i::StringShape(str).IsExternalOneByte()) {
5869 return i::ExternalOneByteString::cast(str).resource();
5870 }
5871 }
5872 return nullptr;
5873 }
5874
Description(Isolate * isolate) const5875 Local<Value> Symbol::Description(Isolate* isolate) const {
5876 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5877 i::Handle<i::Object> description(sym->description(),
5878 reinterpret_cast<i::Isolate*>(isolate));
5879 return Utils::ToLocal(description);
5880 }
5881
Name() const5882 Local<Value> Private::Name() const {
5883 const Symbol* sym = reinterpret_cast<const Symbol*>(this);
5884 i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym);
5885 // v8::Private symbols are created by API and are therefore writable, so we
5886 // can always recover an Isolate.
5887 i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym);
5888 return sym->Description(reinterpret_cast<Isolate*>(isolate));
5889 }
5890
Value() const5891 double Number::Value() const {
5892 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5893 return obj->Number();
5894 }
5895
Value() const5896 bool Boolean::Value() const {
5897 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5898 return obj->IsTrue();
5899 }
5900
Value() const5901 int64_t Integer::Value() const {
5902 i::Object obj = *Utils::OpenHandle(this);
5903 if (obj.IsSmi()) {
5904 return i::Smi::ToInt(obj);
5905 } else {
5906 return static_cast<int64_t>(obj.Number());
5907 }
5908 }
5909
Value() const5910 int32_t Int32::Value() const {
5911 i::Object obj = *Utils::OpenHandle(this);
5912 if (obj.IsSmi()) {
5913 return i::Smi::ToInt(obj);
5914 } else {
5915 return static_cast<int32_t>(obj.Number());
5916 }
5917 }
5918
Value() const5919 uint32_t Uint32::Value() const {
5920 i::Object obj = *Utils::OpenHandle(this);
5921 if (obj.IsSmi()) {
5922 return i::Smi::ToInt(obj);
5923 } else {
5924 return static_cast<uint32_t>(obj.Number());
5925 }
5926 }
5927
InternalFieldCount() const5928 int v8::Object::InternalFieldCount() const {
5929 i::JSReceiver self = *Utils::OpenHandle(this);
5930 if (!self.IsJSObject()) return 0;
5931 return i::JSObject::cast(self).GetEmbedderFieldCount();
5932 }
5933
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5934 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5935 const char* location) {
5936 return Utils::ApiCheck(
5937 obj->IsJSObject() &&
5938 (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5939 location, "Internal field out of bounds");
5940 }
5941
SlowGetInternalField(int index)5942 Local<Value> v8::Object::SlowGetInternalField(int index) {
5943 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5944 const char* location = "v8::Object::GetInternalField()";
5945 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5946 i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
5947 obj->GetIsolate());
5948 return Utils::ToLocal(value);
5949 }
5950
SetInternalField(int index,v8::Local<Value> value)5951 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5952 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5953 const char* location = "v8::Object::SetInternalField()";
5954 if (!InternalFieldOK(obj, index, location)) return;
5955 i::Handle<i::Object> val = Utils::OpenHandle(*value);
5956 i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
5957 }
5958
SlowGetAlignedPointerFromInternalField(int index)5959 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5960 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5961 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5962 if (!InternalFieldOK(obj, index, location)) return nullptr;
5963 void* result;
5964 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5965 .ToAlignedPointer(obj->GetIsolate(), &result),
5966 location, "Unaligned pointer");
5967 return result;
5968 }
5969
SetAlignedPointerInInternalField(int index,void * value)5970 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5971 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5972 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5973 if (!InternalFieldOK(obj, index, location)) return;
5974
5975 i::DisallowGarbageCollection no_gc;
5976
5977 // There's no need to invalidate slots as embedder fields are always
5978 // tagged.
5979 obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
5980 i::InvalidateRecordedSlots::kNo);
5981
5982 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5983 .store_aligned_pointer(obj->GetIsolate(), value),
5984 location, "Unaligned pointer");
5985 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5986 internal::WriteBarrier::MarkingFromInternalFields(i::JSObject::cast(*obj));
5987
5988 #ifdef VERIFY_HEAP
5989 obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
5990 #endif // VERIFY_HEAP
5991 }
5992
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])5993 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
5994 void* values[]) {
5995 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5996
5997 i::DisallowGarbageCollection no_gc;
5998 // There's no need to invalidate slots as embedder fields are always
5999 // tagged.
6000 obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc,
6001 i::InvalidateRecordedSlots::kNo);
6002
6003 const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6004 i::JSObject js_obj = i::JSObject::cast(*obj);
6005 int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
6006 for (int i = 0; i < argc; i++) {
6007 int index = indices[i];
6008 if (!Utils::ApiCheck(index < nof_embedder_fields, location,
6009 "Internal field out of bounds")) {
6010 return;
6011 }
6012 void* value = values[i];
6013 Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
6014 .store_aligned_pointer(obj->GetIsolate(), value),
6015 location, "Unaligned pointer");
6016 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6017 }
6018 internal::WriteBarrier::MarkingFromInternalFields(js_obj);
6019
6020 #ifdef VERIFY_HEAP
6021 obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map());
6022 #endif // VERIFY_HEAP
6023 }
6024
6025 // --- E n v i r o n m e n t ---
6026
InitializePlatform(Platform * platform)6027 void v8::V8::InitializePlatform(Platform* platform) {
6028 i::V8::InitializePlatform(platform);
6029 }
6030
6031 #ifdef V8_SANDBOX
InitializeSandbox()6032 bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); }
6033 #endif
6034
DisposePlatform()6035 void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); }
6036
Initialize(const int build_config)6037 bool v8::V8::Initialize(const int build_config) {
6038 const bool kEmbedderPointerCompression =
6039 (build_config & kPointerCompression) != 0;
6040 if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
6041 FATAL(
6042 "Embedder-vs-V8 build configuration mismatch. On embedder side "
6043 "pointer compression is %s while on V8 side it's %s.",
6044 kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
6045 COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6046 }
6047
6048 const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
6049 if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
6050 FATAL(
6051 "Embedder-vs-V8 build configuration mismatch. On embedder side "
6052 "Smi value size is %d while on V8 side it's %d.",
6053 kEmbedderSmiValueSize, internal::kSmiValueSize);
6054 }
6055
6056 const bool kEmbedderSandboxedExternalPointers =
6057 (build_config & kSandboxedExternalPointers) != 0;
6058 if (kEmbedderSandboxedExternalPointers !=
6059 V8_SANDBOXED_EXTERNAL_POINTERS_BOOL) {
6060 FATAL(
6061 "Embedder-vs-V8 build configuration mismatch. On embedder side "
6062 "sandboxed external pointers is %s while on V8 side it's %s.",
6063 kEmbedderSandboxedExternalPointers ? "ENABLED" : "DISABLED",
6064 V8_SANDBOXED_EXTERNAL_POINTERS_BOOL ? "ENABLED" : "DISABLED");
6065 }
6066
6067 const bool kEmbedderSandbox = (build_config & kSandbox) != 0;
6068 if (kEmbedderSandbox != V8_SANDBOX_BOOL) {
6069 FATAL(
6070 "Embedder-vs-V8 build configuration mismatch. On embedder side "
6071 "sandbox is %s while on V8 side it's %s.",
6072 kEmbedderSandbox ? "ENABLED" : "DISABLED",
6073 V8_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
6074 }
6075
6076 i::V8::Initialize();
6077 return true;
6078 }
6079
6080 #if V8_OS_LINUX || V8_OS_DARWIN
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)6081 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
6082 void* context) {
6083 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6084 return i::trap_handler::TryHandleSignal(sig_code, info, context);
6085 #else
6086 return false;
6087 #endif
6088 }
6089 #endif
6090
6091 #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)6092 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
6093 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED
6094 return i::trap_handler::TryHandleWasmTrap(exception);
6095 #else
6096 return false;
6097 #endif
6098 }
6099 #endif
6100
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)6101 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
6102 #if V8_ENABLE_WEBASSEMBLY
6103 return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
6104 #else
6105 return false;
6106 #endif
6107 }
6108
6109 #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6110 void V8::SetUnhandledExceptionCallback(
6111 UnhandledExceptionCallback unhandled_exception_callback) {
6112 #if defined(V8_OS_WIN64)
6113 v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
6114 unhandled_exception_callback);
6115 #else
6116 // Not implemented, port needed.
6117 #endif // V8_OS_WIN64
6118 }
6119 #endif // V8_OS_WIN
6120
SetFatalMemoryErrorCallback(v8::OOMErrorCallback oom_error_callback)6121 void v8::V8::SetFatalMemoryErrorCallback(
6122 v8::OOMErrorCallback oom_error_callback) {
6123 g_oom_error_callback = oom_error_callback;
6124 }
6125
SetEntropySource(EntropySource entropy_source)6126 void v8::V8::SetEntropySource(EntropySource entropy_source) {
6127 base::RandomNumberGenerator::SetEntropySource(entropy_source);
6128 }
6129
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6130 void v8::V8::SetReturnAddressLocationResolver(
6131 ReturnAddressLocationResolver return_address_resolver) {
6132 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6133 }
6134
Dispose()6135 bool v8::V8::Dispose() {
6136 i::V8::Dispose();
6137 return true;
6138 }
6139
SharedMemoryStatistics()6140 SharedMemoryStatistics::SharedMemoryStatistics()
6141 : read_only_space_size_(0),
6142 read_only_space_used_size_(0),
6143 read_only_space_physical_size_(0) {}
6144
HeapStatistics()6145 HeapStatistics::HeapStatistics()
6146 : total_heap_size_(0),
6147 total_heap_size_executable_(0),
6148 total_physical_size_(0),
6149 total_available_size_(0),
6150 used_heap_size_(0),
6151 heap_size_limit_(0),
6152 malloced_memory_(0),
6153 external_memory_(0),
6154 peak_malloced_memory_(0),
6155 does_zap_garbage_(false),
6156 number_of_native_contexts_(0),
6157 number_of_detached_contexts_(0) {}
6158
HeapSpaceStatistics()6159 HeapSpaceStatistics::HeapSpaceStatistics()
6160 : space_name_(nullptr),
6161 space_size_(0),
6162 space_used_size_(0),
6163 space_available_size_(0),
6164 physical_space_size_(0) {}
6165
HeapObjectStatistics()6166 HeapObjectStatistics::HeapObjectStatistics()
6167 : object_type_(nullptr),
6168 object_sub_type_(nullptr),
6169 object_count_(0),
6170 object_size_(0) {}
6171
HeapCodeStatistics()6172 HeapCodeStatistics::HeapCodeStatistics()
6173 : code_and_metadata_size_(0),
6174 bytecode_and_metadata_size_(0),
6175 external_script_source_size_(0),
6176 cpu_profiler_metadata_size_(0) {}
6177
InitializeICU(const char * icu_data_file)6178 bool v8::V8::InitializeICU(const char* icu_data_file) {
6179 return i::InitializeICU(icu_data_file);
6180 }
6181
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6182 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6183 const char* icu_data_file) {
6184 return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6185 }
6186
InitializeExternalStartupData(const char * directory_path)6187 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6188 i::InitializeExternalStartupData(directory_path);
6189 }
6190
6191 // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)6192 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
6193 i::InitializeExternalStartupDataFromFile(snapshot_blob);
6194 }
6195
GetVersion()6196 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
6197
6198 #ifdef V8_SANDBOX
GetSandboxAddressSpace()6199 VirtualAddressSpace* v8::V8::GetSandboxAddressSpace() {
6200 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6201 "v8::V8::GetSandboxAddressSpace",
6202 "The sandbox must be initialized first.");
6203 return i::GetProcessWideSandbox()->address_space();
6204 }
6205
GetVirtualMemoryCagePageAllocator()6206 PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() {
6207 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6208 "v8::V8::GetVirtualMemoryCagePageAllocator",
6209 "The sandbox must be initialized first.");
6210 return i::GetProcessWideSandbox()->page_allocator();
6211 }
6212
GetSandboxSizeInBytes()6213 size_t v8::V8::GetSandboxSizeInBytes() {
6214 if (!i::GetProcessWideSandbox()->is_initialized()) {
6215 return 0;
6216 } else {
6217 return i::GetProcessWideSandbox()->size();
6218 }
6219 }
6220
IsSandboxConfiguredSecurely()6221 bool v8::V8::IsSandboxConfiguredSecurely() {
6222 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(),
6223 "v8::V8::IsSandoxConfiguredSecurely",
6224 "The sandbox must be initialized first.");
6225 // TODO(saelo) For now, we only treat a partially reserved sandbox as
6226 // insecure. Once we use sandboxed pointers, which assume that the sandbox
6227 // has a fixed size, we'll also treat sandboxes with a smaller size as
6228 // insecure because these pointers can then access memory outside of them.
6229 return !i::GetProcessWideSandbox()->is_partially_reserved();
6230 }
6231 #endif
6232
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6233 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
6234 i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
6235 }
6236
6237 template <typename ObjectType>
6238 struct InvokeBootstrapper;
6239
6240 template <>
6241 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper6242 i::Handle<i::Context> Invoke(
6243 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6244 v8::Local<v8::ObjectTemplate> global_proxy_template,
6245 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6246 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6247 v8::MicrotaskQueue* microtask_queue) {
6248 return isolate->bootstrapper()->CreateEnvironment(
6249 maybe_global_proxy, global_proxy_template, extensions,
6250 context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6251 }
6252 };
6253
6254 template <>
6255 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper6256 i::Handle<i::JSGlobalProxy> Invoke(
6257 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6258 v8::Local<v8::ObjectTemplate> global_proxy_template,
6259 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6260 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6261 v8::MicrotaskQueue* microtask_queue) {
6262 USE(extensions);
6263 USE(context_snapshot_index);
6264 return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6265 global_proxy_template);
6266 }
6267 };
6268
6269 template <typename ObjectType>
CreateEnvironment(i::Isolate * isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> maybe_global_template,v8::MaybeLocal<Value> maybe_global_proxy,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6270 static i::Handle<ObjectType> CreateEnvironment(
6271 i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6272 v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6273 v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6274 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6275 v8::MicrotaskQueue* microtask_queue) {
6276 i::Handle<ObjectType> result;
6277
6278 {
6279 ENTER_V8_FOR_NEW_CONTEXT(isolate);
6280 v8::Local<ObjectTemplate> proxy_template;
6281 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6282 i::Handle<i::FunctionTemplateInfo> global_constructor;
6283 i::Handle<i::HeapObject> named_interceptor(
6284 isolate->factory()->undefined_value());
6285 i::Handle<i::HeapObject> indexed_interceptor(
6286 isolate->factory()->undefined_value());
6287
6288 if (!maybe_global_template.IsEmpty()) {
6289 v8::Local<v8::ObjectTemplate> global_template =
6290 maybe_global_template.ToLocalChecked();
6291 // Make sure that the global_template has a constructor.
6292 global_constructor = EnsureConstructor(isolate, *global_template);
6293
6294 // Create a fresh template for the global proxy object.
6295 proxy_template =
6296 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
6297 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6298
6299 // Set the global template to be the prototype template of
6300 // global proxy template.
6301 i::FunctionTemplateInfo::SetPrototypeTemplate(
6302 isolate, proxy_constructor, Utils::OpenHandle(*global_template));
6303
6304 proxy_template->SetInternalFieldCount(
6305 global_template->InternalFieldCount());
6306
6307 // Migrate security handlers from global_template to
6308 // proxy_template. Temporarily removing access check
6309 // information from the global template.
6310 if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
6311 i::FunctionTemplateInfo::SetAccessCheckInfo(
6312 isolate, proxy_constructor,
6313 i::handle(global_constructor->GetAccessCheckInfo(), isolate));
6314 proxy_constructor->set_needs_access_check(
6315 global_constructor->needs_access_check());
6316 global_constructor->set_needs_access_check(false);
6317 i::FunctionTemplateInfo::SetAccessCheckInfo(
6318 isolate, global_constructor,
6319 i::ReadOnlyRoots(isolate).undefined_value_handle());
6320 }
6321
6322 // Same for other interceptors. If the global constructor has
6323 // interceptors, we need to replace them temporarily with noop
6324 // interceptors, so the map is correctly marked as having interceptors,
6325 // but we don't invoke any.
6326 if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
6327 named_interceptor =
6328 handle(global_constructor->GetNamedPropertyHandler(), isolate);
6329 i::FunctionTemplateInfo::SetNamedPropertyHandler(
6330 isolate, global_constructor,
6331 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6332 }
6333 if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
6334 isolate)) {
6335 indexed_interceptor =
6336 handle(global_constructor->GetIndexedPropertyHandler(), isolate);
6337 i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6338 isolate, global_constructor,
6339 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6340 }
6341 }
6342
6343 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6344 if (!maybe_global_proxy.IsEmpty()) {
6345 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6346 Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6347 }
6348 // Create the environment.
6349 InvokeBootstrapper<ObjectType> invoke;
6350 result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6351 context_snapshot_index, embedder_fields_deserializer,
6352 microtask_queue);
6353
6354 // Restore the access check info and interceptors on the global template.
6355 if (!maybe_global_template.IsEmpty()) {
6356 DCHECK(!global_constructor.is_null());
6357 DCHECK(!proxy_constructor.is_null());
6358 i::FunctionTemplateInfo::SetAccessCheckInfo(
6359 isolate, global_constructor,
6360 i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6361 global_constructor->set_needs_access_check(
6362 proxy_constructor->needs_access_check());
6363 i::FunctionTemplateInfo::SetNamedPropertyHandler(
6364 isolate, global_constructor, named_interceptor);
6365 i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6366 isolate, global_constructor, indexed_interceptor);
6367 }
6368 }
6369 // Leave V8.
6370
6371 return result;
6372 }
6373
NewContext(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6374 Local<Context> NewContext(
6375 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6376 v8::MaybeLocal<ObjectTemplate> global_template,
6377 v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6378 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6379 v8::MicrotaskQueue* microtask_queue) {
6380 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6381 // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6382 // fail.
6383 // Sanity-check that the isolate is initialized and usable.
6384 CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT());
6385
6386 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6387 API_RCS_SCOPE(isolate, Context, New);
6388 i::HandleScope scope(isolate);
6389 ExtensionConfiguration no_extensions;
6390 if (extensions == nullptr) extensions = &no_extensions;
6391 i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6392 isolate, extensions, global_template, global_object,
6393 context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6394 if (env.is_null()) {
6395 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6396 return Local<Context>();
6397 }
6398 return Utils::ToLocal(scope.CloseAndEscape(env));
6399 }
6400
New(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,DeserializeInternalFieldsCallback internal_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6401 Local<Context> v8::Context::New(
6402 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6403 v8::MaybeLocal<ObjectTemplate> global_template,
6404 v8::MaybeLocal<Value> global_object,
6405 DeserializeInternalFieldsCallback internal_fields_deserializer,
6406 v8::MicrotaskQueue* microtask_queue) {
6407 return NewContext(external_isolate, extensions, global_template,
6408 global_object, 0, internal_fields_deserializer,
6409 microtask_queue);
6410 }
6411
FromSnapshot(v8::Isolate * external_isolate,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::ExtensionConfiguration * extensions,MaybeLocal<Value> global_object,v8::MicrotaskQueue * microtask_queue)6412 MaybeLocal<Context> v8::Context::FromSnapshot(
6413 v8::Isolate* external_isolate, size_t context_snapshot_index,
6414 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6415 v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6416 v8::MicrotaskQueue* microtask_queue) {
6417 size_t index_including_default_context = context_snapshot_index + 1;
6418 if (!i::Snapshot::HasContextSnapshot(
6419 reinterpret_cast<i::Isolate*>(external_isolate),
6420 index_including_default_context)) {
6421 return MaybeLocal<Context>();
6422 }
6423 return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6424 global_object, index_including_default_context,
6425 embedder_fields_deserializer, microtask_queue);
6426 }
6427
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6428 MaybeLocal<Object> v8::Context::NewRemoteContext(
6429 v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6430 v8::MaybeLocal<v8::Value> global_object) {
6431 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6432 API_RCS_SCOPE(isolate, Context, NewRemoteContext);
6433 i::HandleScope scope(isolate);
6434 i::Handle<i::FunctionTemplateInfo> global_constructor =
6435 EnsureConstructor(isolate, *global_template);
6436 Utils::ApiCheck(global_constructor->needs_access_check(),
6437 "v8::Context::NewRemoteContext",
6438 "Global template needs to have access checks enabled.");
6439 i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6440 i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6441 isolate);
6442 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6443 "v8::Context::NewRemoteContext",
6444 "Global template needs to have access check handlers.");
6445 i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6446 isolate, nullptr, global_template, global_object, 0,
6447 DeserializeInternalFieldsCallback(), nullptr);
6448 if (global_proxy.is_null()) {
6449 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6450 return MaybeLocal<Object>();
6451 }
6452 return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6453 }
6454
SetSecurityToken(Local<Value> token)6455 void v8::Context::SetSecurityToken(Local<Value> token) {
6456 i::Handle<i::Context> env = Utils::OpenHandle(this);
6457 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6458 env->set_security_token(*token_handle);
6459 }
6460
UseDefaultSecurityToken()6461 void v8::Context::UseDefaultSecurityToken() {
6462 i::Handle<i::Context> env = Utils::OpenHandle(this);
6463 env->set_security_token(env->global_object());
6464 }
6465
GetSecurityToken()6466 Local<Value> v8::Context::GetSecurityToken() {
6467 i::Handle<i::Context> env = Utils::OpenHandle(this);
6468 i::Isolate* isolate = env->GetIsolate();
6469 i::Object security_token = env->security_token();
6470 i::Handle<i::Object> token_handle(security_token, isolate);
6471 return Utils::ToLocal(token_handle);
6472 }
6473
GetIsolate()6474 v8::Isolate* Context::GetIsolate() {
6475 i::Handle<i::Context> env = Utils::OpenHandle(this);
6476 return reinterpret_cast<Isolate*>(env->GetIsolate());
6477 }
6478
GetMicrotaskQueue()6479 v8::MicrotaskQueue* Context::GetMicrotaskQueue() {
6480 i::Handle<i::Context> env = Utils::OpenHandle(this);
6481 Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue",
6482 "Must be calld on a native context");
6483 return i::Handle<i::NativeContext>::cast(env)->microtask_queue();
6484 }
6485
Global()6486 v8::Local<v8::Object> Context::Global() {
6487 i::Handle<i::Context> context = Utils::OpenHandle(this);
6488 i::Isolate* isolate = context->GetIsolate();
6489 i::Handle<i::Object> global(context->global_proxy(), isolate);
6490 // TODO(chromium:324812): This should always return the global proxy
6491 // but can't presently as calls to GetProtoype will return the wrong result.
6492 if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6493 context->global_object())) {
6494 global = i::Handle<i::Object>(context->global_object(), isolate);
6495 }
6496 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6497 }
6498
DetachGlobal()6499 void Context::DetachGlobal() {
6500 i::Handle<i::Context> context = Utils::OpenHandle(this);
6501 i::Isolate* isolate = context->GetIsolate();
6502 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6503 isolate->DetachGlobal(context);
6504 }
6505
GetExtrasBindingObject()6506 Local<v8::Object> Context::GetExtrasBindingObject() {
6507 i::Handle<i::Context> context = Utils::OpenHandle(this);
6508 i::Isolate* isolate = context->GetIsolate();
6509 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6510 return Utils::ToLocal(binding);
6511 }
6512
AllowCodeGenerationFromStrings(bool allow)6513 void Context::AllowCodeGenerationFromStrings(bool allow) {
6514 i::Handle<i::Context> context = Utils::OpenHandle(this);
6515 i::Isolate* isolate = context->GetIsolate();
6516 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6517 context->set_allow_code_gen_from_strings(
6518 allow ? i::ReadOnlyRoots(isolate).true_value()
6519 : i::ReadOnlyRoots(isolate).false_value());
6520 }
6521
IsCodeGenerationFromStringsAllowed() const6522 bool Context::IsCodeGenerationFromStringsAllowed() const {
6523 i::Context context = *Utils::OpenHandle(this);
6524 return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate());
6525 }
6526
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6527 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6528 i::Handle<i::Context> context = Utils::OpenHandle(this);
6529 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6530 context->set_error_message_for_code_gen_from_strings(*error_handle);
6531 }
6532
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6533 void Context::SetAbortScriptExecution(
6534 Context::AbortScriptExecutionCallback callback) {
6535 i::Handle<i::Context> context = Utils::OpenHandle(this);
6536 i::Isolate* isolate = context->GetIsolate();
6537 if (callback == nullptr) {
6538 context->set_script_execution_callback(
6539 i::ReadOnlyRoots(isolate).undefined_value());
6540 } else {
6541 SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6542 callback);
6543 }
6544 }
6545
GetContinuationPreservedEmbedderData() const6546 Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6547 i::Handle<i::Context> context = Utils::OpenHandle(this);
6548 i::Isolate* isolate = context->GetIsolate();
6549 i::Handle<i::Object> data(
6550 context->native_context().continuation_preserved_embedder_data(),
6551 isolate);
6552 return ToApiHandle<Object>(data);
6553 }
6554
SetContinuationPreservedEmbedderData(Local<Value> data)6555 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6556 i::Handle<i::Context> context = Utils::OpenHandle(this);
6557 i::Isolate* isolate = context->GetIsolate();
6558 if (data.IsEmpty())
6559 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6560 context->native_context().set_continuation_preserved_embedder_data(
6561 *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6562 }
6563
SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6564 void v8::Context::SetPromiseHooks(Local<Function> init_hook,
6565 Local<Function> before_hook,
6566 Local<Function> after_hook,
6567 Local<Function> resolve_hook) {
6568 #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6569 i::Handle<i::Context> context = Utils::OpenHandle(this);
6570 i::Isolate* isolate = context->GetIsolate();
6571
6572 i::Handle<i::Object> init = isolate->factory()->undefined_value();
6573 i::Handle<i::Object> before = isolate->factory()->undefined_value();
6574 i::Handle<i::Object> after = isolate->factory()->undefined_value();
6575 i::Handle<i::Object> resolve = isolate->factory()->undefined_value();
6576
6577 bool has_hook = false;
6578
6579 if (!init_hook.IsEmpty()) {
6580 init = Utils::OpenHandle(*init_hook);
6581 has_hook = true;
6582 }
6583 if (!before_hook.IsEmpty()) {
6584 before = Utils::OpenHandle(*before_hook);
6585 has_hook = true;
6586 }
6587 if (!after_hook.IsEmpty()) {
6588 after = Utils::OpenHandle(*after_hook);
6589 has_hook = true;
6590 }
6591 if (!resolve_hook.IsEmpty()) {
6592 resolve = Utils::OpenHandle(*resolve_hook);
6593 has_hook = true;
6594 }
6595
6596 isolate->SetHasContextPromiseHooks(has_hook);
6597
6598 context->native_context().set_promise_hook_init_function(*init);
6599 context->native_context().set_promise_hook_before_function(*before);
6600 context->native_context().set_promise_hook_after_function(*after);
6601 context->native_context().set_promise_hook_resolve_function(*resolve);
6602 #else // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6603 Utils::ApiCheck(false, "v8::Context::SetPromiseHook",
6604 "V8 was compiled without JavaScript Promise hooks");
6605 #endif // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
6606 }
6607
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6608 MaybeLocal<Context> metrics::Recorder::GetContext(
6609 Isolate* isolate, metrics::Recorder::ContextId id) {
6610 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6611 return i_isolate->GetContextFromRecorderContextId(id);
6612 }
6613
GetContextId(Local<Context> context)6614 metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6615 Local<Context> context) {
6616 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6617 i::Isolate* isolate = i_context->GetIsolate();
6618 return isolate->GetOrRegisterRecorderContextId(
6619 handle(i_context->native_context(), isolate));
6620 }
6621
Get(v8::Isolate * isolate)6622 metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) {
6623 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6624 return *i_isolate->GetCurrentLongTaskStats();
6625 }
6626
6627 namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6628 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6629 i::FixedArray list, size_t index) {
6630 if (index < static_cast<size_t>(list.length())) {
6631 int int_index = static_cast<int>(index);
6632 i::Object object = list.get(int_index);
6633 if (!object.IsTheHole(isolate)) {
6634 list.set_the_hole(isolate, int_index);
6635 // Shrink the list so that the last element is not the hole (unless it's
6636 // the first element, because we don't want to end up with a non-canonical
6637 // empty FixedArray).
6638 int last = list.length() - 1;
6639 while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6640 if (last != -1) list.Shrink(isolate, last + 1);
6641 return i::Handle<i::Object>(object, isolate).location();
6642 }
6643 }
6644 return nullptr;
6645 }
6646 } // anonymous namespace
6647
GetDataFromSnapshotOnce(size_t index)6648 i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6649 auto context = Utils::OpenHandle(this);
6650 i::Isolate* i_isolate = context->GetIsolate();
6651 i::FixedArray list = context->serialized_objects();
6652 return GetSerializedDataFromFixedArray(i_isolate, list, index);
6653 }
6654
NewInstance(Local<Context> context)6655 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6656 PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6657 auto self = Utils::OpenHandle(this);
6658 Local<Object> result;
6659 has_pending_exception = !ToLocal<Object>(
6660 i::ApiNatives::InstantiateObject(isolate, self), &result);
6661 RETURN_ON_FAILED_EXECUTION(Object);
6662 RETURN_ESCAPED(result);
6663 }
6664
CheckCast(Data * that)6665 void v8::ObjectTemplate::CheckCast(Data* that) {
6666 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6667 Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6668 "Value is not an ObjectTemplate");
6669 }
6670
CheckCast(Data * that)6671 void v8::FunctionTemplate::CheckCast(Data* that) {
6672 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6673 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6674 "Value is not a FunctionTemplate");
6675 }
6676
CheckCast(Data * that)6677 void v8::Signature::CheckCast(Data* that) {
6678 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6679 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6680 "Value is not a Signature");
6681 }
6682
CheckCast(Data * that)6683 void v8::AccessorSignature::CheckCast(Data* that) {
6684 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6685 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6686 "Value is not an AccessorSignature");
6687 }
6688
GetFunction(Local<Context> context)6689 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6690 PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6691 auto self = Utils::OpenHandle(this);
6692 Local<Function> result;
6693 has_pending_exception =
6694 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6695 RETURN_ON_FAILED_EXECUTION(Function);
6696 RETURN_ESCAPED(result);
6697 }
6698
NewRemoteInstance()6699 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6700 auto self = Utils::OpenHandle(this);
6701 i::Isolate* isolate = self->GetIsolate();
6702 API_RCS_SCOPE(isolate, FunctionTemplate, NewRemoteInstance);
6703 i::HandleScope scope(isolate);
6704 i::Handle<i::FunctionTemplateInfo> constructor =
6705 EnsureConstructor(isolate, *InstanceTemplate());
6706 Utils::ApiCheck(constructor->needs_access_check(),
6707 "v8::FunctionTemplate::NewRemoteInstance",
6708 "InstanceTemplate needs to have access checks enabled.");
6709 i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6710 i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6711 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6712 "v8::FunctionTemplate::NewRemoteInstance",
6713 "InstanceTemplate needs to have access check handlers.");
6714 i::Handle<i::JSObject> object;
6715 if (!i::ApiNatives::InstantiateRemoteObject(
6716 Utils::OpenHandle(*InstanceTemplate()))
6717 .ToHandle(&object)) {
6718 if (isolate->has_pending_exception()) {
6719 isolate->OptionalRescheduleException(true);
6720 }
6721 return MaybeLocal<Object>();
6722 }
6723 return Utils::ToLocal(scope.CloseAndEscape(object));
6724 }
6725
HasInstance(v8::Local<v8::Value> value)6726 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6727 auto self = Utils::OpenHandle(this);
6728 auto obj = Utils::OpenHandle(*value);
6729 if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6730 return true;
6731 }
6732 if (obj->IsJSGlobalProxy()) {
6733 // If it's a global proxy, then test with the global object. Note that the
6734 // inner global object may not necessarily be a JSGlobalObject.
6735 i::PrototypeIterator iter(self->GetIsolate(),
6736 i::JSObject::cast(*obj).map());
6737 // The global proxy should always have a prototype, as it is a bug to call
6738 // this on a detached JSGlobalProxy.
6739 DCHECK(!iter.IsAtEnd());
6740 return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6741 }
6742 return false;
6743 }
6744
IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6745 bool FunctionTemplate::IsLeafTemplateForApiObject(
6746 v8::Local<v8::Value> value) const {
6747 i::DisallowGarbageCollection no_gc;
6748
6749 i::Object object = *Utils::OpenHandle(*value);
6750
6751 auto self = Utils::OpenHandle(this);
6752 return self->IsLeafTemplateForApiObject(object);
6753 }
6754
New(Isolate * isolate,void * value)6755 Local<External> v8::External::New(Isolate* isolate, void* value) {
6756 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6757 // Nullptr is not allowed here because serialization/deserialization of
6758 // nullptr external api references is not possible as nullptr is used as an
6759 // external_references table terminator, see v8::SnapshotCreator()
6760 // constructors.
6761 DCHECK_NOT_NULL(value);
6762 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6763 API_RCS_SCOPE(i_isolate, External, New);
6764 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6765 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6766 return Utils::ExternalToLocal(external);
6767 }
6768
Value() const6769 void* External::Value() const {
6770 auto self = Utils::OpenHandle(this);
6771 return i::JSExternalObject::cast(*self).value();
6772 }
6773
6774 // anonymous namespace for string creation helper functions
6775 namespace {
6776
StringLength(const char * string)6777 inline int StringLength(const char* string) {
6778 size_t len = strlen(string);
6779 CHECK_GE(i::kMaxInt, len);
6780 return static_cast<int>(len);
6781 }
6782
StringLength(const uint8_t * string)6783 inline int StringLength(const uint8_t* string) {
6784 return StringLength(reinterpret_cast<const char*>(string));
6785 }
6786
StringLength(const uint16_t * string)6787 inline int StringLength(const uint16_t* string) {
6788 size_t length = 0;
6789 while (string[length] != '\0') length++;
6790 CHECK_GE(i::kMaxInt, length);
6791 return static_cast<int>(length);
6792 }
6793
6794 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6795 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6796 NewStringType type,
6797 base::Vector<const char> string) {
6798 if (type == NewStringType::kInternalized) {
6799 return factory->InternalizeUtf8String(string);
6800 }
6801 return factory->NewStringFromUtf8(string);
6802 }
6803
6804 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6805 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6806 NewStringType type,
6807 base::Vector<const uint8_t> string) {
6808 if (type == NewStringType::kInternalized) {
6809 return factory->InternalizeString(string);
6810 }
6811 return factory->NewStringFromOneByte(string);
6812 }
6813
6814 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6815 inline i::MaybeHandle<i::String> NewString(
6816 i::Factory* factory, NewStringType type,
6817 base::Vector<const uint16_t> string) {
6818 if (type == NewStringType::kInternalized) {
6819 return factory->InternalizeString(string);
6820 }
6821 return factory->NewStringFromTwoByte(string);
6822 }
6823
6824 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6825
6826 } // anonymous namespace
6827
6828 // TODO(dcarney): throw a context free exception.
6829 #define NEW_STRING(isolate, class_name, function_name, Char, data, type, \
6830 length) \
6831 MaybeLocal<String> result; \
6832 if (length == 0) { \
6833 result = String::Empty(isolate); \
6834 } else if (length > i::String::kMaxLength) { \
6835 result = MaybeLocal<String>(); \
6836 } else { \
6837 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6838 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); \
6839 API_RCS_SCOPE(i_isolate, class_name, function_name); \
6840 if (length < 0) length = StringLength(data); \
6841 i::Handle<i::String> handle_result = \
6842 NewString(i_isolate->factory(), type, \
6843 base::Vector<const Char>(data, length)) \
6844 .ToHandleChecked(); \
6845 result = Utils::ToLocal(handle_result); \
6846 }
6847
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6848 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6849 NewStringType type, int length) {
6850 DCHECK_LE(length, i::String::kMaxLength);
6851 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6852 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6853 API_RCS_SCOPE(i_isolate, String, NewFromUtf8Literal);
6854 i::Handle<i::String> handle_result =
6855 NewString(i_isolate->factory(), type,
6856 base::Vector<const char>(literal, length))
6857 .ToHandleChecked();
6858 return Utils::ToLocal(handle_result);
6859 }
6860
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6861 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6862 NewStringType type, int length) {
6863 NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6864 return result;
6865 }
6866
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6867 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6868 NewStringType type, int length) {
6869 NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6870 return result;
6871 }
6872
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6873 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6874 const uint16_t* data,
6875 NewStringType type, int length) {
6876 NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6877 return result;
6878 }
6879
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6880 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6881 Local<String> right) {
6882 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6883 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6884 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6885 API_RCS_SCOPE(isolate, String, Concat);
6886 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6887 // If we are steering towards a range error, do not wait for the error to be
6888 // thrown, and return the null handle instead.
6889 if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6890 return Local<String>();
6891 }
6892 i::Handle<i::String> result = isolate->factory()
6893 ->NewConsString(left_string, right_string)
6894 .ToHandleChecked();
6895 return Utils::ToLocal(result);
6896 }
6897
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6898 MaybeLocal<String> v8::String::NewExternalTwoByte(
6899 Isolate* isolate, v8::String::ExternalStringResource* resource) {
6900 CHECK(resource && resource->data());
6901 // TODO(dcarney): throw a context free exception.
6902 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6903 return MaybeLocal<String>();
6904 }
6905 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6906 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6907 API_RCS_SCOPE(i_isolate, String, NewExternalTwoByte);
6908 if (resource->length() > 0) {
6909 i::Handle<i::String> string = i_isolate->factory()
6910 ->NewExternalStringFromTwoByte(resource)
6911 .ToHandleChecked();
6912 return Utils::ToLocal(string);
6913 } else {
6914 // The resource isn't going to be used, free it immediately.
6915 resource->Dispose();
6916 return Utils::ToLocal(i_isolate->factory()->empty_string());
6917 }
6918 }
6919
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6920 MaybeLocal<String> v8::String::NewExternalOneByte(
6921 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6922 CHECK_NOT_NULL(resource);
6923 // TODO(dcarney): throw a context free exception.
6924 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6925 return MaybeLocal<String>();
6926 }
6927 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6928 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6929 API_RCS_SCOPE(i_isolate, String, NewExternalOneByte);
6930 if (resource->length() == 0) {
6931 // The resource isn't going to be used, free it immediately.
6932 resource->Dispose();
6933 return Utils::ToLocal(i_isolate->factory()->empty_string());
6934 }
6935 CHECK_NOT_NULL(resource->data());
6936 i::Handle<i::String> string = i_isolate->factory()
6937 ->NewExternalStringFromOneByte(resource)
6938 .ToHandleChecked();
6939 return Utils::ToLocal(string);
6940 }
6941
MakeExternal(v8::String::ExternalStringResource * resource)6942 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6943 i::DisallowGarbageCollection no_gc;
6944
6945 i::String obj = *Utils::OpenHandle(this);
6946
6947 if (obj.IsThinString()) {
6948 obj = i::ThinString::cast(obj).actual();
6949 }
6950
6951 if (!obj.SupportsExternalization()) {
6952 return false;
6953 }
6954
6955 // It is safe to call GetIsolateFromWritableHeapObject because
6956 // SupportsExternalization already checked that the object is writable.
6957 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6958 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6959
6960 CHECK(resource && resource->data());
6961
6962 bool result = obj.MakeExternal(resource);
6963 DCHECK(result);
6964 DCHECK(obj.IsExternalString());
6965 return result;
6966 }
6967
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6968 bool v8::String::MakeExternal(
6969 v8::String::ExternalOneByteStringResource* resource) {
6970 i::DisallowGarbageCollection no_gc;
6971
6972 i::String obj = *Utils::OpenHandle(this);
6973
6974 if (obj.IsThinString()) {
6975 obj = i::ThinString::cast(obj).actual();
6976 }
6977
6978 if (!obj.SupportsExternalization()) {
6979 return false;
6980 }
6981
6982 // It is safe to call GetIsolateFromWritableHeapObject because
6983 // SupportsExternalization already checked that the object is writable.
6984 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6985 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6986
6987 CHECK(resource && resource->data());
6988
6989 bool result = obj.MakeExternal(resource);
6990 DCHECK_IMPLIES(result, obj.IsExternalString());
6991 return result;
6992 }
6993
CanMakeExternal() const6994 bool v8::String::CanMakeExternal() const {
6995 i::String obj = *Utils::OpenHandle(this);
6996
6997 if (obj.IsThinString()) {
6998 obj = i::ThinString::cast(obj).actual();
6999 }
7000
7001 if (!obj.SupportsExternalization()) {
7002 return false;
7003 }
7004
7005 // Only old space strings should be externalized.
7006 return !i::Heap::InYoungGeneration(obj);
7007 }
7008
StringEquals(Local<String> that) const7009 bool v8::String::StringEquals(Local<String> that) const {
7010 auto self = Utils::OpenHandle(this);
7011 auto other = Utils::OpenHandle(*that);
7012 return self->Equals(*other);
7013 }
7014
GetIsolate()7015 Isolate* v8::Object::GetIsolate() {
7016 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7017 return reinterpret_cast<Isolate*>(i_isolate);
7018 }
7019
New(Isolate * isolate)7020 Local<v8::Object> v8::Object::New(Isolate* isolate) {
7021 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7022 API_RCS_SCOPE(i_isolate, Object, New);
7023 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7024 i::Handle<i::JSObject> obj =
7025 i_isolate->factory()->NewJSObject(i_isolate->object_function());
7026 return Utils::ToLocal(obj);
7027 }
7028
7029 namespace {
7030
7031 // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference
7032 // in the return types of the different Add functions:
7033 // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns
7034 // Handle.
7035 template <typename T>
ToHandle(i::Handle<T> h)7036 i::Handle<T> ToHandle(i::Handle<T> h) {
7037 return h;
7038 }
7039 template <typename T>
ToHandle(i::MaybeHandle<T> h)7040 i::Handle<T> ToHandle(i::MaybeHandle<T> h) {
7041 return h.ToHandleChecked();
7042 }
7043
7044 template <typename Dictionary>
AddPropertiesAndElementsToObject(i::Isolate * i_isolate,i::Handle<Dictionary> & properties,i::Handle<i::FixedArrayBase> & elements,Local<Name> * names,Local<Value> * values,size_t length)7045 void AddPropertiesAndElementsToObject(i::Isolate* i_isolate,
7046 i::Handle<Dictionary>& properties,
7047 i::Handle<i::FixedArrayBase>& elements,
7048 Local<Name>* names, Local<Value>* values,
7049 size_t length) {
7050 for (size_t i = 0; i < length; ++i) {
7051 i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
7052 i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
7053
7054 // See if the {name} is a valid array index, in which case we need to
7055 // add the {name}/{value} pair to the {elements}, otherwise they end
7056 // up in the {properties} backing store.
7057 uint32_t index;
7058 if (name->AsArrayIndex(&index)) {
7059 // If this is the first element, allocate a proper
7060 // dictionary elements backing store for {elements}.
7061 if (!elements->IsNumberDictionary()) {
7062 elements =
7063 i::NumberDictionary::New(i_isolate, static_cast<int>(length));
7064 }
7065 elements = i::NumberDictionary::Set(
7066 i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
7067 value);
7068 } else {
7069 // Internalize the {name} first.
7070 name = i_isolate->factory()->InternalizeName(name);
7071 i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
7072 if (entry.is_not_found()) {
7073 // Add the {name}/{value} pair as a new entry.
7074 properties = ToHandle(Dictionary::Add(
7075 i_isolate, properties, name, value, i::PropertyDetails::Empty()));
7076 } else {
7077 // Overwrite the {entry} with the {value}.
7078 properties->ValueAtPut(entry, *value);
7079 }
7080 }
7081 }
7082 }
7083
7084 } // namespace
7085
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)7086 Local<v8::Object> v8::Object::New(Isolate* isolate,
7087 Local<Value> prototype_or_null,
7088 Local<Name>* names, Local<Value>* values,
7089 size_t length) {
7090 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7091 i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
7092 if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
7093 "v8::Object::New", "prototype must be null or object")) {
7094 return Local<v8::Object>();
7095 }
7096 API_RCS_SCOPE(i_isolate, Object, New);
7097 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7098
7099 i::Handle<i::FixedArrayBase> elements =
7100 i_isolate->factory()->empty_fixed_array();
7101
7102 // We assume that this API is mostly used to create objects with named
7103 // properties, and so we default to creating a properties backing store
7104 // large enough to hold all of them, while we start with no elements
7105 // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
7106 if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
7107 i::Handle<i::SwissNameDictionary> properties =
7108 i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length));
7109 AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7110 values, length);
7111 i::Handle<i::JSObject> obj =
7112 i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7113 i::Handle<i::HeapObject>::cast(proto), properties, elements);
7114 return Utils::ToLocal(obj);
7115 } else {
7116 i::Handle<i::NameDictionary> properties =
7117 i::NameDictionary::New(i_isolate, static_cast<int>(length));
7118 AddPropertiesAndElementsToObject(i_isolate, properties, elements, names,
7119 values, length);
7120 i::Handle<i::JSObject> obj =
7121 i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
7122 i::Handle<i::HeapObject>::cast(proto), properties, elements);
7123 return Utils::ToLocal(obj);
7124 }
7125 }
7126
New(Isolate * isolate,double value)7127 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
7128 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7129 API_RCS_SCOPE(i_isolate, NumberObject, New);
7130 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7131 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
7132 i::Handle<i::Object> obj =
7133 i::Object::ToObject(i_isolate, number).ToHandleChecked();
7134 return Utils::ToLocal(obj);
7135 }
7136
ValueOf() const7137 double v8::NumberObject::ValueOf() const {
7138 i::Handle<i::Object> obj = Utils::OpenHandle(this);
7139 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7140 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7141 API_RCS_SCOPE(js_primitive_wrapper->GetIsolate(), NumberObject, NumberValue);
7142 return js_primitive_wrapper->value().Number();
7143 }
7144
New(Isolate * isolate,int64_t value)7145 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
7146 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7147 API_RCS_SCOPE(i_isolate, BigIntObject, New);
7148 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7149 i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
7150 i::Handle<i::Object> obj =
7151 i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
7152 return Utils::ToLocal(obj);
7153 }
7154
ValueOf() const7155 Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
7156 i::Handle<i::Object> obj = Utils::OpenHandle(this);
7157 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7158 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7159 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7160 API_RCS_SCOPE(isolate, BigIntObject, BigIntValue);
7161 return Utils::ToLocal(i::Handle<i::BigInt>(
7162 i::BigInt::cast(js_primitive_wrapper->value()), isolate));
7163 }
7164
New(Isolate * isolate,bool value)7165 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7166 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7167 API_RCS_SCOPE(i_isolate, BooleanObject, New);
7168 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7169 i::Handle<i::Object> boolean(value
7170 ? i::ReadOnlyRoots(i_isolate).true_value()
7171 : i::ReadOnlyRoots(i_isolate).false_value(),
7172 i_isolate);
7173 i::Handle<i::Object> obj =
7174 i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7175 return Utils::ToLocal(obj);
7176 }
7177
ValueOf() const7178 bool v8::BooleanObject::ValueOf() const {
7179 i::Object obj = *Utils::OpenHandle(this);
7180 i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj);
7181 i::Isolate* isolate = js_primitive_wrapper.GetIsolate();
7182 API_RCS_SCOPE(isolate, BooleanObject, BooleanValue);
7183 return js_primitive_wrapper.value().IsTrue(isolate);
7184 }
7185
New(Isolate * v8_isolate,Local<String> value)7186 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
7187 Local<String> value) {
7188 i::Handle<i::String> string = Utils::OpenHandle(*value);
7189 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7190 API_RCS_SCOPE(isolate, StringObject, New);
7191 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7192 i::Handle<i::Object> obj =
7193 i::Object::ToObject(isolate, string).ToHandleChecked();
7194 return Utils::ToLocal(obj);
7195 }
7196
ValueOf() const7197 Local<v8::String> v8::StringObject::ValueOf() const {
7198 i::Handle<i::Object> obj = Utils::OpenHandle(this);
7199 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7200 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7201 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7202 API_RCS_SCOPE(isolate, StringObject, StringValue);
7203 return Utils::ToLocal(i::Handle<i::String>(
7204 i::String::cast(js_primitive_wrapper->value()), isolate));
7205 }
7206
New(Isolate * isolate,Local<Symbol> value)7207 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7208 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7209 API_RCS_SCOPE(i_isolate, SymbolObject, New);
7210 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7211 i::Handle<i::Object> obj =
7212 i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
7213 .ToHandleChecked();
7214 return Utils::ToLocal(obj);
7215 }
7216
ValueOf() const7217 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7218 i::Handle<i::Object> obj = Utils::OpenHandle(this);
7219 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
7220 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
7221 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
7222 API_RCS_SCOPE(isolate, SymbolObject, SymbolValue);
7223 return Utils::ToLocal(i::Handle<i::Symbol>(
7224 i::Symbol::cast(js_primitive_wrapper->value()), isolate));
7225 }
7226
New(Local<Context> context,double time)7227 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7228 if (std::isnan(time)) {
7229 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7230 time = std::numeric_limits<double>::quiet_NaN();
7231 }
7232 PREPARE_FOR_EXECUTION(context, Date, New, Value);
7233 Local<Value> result;
7234 has_pending_exception = !ToLocal<Value>(
7235 i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7236 &result);
7237 RETURN_ON_FAILED_EXECUTION(Value);
7238 RETURN_ESCAPED(result);
7239 }
7240
ValueOf() const7241 double v8::Date::ValueOf() const {
7242 i::Handle<i::Object> obj = Utils::OpenHandle(this);
7243 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7244 API_RCS_SCOPE(jsdate->GetIsolate(), Date, NumberValue);
7245 return jsdate->value().Number();
7246 }
7247
7248 // Assert that the static TimeZoneDetection cast in
7249 // DateTimeConfigurationChangeNotification is valid.
7250 #define TIME_ZONE_DETECTION_ASSERT_EQ(value) \
7251 STATIC_ASSERT( \
7252 static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
7253 static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
7254 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7255 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
7256 #undef TIME_ZONE_DETECTION_ASSERT_EQ
7257
7258 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7259 Local<String> pattern, Flags flags) {
7260 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7261 Local<v8::RegExp> result;
7262 has_pending_exception =
7263 !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7264 static_cast<i::JSRegExp::Flags>(flags)),
7265 &result);
7266 RETURN_ON_FAILED_EXECUTION(RegExp);
7267 RETURN_ESCAPED(result);
7268 }
7269
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7270 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
7271 Local<Context> context, Local<String> pattern, Flags flags,
7272 uint32_t backtrack_limit) {
7273 Utils::ApiCheck(i::Smi::IsValid(backtrack_limit),
7274 "v8::RegExp::NewWithBacktrackLimit",
7275 "backtrack_limit is too large or too small.");
7276 Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit,
7277 "v8::RegExp::NewWithBacktrackLimit",
7278 "Must set backtrack_limit");
7279 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7280 Local<v8::RegExp> result;
7281 has_pending_exception = !ToLocal<RegExp>(
7282 i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
7283 static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
7284 &result);
7285 RETURN_ON_FAILED_EXECUTION(RegExp);
7286 RETURN_ESCAPED(result);
7287 }
7288
GetSource() const7289 Local<v8::String> v8::RegExp::GetSource() const {
7290 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7291 return Utils::ToLocal(
7292 i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate()));
7293 }
7294
7295 // Assert that the static flags cast in GetFlags is valid.
7296 #define REGEXP_FLAG_ASSERT_EQ(flag) \
7297 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7298 static_cast<int>(i::JSRegExp::flag))
7299 REGEXP_FLAG_ASSERT_EQ(kNone);
7300 REGEXP_FLAG_ASSERT_EQ(kGlobal);
7301 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7302 REGEXP_FLAG_ASSERT_EQ(kMultiline);
7303 REGEXP_FLAG_ASSERT_EQ(kSticky);
7304 REGEXP_FLAG_ASSERT_EQ(kUnicode);
7305 REGEXP_FLAG_ASSERT_EQ(kHasIndices);
7306 REGEXP_FLAG_ASSERT_EQ(kLinear);
7307 #undef REGEXP_FLAG_ASSERT_EQ
7308
GetFlags() const7309 v8::RegExp::Flags v8::RegExp::GetFlags() const {
7310 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7311 return RegExp::Flags(static_cast<int>(obj->flags()));
7312 }
7313
Exec(Local<Context> context,Local<v8::String> subject)7314 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
7315 Local<v8::String> subject) {
7316 PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
7317
7318 i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
7319 i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
7320
7321 // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
7322 // mind. It fetches the 'exec' property and then calls it through JSEntry.
7323 // Unfortunately, this is currently the only full implementation of
7324 // RegExp.prototype.exec available in C++.
7325 Local<v8::Object> result;
7326 has_pending_exception = !ToLocal<Object>(
7327 i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
7328 isolate->factory()->undefined_value()),
7329 &result);
7330
7331 RETURN_ON_FAILED_EXECUTION(Object);
7332 RETURN_ESCAPED(result);
7333 }
7334
New(Isolate * isolate,int length)7335 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7336 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7337 API_RCS_SCOPE(i_isolate, Array, New);
7338 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7339 int real_length = length > 0 ? length : 0;
7340 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7341 i::Handle<i::Object> length_obj =
7342 i_isolate->factory()->NewNumberFromInt(real_length);
7343 obj->set_length(*length_obj);
7344 return Utils::ToLocal(obj);
7345 }
7346
New(Isolate * isolate,Local<Value> * elements,size_t length)7347 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
7348 size_t length) {
7349 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7350 i::Factory* factory = i_isolate->factory();
7351 API_RCS_SCOPE(i_isolate, Array, New);
7352 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7353 int len = static_cast<int>(length);
7354
7355 i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
7356 for (int i = 0; i < len; i++) {
7357 i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
7358 result->set(i, *element);
7359 }
7360
7361 return Utils::ToLocal(
7362 factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
7363 }
7364
Length() const7365 uint32_t v8::Array::Length() const {
7366 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7367 i::Object length = obj->length();
7368 if (length.IsSmi()) {
7369 return i::Smi::ToInt(length);
7370 } else {
7371 return static_cast<uint32_t>(length.Number());
7372 }
7373 }
7374
New(Isolate * isolate)7375 Local<v8::Map> v8::Map::New(Isolate* isolate) {
7376 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7377 API_RCS_SCOPE(i_isolate, Map, New);
7378 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7379 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7380 return Utils::ToLocal(obj);
7381 }
7382
Size() const7383 size_t v8::Map::Size() const {
7384 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7385 return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
7386 }
7387
Clear()7388 void Map::Clear() {
7389 auto self = Utils::OpenHandle(this);
7390 i::Isolate* isolate = self->GetIsolate();
7391 API_RCS_SCOPE(isolate, Map, Clear);
7392 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7393 i::JSMap::Clear(isolate, self);
7394 }
7395
Get(Local<Context> context,Local<Value> key)7396 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7397 PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7398 auto self = Utils::OpenHandle(this);
7399 Local<Value> result;
7400 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7401 has_pending_exception =
7402 !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
7403 self, arraysize(argv), argv),
7404 &result);
7405 RETURN_ON_FAILED_EXECUTION(Value);
7406 RETURN_ESCAPED(result);
7407 }
7408
Set(Local<Context> context,Local<Value> key,Local<Value> value)7409 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7410 Local<Value> value) {
7411 PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7412 auto self = Utils::OpenHandle(this);
7413 i::Handle<i::Object> result;
7414 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7415 Utils::OpenHandle(*value)};
7416 has_pending_exception =
7417 !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
7418 arraysize(argv), argv)
7419 .ToHandle(&result);
7420 RETURN_ON_FAILED_EXECUTION(Map);
7421 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7422 }
7423
Has(Local<Context> context,Local<Value> key)7424 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7425 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7426 ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7427 auto self = Utils::OpenHandle(this);
7428 i::Handle<i::Object> result;
7429 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7430 has_pending_exception =
7431 !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
7432 arraysize(argv), argv)
7433 .ToHandle(&result);
7434 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7435 return Just(result->IsTrue(isolate));
7436 }
7437
Delete(Local<Context> context,Local<Value> key)7438 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7439 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7440 ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7441 auto self = Utils::OpenHandle(this);
7442 i::Handle<i::Object> result;
7443 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7444 has_pending_exception =
7445 !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
7446 arraysize(argv), argv)
7447 .ToHandle(&result);
7448 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7449 return Just(result->IsTrue(isolate));
7450 }
7451
7452 namespace {
7453
7454 enum class MapAsArrayKind {
7455 kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7456 kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7457 kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7458 };
7459
7460 enum class SetAsArrayKind {
7461 kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7462 kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7463 };
7464
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7465 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7466 int offset, MapAsArrayKind kind) {
7467 i::Factory* factory = isolate->factory();
7468 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7469 isolate);
7470 const bool collect_keys =
7471 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7472 const bool collect_values =
7473 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7474 int capacity = table->UsedCapacity();
7475 int max_length =
7476 (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7477 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7478 int result_index = 0;
7479 {
7480 i::DisallowGarbageCollection no_gc;
7481 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7482 for (int i = offset; i < capacity; ++i) {
7483 i::InternalIndex entry(i);
7484 i::Object key = table->KeyAt(entry);
7485 if (key == the_hole) continue;
7486 if (collect_keys) result->set(result_index++, key);
7487 if (collect_values) result->set(result_index++, table->ValueAt(entry));
7488 }
7489 }
7490 DCHECK_GE(max_length, result_index);
7491 if (result_index == 0) return factory->NewJSArray(0);
7492 result->Shrink(isolate, result_index);
7493 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7494 result_index);
7495 }
7496
7497 } // namespace
7498
AsArray() const7499 Local<Array> Map::AsArray() const {
7500 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7501 i::Isolate* isolate = obj->GetIsolate();
7502 API_RCS_SCOPE(isolate, Map, AsArray);
7503 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7504 return Utils::ToLocal(
7505 MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7506 }
7507
New(Isolate * isolate)7508 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7509 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7510 API_RCS_SCOPE(i_isolate, Set, New);
7511 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7512 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7513 return Utils::ToLocal(obj);
7514 }
7515
Size() const7516 size_t v8::Set::Size() const {
7517 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7518 return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7519 }
7520
Clear()7521 void Set::Clear() {
7522 auto self = Utils::OpenHandle(this);
7523 i::Isolate* isolate = self->GetIsolate();
7524 API_RCS_SCOPE(isolate, Set, Clear);
7525 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7526 i::JSSet::Clear(isolate, self);
7527 }
7528
Add(Local<Context> context,Local<Value> key)7529 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7530 PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7531 auto self = Utils::OpenHandle(this);
7532 i::Handle<i::Object> result;
7533 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7534 has_pending_exception =
7535 !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7536 arraysize(argv), argv)
7537 .ToHandle(&result);
7538 RETURN_ON_FAILED_EXECUTION(Set);
7539 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7540 }
7541
Has(Local<Context> context,Local<Value> key)7542 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7543 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7544 ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7545 auto self = Utils::OpenHandle(this);
7546 i::Handle<i::Object> result;
7547 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7548 has_pending_exception =
7549 !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7550 arraysize(argv), argv)
7551 .ToHandle(&result);
7552 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7553 return Just(result->IsTrue(isolate));
7554 }
7555
Delete(Local<Context> context,Local<Value> key)7556 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7557 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7558 ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7559 auto self = Utils::OpenHandle(this);
7560 i::Handle<i::Object> result;
7561 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7562 has_pending_exception =
7563 !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7564 arraysize(argv), argv)
7565 .ToHandle(&result);
7566 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7567 return Just(result->IsTrue(isolate));
7568 }
7569
7570 namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7571 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7572 int offset, SetAsArrayKind kind) {
7573 i::Factory* factory = isolate->factory();
7574 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7575 isolate);
7576 // Elements skipped by |offset| may already be deleted.
7577 int capacity = table->UsedCapacity();
7578 const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7579 int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7580 if (max_length == 0) return factory->NewJSArray(0);
7581 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7582 int result_index = 0;
7583 {
7584 i::DisallowGarbageCollection no_gc;
7585 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7586 for (int i = offset; i < capacity; ++i) {
7587 i::InternalIndex entry(i);
7588 i::Object key = table->KeyAt(entry);
7589 if (key == the_hole) continue;
7590 result->set(result_index++, key);
7591 if (collect_key_values) result->set(result_index++, key);
7592 }
7593 }
7594 DCHECK_GE(max_length, result_index);
7595 if (result_index == 0) return factory->NewJSArray(0);
7596 result->Shrink(isolate, result_index);
7597 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7598 result_index);
7599 }
7600 } // namespace
7601
AsArray() const7602 Local<Array> Set::AsArray() const {
7603 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7604 i::Isolate* isolate = obj->GetIsolate();
7605 API_RCS_SCOPE(isolate, Set, AsArray);
7606 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7607 return Utils::ToLocal(
7608 SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7609 }
7610
New(Local<Context> context)7611 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7612 PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7613 Local<Promise::Resolver> result;
7614 has_pending_exception =
7615 !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7616 RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7617 RETURN_ESCAPED(result);
7618 }
7619
GetPromise()7620 Local<Promise> Promise::Resolver::GetPromise() {
7621 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7622 return Local<Promise>::Cast(Utils::ToLocal(promise));
7623 }
7624
Resolve(Local<Context> context,Local<Value> value)7625 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7626 Local<Value> value) {
7627 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7628 ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7629 i::HandleScope);
7630 auto self = Utils::OpenHandle(this);
7631 auto promise = i::Handle<i::JSPromise>::cast(self);
7632
7633 if (promise->status() != Promise::kPending) {
7634 return Just(true);
7635 }
7636
7637 has_pending_exception =
7638 i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7639 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7640 return Just(true);
7641 }
7642
Reject(Local<Context> context,Local<Value> value)7643 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7644 Local<Value> value) {
7645 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7646 ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7647 i::HandleScope);
7648 auto self = Utils::OpenHandle(this);
7649 auto promise = i::Handle<i::JSPromise>::cast(self);
7650
7651 if (promise->status() != Promise::kPending) {
7652 return Just(true);
7653 }
7654
7655 has_pending_exception =
7656 i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7657 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7658 return Just(true);
7659 }
7660
Catch(Local<Context> context,Local<Function> handler)7661 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7662 Local<Function> handler) {
7663 PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7664 auto self = Utils::OpenHandle(this);
7665 i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(),
7666 Utils::OpenHandle(*handler)};
7667 i::Handle<i::Object> result;
7668 // Do not call the built-in Promise.prototype.catch!
7669 // v8::Promise should not call out to a monkeypatched Promise.prototype.then
7670 // as the implementation of Promise.prototype.catch does.
7671 has_pending_exception =
7672 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7673 arraysize(argv), argv)
7674 .ToHandle(&result);
7675 RETURN_ON_FAILED_EXECUTION(Promise);
7676 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7677 }
7678
Then(Local<Context> context,Local<Function> handler)7679 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7680 Local<Function> handler) {
7681 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7682 auto self = Utils::OpenHandle(this);
7683 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7684 i::Handle<i::Object> result;
7685 has_pending_exception =
7686 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7687 arraysize(argv), argv)
7688 .ToHandle(&result);
7689 RETURN_ON_FAILED_EXECUTION(Promise);
7690 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7691 }
7692
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7693 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7694 Local<Function> on_fulfilled,
7695 Local<Function> on_rejected) {
7696 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7697 auto self = Utils::OpenHandle(this);
7698 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7699 Utils::OpenHandle(*on_rejected)};
7700 i::Handle<i::Object> result;
7701 has_pending_exception =
7702 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7703 arraysize(argv), argv)
7704 .ToHandle(&result);
7705 RETURN_ON_FAILED_EXECUTION(Promise);
7706 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7707 }
7708
HasHandler() const7709 bool Promise::HasHandler() const {
7710 i::JSReceiver promise = *Utils::OpenHandle(this);
7711 i::Isolate* isolate = promise.GetIsolate();
7712 API_RCS_SCOPE(isolate, Promise, HasRejectHandler);
7713 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7714 if (!promise.IsJSPromise()) return false;
7715 return i::JSPromise::cast(promise).has_handler();
7716 }
7717
Result()7718 Local<Value> Promise::Result() {
7719 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7720 i::Isolate* isolate = promise->GetIsolate();
7721 API_RCS_SCOPE(isolate, Promise, Result);
7722 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7723 Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7724 "Promise is still pending");
7725 i::Handle<i::Object> result(js_promise->result(), isolate);
7726 return Utils::ToLocal(result);
7727 }
7728
State()7729 Promise::PromiseState Promise::State() {
7730 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7731 API_RCS_SCOPE(promise->GetIsolate(), Promise, Status);
7732 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7733 return static_cast<PromiseState>(js_promise->status());
7734 }
7735
MarkAsHandled()7736 void Promise::MarkAsHandled() {
7737 i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7738 js_promise->set_has_handler(true);
7739 }
7740
MarkAsSilent()7741 void Promise::MarkAsSilent() {
7742 i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7743 js_promise->set_is_silent(true);
7744 }
7745
GetTarget()7746 Local<Value> Proxy::GetTarget() {
7747 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7748 i::Handle<i::Object> target(self->target(), self->GetIsolate());
7749 return Utils::ToLocal(target);
7750 }
7751
GetHandler()7752 Local<Value> Proxy::GetHandler() {
7753 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7754 i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7755 return Utils::ToLocal(handler);
7756 }
7757
IsRevoked() const7758 bool Proxy::IsRevoked() const {
7759 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7760 return self->IsRevoked();
7761 }
7762
Revoke()7763 void Proxy::Revoke() {
7764 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7765 i::JSProxy::Revoke(self);
7766 }
7767
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7768 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7769 Local<Object> local_handler) {
7770 PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7771 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7772 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7773 Local<Proxy> result;
7774 has_pending_exception =
7775 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7776 RETURN_ON_FAILED_EXECUTION(Proxy);
7777 RETURN_ESCAPED(result);
7778 }
7779
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7780 CompiledWasmModule::CompiledWasmModule(
7781 std::shared_ptr<internal::wasm::NativeModule> native_module,
7782 const char* source_url, size_t url_length)
7783 : native_module_(std::move(native_module)),
7784 source_url_(source_url, url_length) {
7785 CHECK_NOT_NULL(native_module_);
7786 }
7787
Serialize()7788 OwnedBuffer CompiledWasmModule::Serialize() {
7789 #if V8_ENABLE_WEBASSEMBLY
7790 TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7791 i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7792 size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7793 std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7794 if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7795 return {};
7796 return {std::move(buffer), buffer_size};
7797 #else
7798 UNREACHABLE();
7799 #endif // V8_ENABLE_WEBASSEMBLY
7800 }
7801
GetWireBytesRef()7802 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7803 #if V8_ENABLE_WEBASSEMBLY
7804 base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7805 return {bytes_vec.begin(), bytes_vec.size()};
7806 #else
7807 UNREACHABLE();
7808 #endif // V8_ENABLE_WEBASSEMBLY
7809 }
7810
Buffer()7811 Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() {
7812 #if V8_ENABLE_WEBASSEMBLY
7813 i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this);
7814 i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate());
7815 return Utils::ToLocal(buffer);
7816 #else
7817 UNREACHABLE();
7818 #endif // V8_ENABLE_WEBASSEMBLY
7819 }
7820
GetCompiledModule()7821 CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7822 #if V8_ENABLE_WEBASSEMBLY
7823 auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7824 auto url =
7825 i::handle(i::String::cast(obj->script().name()), obj->GetIsolate());
7826 int length;
7827 std::unique_ptr<char[]> cstring =
7828 url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7829 return CompiledWasmModule(std::move(obj->shared_native_module()),
7830 cstring.get(), length);
7831 #else
7832 UNREACHABLE();
7833 #endif // V8_ENABLE_WEBASSEMBLY
7834 }
7835
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7836 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7837 Isolate* isolate, const CompiledWasmModule& compiled_module) {
7838 #if V8_ENABLE_WEBASSEMBLY
7839 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7840 i::Handle<i::WasmModuleObject> module_object =
7841 i::wasm::GetWasmEngine()->ImportNativeModule(
7842 i_isolate, compiled_module.native_module_,
7843 base::VectorOf(compiled_module.source_url()));
7844 return Local<WasmModuleObject>::Cast(
7845 Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7846 #else
7847 UNREACHABLE();
7848 #endif // V8_ENABLE_WEBASSEMBLY
7849 }
7850
Compile(Isolate * isolate,MemorySpan<const uint8_t> wire_bytes)7851 MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
7852 Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) {
7853 #if V8_ENABLE_WEBASSEMBLY
7854 const uint8_t* start = wire_bytes.data();
7855 size_t length = wire_bytes.size();
7856 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7857 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7858 return MaybeLocal<WasmModuleObject>();
7859 }
7860 i::MaybeHandle<i::JSObject> maybe_compiled;
7861 {
7862 i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
7863 auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
7864 maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
7865 i_isolate, enabled_features, &thrower,
7866 i::wasm::ModuleWireBytes(start, start + length));
7867 }
7868 CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception());
7869 if (maybe_compiled.is_null()) {
7870 i_isolate->OptionalRescheduleException(false);
7871 return MaybeLocal<WasmModuleObject>();
7872 }
7873 return Local<WasmModuleObject>::Cast(
7874 Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7875 #else
7876 Utils::ApiCheck(false, "WasmModuleObject::Compile",
7877 "WebAssembly support is not enabled.");
7878 UNREACHABLE();
7879 #endif // V8_ENABLE_WEBASSEMBLY
7880 }
7881
WasmModuleObjectBuilderStreaming(Isolate * isolate)7882 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7883 Isolate* isolate) {
7884 USE(isolate_);
7885 }
7886
GetPromise()7887 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7888
OnBytesReceived(const uint8_t * bytes,size_t size)7889 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7890 size_t size) {}
7891
Finish()7892 void WasmModuleObjectBuilderStreaming::Finish() {}
7893
Abort(MaybeLocal<Value> exception)7894 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7895
Reallocate(void * data,size_t old_length,size_t new_length)7896 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7897 size_t new_length) {
7898 if (old_length == new_length) return data;
7899 uint8_t* new_data =
7900 reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7901 if (new_data == nullptr) return nullptr;
7902 size_t bytes_to_copy = std::min(old_length, new_length);
7903 memcpy(new_data, data, bytes_to_copy);
7904 if (new_length > bytes_to_copy) {
7905 memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7906 }
7907 Free(data, old_length);
7908 return new_data;
7909 }
7910
7911 // static
NewDefaultAllocator()7912 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7913 return new ArrayBufferAllocator();
7914 }
7915
IsDetachable() const7916 bool v8::ArrayBuffer::IsDetachable() const {
7917 return Utils::OpenHandle(this)->is_detachable();
7918 }
7919
WasDetached() const7920 bool v8::ArrayBuffer::WasDetached() const {
7921 return Utils::OpenHandle(this)->was_detached();
7922 }
7923
7924 namespace {
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7925 std::shared_ptr<i::BackingStore> ToInternal(
7926 std::shared_ptr<i::BackingStoreBase> backing_store) {
7927 return std::static_pointer_cast<i::BackingStore>(backing_store);
7928 }
7929 } // namespace
7930
Detach()7931 void v8::ArrayBuffer::Detach() {
7932 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7933 i::Isolate* isolate = obj->GetIsolate();
7934 Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
7935 "Only detachable ArrayBuffers can be detached");
7936 API_RCS_SCOPE(isolate, ArrayBuffer, Detach);
7937 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7938 obj->Detach();
7939 }
7940
ByteLength() const7941 size_t v8::ArrayBuffer::ByteLength() const {
7942 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7943 return obj->byte_length();
7944 }
7945
New(Isolate * isolate,size_t byte_length)7946 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7947 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7948 API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7949 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7950 i::MaybeHandle<i::JSArrayBuffer> result =
7951 i_isolate->factory()->NewJSArrayBufferAndBackingStore(
7952 byte_length, i::InitializedFlag::kZeroInitialized);
7953
7954 i::Handle<i::JSArrayBuffer> array_buffer;
7955 if (!result.ToHandle(&array_buffer)) {
7956 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7957 // version that throws an exception or otherwise does not crash.
7958 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
7959 }
7960
7961 return Utils::ToLocal(array_buffer);
7962 }
7963
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7964 Local<ArrayBuffer> v8::ArrayBuffer::New(
7965 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7966 CHECK_IMPLIES(backing_store->ByteLength() != 0,
7967 backing_store->Data() != nullptr);
7968 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7969 API_RCS_SCOPE(i_isolate, ArrayBuffer, New);
7970 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7971 std::shared_ptr<i::BackingStore> i_backing_store(
7972 ToInternal(std::move(backing_store)));
7973 Utils::ApiCheck(
7974 !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
7975 "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
7976 i::Handle<i::JSArrayBuffer> obj =
7977 i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
7978 return Utils::ToLocal(obj);
7979 }
7980
NewBackingStore(Isolate * isolate,size_t byte_length)7981 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7982 Isolate* isolate, size_t byte_length) {
7983 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7984 API_RCS_SCOPE(i_isolate, ArrayBuffer, NewBackingStore);
7985 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7986 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7987 std::unique_ptr<i::BackingStoreBase> backing_store =
7988 i::BackingStore::Allocate(i_isolate, byte_length,
7989 i::SharedFlag::kNotShared,
7990 i::InitializedFlag::kZeroInitialized);
7991 if (!backing_store) {
7992 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
7993 }
7994 return std::unique_ptr<v8::BackingStore>(
7995 static_cast<v8::BackingStore*>(backing_store.release()));
7996 }
7997
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)7998 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7999 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8000 void* deleter_data) {
8001 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8002 std::unique_ptr<i::BackingStoreBase> backing_store =
8003 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8004 i::SharedFlag::kNotShared);
8005 return std::unique_ptr<v8::BackingStore>(
8006 static_cast<v8::BackingStore*>(backing_store.release()));
8007 }
8008
Buffer()8009 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
8010 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8011 i::Handle<i::JSArrayBuffer> buffer;
8012 if (obj->IsJSDataView()) {
8013 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
8014 obj->GetIsolate());
8015 DCHECK(data_view->buffer().IsJSArrayBuffer());
8016 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
8017 data_view->GetIsolate());
8018 } else {
8019 DCHECK(obj->IsJSTypedArray());
8020 buffer = i::JSTypedArray::cast(*obj).GetBuffer();
8021 }
8022 return Utils::ToLocal(buffer);
8023 }
8024
CopyContents(void * dest,size_t byte_length)8025 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
8026 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8027 size_t bytes_to_copy = std::min(byte_length, self->byte_length());
8028 if (bytes_to_copy) {
8029 i::DisallowGarbageCollection no_gc;
8030 i::Isolate* isolate = self->GetIsolate();
8031 const char* source;
8032 if (self->IsJSTypedArray()) {
8033 i::Handle<i::JSTypedArray> array(i::JSTypedArray::cast(*self), isolate);
8034 source = reinterpret_cast<char*>(array->DataPtr());
8035 } else {
8036 DCHECK(self->IsJSDataView());
8037 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*self), isolate);
8038 source = reinterpret_cast<char*>(data_view->data_pointer());
8039 }
8040 memcpy(dest, source, bytes_to_copy);
8041 }
8042 return bytes_to_copy;
8043 }
8044
HasBuffer() const8045 bool v8::ArrayBufferView::HasBuffer() const {
8046 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8047 if (!self->IsJSTypedArray()) return true;
8048 auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
8049 return !typed_array->is_on_heap();
8050 }
8051
ByteOffset()8052 size_t v8::ArrayBufferView::ByteOffset() {
8053 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8054 return obj->WasDetached() ? 0 : obj->byte_offset();
8055 }
8056
ByteLength()8057 size_t v8::ArrayBufferView::ByteLength() {
8058 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8059 return obj->WasDetached() ? 0 : obj->byte_length();
8060 }
8061
Length()8062 size_t v8::TypedArray::Length() {
8063 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8064 return obj->WasDetached() ? 0 : obj->length();
8065 }
8066
8067 static_assert(
8068 v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
8069 "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
8070
8071 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype) \
8072 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
8073 size_t byte_offset, size_t length) { \
8074 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
8075 API_RCS_SCOPE(isolate, Type##Array, New); \
8076 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
8077 if (!Utils::ApiCheck(length <= kMaxLength, \
8078 "v8::" #Type \
8079 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
8080 "length exceeds max allowed value")) { \
8081 return Local<Type##Array>(); \
8082 } \
8083 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
8084 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
8085 i::kExternal##Type##Array, buffer, byte_offset, length); \
8086 return Utils::ToLocal##Type##Array(obj); \
8087 } \
8088 Local<Type##Array> Type##Array::New( \
8089 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
8090 size_t length) { \
8091 CHECK(i::FLAG_harmony_sharedarraybuffer); \
8092 i::Isolate* isolate = \
8093 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
8094 API_RCS_SCOPE(isolate, Type##Array, New); \
8095 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
8096 if (!Utils::ApiCheck( \
8097 length <= kMaxLength, \
8098 "v8::" #Type \
8099 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
8100 "length exceeds max allowed value")) { \
8101 return Local<Type##Array>(); \
8102 } \
8103 i::Handle<i::JSArrayBuffer> buffer = \
8104 Utils::OpenHandle(*shared_array_buffer); \
8105 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
8106 i::kExternal##Type##Array, buffer, byte_offset, length); \
8107 return Utils::ToLocal##Type##Array(obj); \
8108 }
8109
TYPED_ARRAYS(TYPED_ARRAY_NEW)8110 TYPED_ARRAYS(TYPED_ARRAY_NEW)
8111 #undef TYPED_ARRAY_NEW
8112
8113 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
8114 size_t byte_offset, size_t byte_length) {
8115 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
8116 i::Isolate* isolate = buffer->GetIsolate();
8117 API_RCS_SCOPE(isolate, DataView, New);
8118 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8119 i::Handle<i::JSDataView> obj =
8120 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8121 return Utils::ToLocal(obj);
8122 }
8123
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)8124 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
8125 size_t byte_offset, size_t byte_length) {
8126 CHECK(i::FLAG_harmony_sharedarraybuffer);
8127 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
8128 i::Isolate* isolate = buffer->GetIsolate();
8129 API_RCS_SCOPE(isolate, DataView, New);
8130 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8131 i::Handle<i::JSDataView> obj =
8132 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8133 return Utils::ToLocal(obj);
8134 }
8135
ByteLength() const8136 size_t v8::SharedArrayBuffer::ByteLength() const {
8137 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8138 return obj->byte_length();
8139 }
8140
New(Isolate * isolate,size_t byte_length)8141 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
8142 size_t byte_length) {
8143 CHECK(i::FLAG_harmony_sharedarraybuffer);
8144 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8145 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8146 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8147
8148 std::unique_ptr<i::BackingStore> backing_store =
8149 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8150 i::InitializedFlag::kZeroInitialized);
8151
8152 if (!backing_store) {
8153 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8154 // version that throws an exception or otherwise does not crash.
8155 i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
8156 }
8157
8158 i::Handle<i::JSArrayBuffer> obj =
8159 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
8160 return Utils::ToLocalShared(obj);
8161 }
8162
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8163 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
8164 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
8165 CHECK(i::FLAG_harmony_sharedarraybuffer);
8166 CHECK_IMPLIES(backing_store->ByteLength() != 0,
8167 backing_store->Data() != nullptr);
8168 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8169 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New);
8170 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8171 std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
8172 Utils::ApiCheck(
8173 i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
8174 "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
8175 i::Handle<i::JSArrayBuffer> obj =
8176 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
8177 return Utils::ToLocalShared(obj);
8178 }
8179
NewBackingStore(Isolate * isolate,size_t byte_length)8180 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8181 Isolate* isolate, size_t byte_length) {
8182 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8183 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, NewBackingStore);
8184 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8185 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8186 std::unique_ptr<i::BackingStoreBase> backing_store =
8187 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
8188 i::InitializedFlag::kZeroInitialized);
8189 if (!backing_store) {
8190 i::FatalProcessOutOfMemory(i_isolate,
8191 "v8::SharedArrayBuffer::NewBackingStore");
8192 }
8193 return std::unique_ptr<v8::BackingStore>(
8194 static_cast<v8::BackingStore*>(backing_store.release()));
8195 }
8196
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8197 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
8198 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
8199 void* deleter_data) {
8200 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
8201 std::unique_ptr<i::BackingStoreBase> backing_store =
8202 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
8203 i::SharedFlag::kShared);
8204 return std::unique_ptr<v8::BackingStore>(
8205 static_cast<v8::BackingStore*>(backing_store.release()));
8206 }
8207
New(Isolate * isolate,Local<String> name)8208 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8209 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8210 API_RCS_SCOPE(i_isolate, Symbol, New);
8211 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8212 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8213 if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8214 return Utils::ToLocal(result);
8215 }
8216
For(Isolate * isolate,Local<String> name)8217 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8218 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8219 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8220 return Utils::ToLocal(
8221 i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8222 }
8223
ForApi(Isolate * isolate,Local<String> name)8224 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8225 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8226 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8227 return Utils::ToLocal(
8228 i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8229 }
8230
8231 #define WELL_KNOWN_SYMBOLS(V) \
8232 V(AsyncIterator, async_iterator) \
8233 V(HasInstance, has_instance) \
8234 V(IsConcatSpreadable, is_concat_spreadable) \
8235 V(Iterator, iterator) \
8236 V(Match, match) \
8237 V(Replace, replace) \
8238 V(Search, search) \
8239 V(Split, split) \
8240 V(ToPrimitive, to_primitive) \
8241 V(ToStringTag, to_string_tag) \
8242 V(Unscopables, unscopables)
8243
8244 #define SYMBOL_GETTER(Name, name) \
8245 Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) { \
8246 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8247 return Utils::ToLocal(i_isolate->factory()->name##_symbol()); \
8248 }
8249
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8250 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8251
8252 #undef SYMBOL_GETTER
8253 #undef WELL_KNOWN_SYMBOLS
8254
8255 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8256 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8257 API_RCS_SCOPE(i_isolate, Private, New);
8258 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8259 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8260 if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8261 Local<Symbol> result = Utils::ToLocal(symbol);
8262 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8263 }
8264
ForApi(Isolate * isolate,Local<String> name)8265 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8266 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8267 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8268 Local<Symbol> result = Utils::ToLocal(
8269 i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8270 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8271 }
8272
New(Isolate * isolate,double value)8273 Local<Number> v8::Number::New(Isolate* isolate, double value) {
8274 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8275 if (std::isnan(value)) {
8276 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8277 value = std::numeric_limits<double>::quiet_NaN();
8278 }
8279 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8280 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8281 return Utils::NumberToLocal(result);
8282 }
8283
New(Isolate * isolate,int32_t value)8284 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8285 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8286 if (i::Smi::IsValid(value)) {
8287 return Utils::IntegerToLocal(
8288 i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8289 }
8290 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8291 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8292 return Utils::IntegerToLocal(result);
8293 }
8294
NewFromUnsigned(Isolate * isolate,uint32_t value)8295 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8296 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8297 bool fits_into_int32_t = (value & (1 << 31)) == 0;
8298 if (fits_into_int32_t) {
8299 return Integer::New(isolate, static_cast<int32_t>(value));
8300 }
8301 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8302 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8303 return Utils::IntegerToLocal(result);
8304 }
8305
New(Isolate * isolate,int64_t value)8306 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8307 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8308 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8309 i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8310 return Utils::ToLocal(result);
8311 }
8312
NewFromUnsigned(Isolate * isolate,uint64_t value)8313 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8314 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8315 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8316 i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8317 return Utils::ToLocal(result);
8318 }
8319
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8320 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8321 int sign_bit, int word_count,
8322 const uint64_t* words) {
8323 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8324 ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8325 MaybeLocal<BigInt>(), InternalEscapableScope);
8326 i::MaybeHandle<i::BigInt> result =
8327 i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8328 has_pending_exception = result.is_null();
8329 RETURN_ON_FAILED_EXECUTION(BigInt);
8330 RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8331 }
8332
Uint64Value(bool * lossless) const8333 uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8334 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8335 return handle->AsUint64(lossless);
8336 }
8337
Int64Value(bool * lossless) const8338 int64_t v8::BigInt::Int64Value(bool* lossless) const {
8339 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8340 return handle->AsInt64(lossless);
8341 }
8342
WordCount() const8343 int BigInt::WordCount() const {
8344 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8345 return handle->Words64Count();
8346 }
8347
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8348 void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8349 uint64_t* words) const {
8350 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8351 return handle->ToWordsArray64(sign_bit, word_count, words);
8352 }
8353
ReportExternalAllocationLimitReached()8354 void Isolate::ReportExternalAllocationLimitReached() {
8355 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8356 if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8357 heap->ReportExternalMemoryPressure();
8358 }
8359
GetHeapProfiler()8360 HeapProfiler* Isolate::GetHeapProfiler() {
8361 i::HeapProfiler* heap_profiler =
8362 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8363 return reinterpret_cast<HeapProfiler*>(heap_profiler);
8364 }
8365
SetIdle(bool is_idle)8366 void Isolate::SetIdle(bool is_idle) {
8367 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8368 isolate->SetIdle(is_idle);
8369 }
8370
GetArrayBufferAllocator()8371 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8372 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8373 return isolate->array_buffer_allocator();
8374 }
8375
InContext()8376 bool Isolate::InContext() {
8377 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8378 return !isolate->context().is_null();
8379 }
8380
ClearKeptObjects()8381 void Isolate::ClearKeptObjects() {
8382 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8383 isolate->ClearKeptObjects();
8384 }
8385
GetCurrentContext()8386 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8387 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8388 i::Context context = isolate->context();
8389 if (context.is_null()) return Local<Context>();
8390 i::Context native_context = context.native_context();
8391 if (native_context.is_null()) return Local<Context>();
8392 return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8393 }
8394
GetEnteredOrMicrotaskContext()8395 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8396 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8397 i::Handle<i::Object> last =
8398 isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8399 if (last.is_null()) return Local<Context>();
8400 DCHECK(last->IsNativeContext());
8401 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8402 }
8403
GetIncumbentContext()8404 v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8405 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8406 i::Handle<i::Context> context = isolate->GetIncumbentContext();
8407 return Utils::ToLocal(context);
8408 }
8409
ThrowError(v8::Local<v8::String> message)8410 v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) {
8411 return ThrowException(v8::Exception::Error(message));
8412 }
8413
ThrowException(v8::Local<v8::Value> value)8414 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8415 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8416 ENTER_V8_DO_NOT_USE(isolate);
8417 // If we're passed an empty handle, we throw an undefined exception
8418 // to deal more gracefully with out of memory situations.
8419 if (value.IsEmpty()) {
8420 isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8421 } else {
8422 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8423 }
8424 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8425 }
8426
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8427 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8428 GCType gc_type) {
8429 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8430 isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8431 }
8432
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8433 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8434 void* data) {
8435 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8436 isolate->heap()->RemoveGCPrologueCallback(callback, data);
8437 }
8438
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8439 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8440 GCType gc_type) {
8441 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8442 isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8443 }
8444
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8445 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8446 void* data) {
8447 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8448 isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8449 }
8450
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8451 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8452 GCCallbackFlags flags, void* data) {
8453 reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8454 }
8455
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8456 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8457 void* data = reinterpret_cast<void*>(callback);
8458 AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8459 }
8460
RemoveGCPrologueCallback(GCCallback callback)8461 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8462 void* data = reinterpret_cast<void*>(callback);
8463 RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8464 }
8465
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8466 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8467 void* data = reinterpret_cast<void*>(callback);
8468 AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8469 }
8470
RemoveGCEpilogueCallback(GCCallback callback)8471 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8472 void* data = reinterpret_cast<void*>(callback);
8473 RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8474 }
8475
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8476 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8477 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8478 CHECK_NULL(isolate->heap()->cpp_heap());
8479 isolate->heap()->SetEmbedderHeapTracer(tracer);
8480 }
8481
GetEmbedderHeapTracer()8482 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8483 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8484 return isolate->heap()->GetEmbedderHeapTracer();
8485 }
8486
SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8487 void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
8488 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8489 isolate->heap()->SetEmbedderRootsHandler(handler);
8490 }
8491
AttachCppHeap(CppHeap * cpp_heap)8492 void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
8493 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8494 CHECK_NULL(GetEmbedderHeapTracer());
8495 isolate->heap()->AttachCppHeap(cpp_heap);
8496 }
8497
DetachCppHeap()8498 void Isolate::DetachCppHeap() {
8499 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8500 isolate->heap()->DetachCppHeap();
8501 }
8502
GetCppHeap() const8503 CppHeap* Isolate::GetCppHeap() const {
8504 const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
8505 return isolate->heap()->cpp_heap();
8506 }
8507
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8508 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8509 GetExternallyAllocatedMemoryInBytesCallback callback) {
8510 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8511 isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8512 }
8513
TerminateExecution()8514 void Isolate::TerminateExecution() {
8515 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8516 isolate->stack_guard()->RequestTerminateExecution();
8517 }
8518
IsExecutionTerminating()8519 bool Isolate::IsExecutionTerminating() {
8520 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8521 return IsExecutionTerminatingCheck(isolate);
8522 }
8523
CancelTerminateExecution()8524 void Isolate::CancelTerminateExecution() {
8525 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8526 isolate->stack_guard()->ClearTerminateExecution();
8527 isolate->CancelTerminateExecution();
8528 }
8529
RequestInterrupt(InterruptCallback callback,void * data)8530 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8531 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8532 isolate->RequestInterrupt(callback, data);
8533 }
8534
HasPendingBackgroundTasks()8535 bool Isolate::HasPendingBackgroundTasks() {
8536 #if V8_ENABLE_WEBASSEMBLY
8537 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8538 return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate);
8539 #else
8540 return false;
8541 #endif // V8_ENABLE_WEBASSEMBLY
8542 }
8543
RequestGarbageCollectionForTesting(GarbageCollectionType type)8544 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8545 Utils::ApiCheck(i::FLAG_expose_gc,
8546 "v8::Isolate::RequestGarbageCollectionForTesting",
8547 "Must use --expose-gc");
8548 if (type == kMinorGarbageCollection) {
8549 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8550 i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8551 kGCCallbackFlagForced);
8552 } else {
8553 DCHECK_EQ(kFullGarbageCollection, type);
8554 reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8555 i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8556 kGCCallbackFlagForced);
8557 }
8558 }
8559
RequestGarbageCollectionForTesting(GarbageCollectionType type,EmbedderHeapTracer::EmbedderStackState stack_state)8560 void Isolate::RequestGarbageCollectionForTesting(
8561 GarbageCollectionType type,
8562 EmbedderHeapTracer::EmbedderStackState stack_state) {
8563 base::Optional<i::EmbedderStackStateScope> stack_scope;
8564 if (type == kFullGarbageCollection) {
8565 stack_scope.emplace(reinterpret_cast<i::Isolate*>(this)->heap(),
8566 i::EmbedderStackStateScope::kExplicitInvocation,
8567 stack_state);
8568 }
8569 RequestGarbageCollectionForTesting(type);
8570 }
8571
GetCurrent()8572 Isolate* Isolate::GetCurrent() {
8573 i::Isolate* isolate = i::Isolate::Current();
8574 return reinterpret_cast<Isolate*>(isolate);
8575 }
8576
TryGetCurrent()8577 Isolate* Isolate::TryGetCurrent() {
8578 i::Isolate* isolate = i::Isolate::TryGetCurrent();
8579 return reinterpret_cast<Isolate*>(isolate);
8580 }
8581
IsCurrent() const8582 bool Isolate::IsCurrent() const {
8583 return reinterpret_cast<const i::Isolate*>(this)->IsCurrent();
8584 }
8585
8586 // static
Allocate()8587 Isolate* Isolate::Allocate() {
8588 return reinterpret_cast<Isolate*>(i::Isolate::New());
8589 }
8590
8591 Isolate::CreateParams::CreateParams() = default;
8592
8593 Isolate::CreateParams::~CreateParams() = default;
8594
8595 // static
8596 // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8597 void Isolate::Initialize(Isolate* isolate,
8598 const v8::Isolate::CreateParams& params) {
8599 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8600 TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.IsolateInitialize");
8601 if (auto allocator = params.array_buffer_allocator_shared) {
8602 CHECK(params.array_buffer_allocator == nullptr ||
8603 params.array_buffer_allocator == allocator.get());
8604 i_isolate->set_array_buffer_allocator(allocator.get());
8605 i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8606 } else {
8607 CHECK_NOT_NULL(params.array_buffer_allocator);
8608 i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8609 }
8610 if (params.snapshot_blob != nullptr) {
8611 i_isolate->set_snapshot_blob(params.snapshot_blob);
8612 } else {
8613 i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8614 }
8615
8616 if (params.fatal_error_callback) {
8617 isolate->SetFatalErrorHandler(params.fatal_error_callback);
8618 }
8619
8620 if (params.oom_error_callback) {
8621 isolate->SetOOMErrorHandler(params.oom_error_callback);
8622 }
8623
8624 if (params.counter_lookup_callback) {
8625 isolate->SetCounterFunction(params.counter_lookup_callback);
8626 }
8627
8628 if (params.create_histogram_callback) {
8629 isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8630 }
8631
8632 if (params.add_histogram_sample_callback) {
8633 isolate->SetAddHistogramSampleFunction(
8634 params.add_histogram_sample_callback);
8635 }
8636
8637 i_isolate->set_api_external_references(params.external_references);
8638 i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8639
8640 i_isolate->heap()->ConfigureHeap(params.constraints);
8641 if (params.constraints.stack_limit() != nullptr) {
8642 uintptr_t limit =
8643 reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8644 i_isolate->stack_guard()->SetStackLimit(limit);
8645 }
8646
8647 if (params.experimental_attach_to_shared_isolate != nullptr) {
8648 i_isolate->set_shared_isolate(reinterpret_cast<i::Isolate*>(
8649 params.experimental_attach_to_shared_isolate));
8650 }
8651
8652 // TODO(v8:2487): Once we got rid of Isolate::Current(), we can remove this.
8653 Isolate::Scope isolate_scope(isolate);
8654 if (i_isolate->snapshot_blob() == nullptr) {
8655 FATAL(
8656 "V8 snapshot blob was not set during initialization. This can mean "
8657 "that the snapshot blob file is corrupted or missing.");
8658 }
8659 if (!i::Snapshot::Initialize(i_isolate)) {
8660 // If snapshot data was provided and we failed to deserialize it must
8661 // have been corrupted.
8662 FATAL(
8663 "Failed to deserialize the V8 snapshot blob. This can mean that the "
8664 "snapshot blob file is corrupted or missing.");
8665 }
8666
8667 {
8668 // Set up code event handlers. Needs to be after i::Snapshot::Initialize
8669 // because that is where we add the isolate to WasmEngine.
8670 auto code_event_handler = params.code_event_handler;
8671 if (code_event_handler) {
8672 isolate->SetJitCodeEventHandler(kJitCodeEventEnumExisting,
8673 code_event_handler);
8674 }
8675 }
8676
8677 i_isolate->set_only_terminate_in_safe_scope(
8678 params.only_terminate_in_safe_scope);
8679 i_isolate->set_embedder_wrapper_type_index(
8680 params.embedder_wrapper_type_index);
8681 i_isolate->set_embedder_wrapper_object_index(
8682 params.embedder_wrapper_object_index);
8683
8684 if (!i::V8::GetCurrentPlatform()
8685 ->GetForegroundTaskRunner(isolate)
8686 ->NonNestableTasksEnabled()) {
8687 FATAL(
8688 "The current platform's foreground task runner does not have "
8689 "non-nestable tasks enabled. The embedder must provide one.");
8690 }
8691 }
8692
New(const Isolate::CreateParams & params)8693 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8694 Isolate* isolate = Allocate();
8695 Initialize(isolate, params);
8696 return isolate;
8697 }
8698
Dispose()8699 void Isolate::Dispose() {
8700 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8701 if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8702 "Disposing the isolate that is entered by a thread.")) {
8703 return;
8704 }
8705 i::Isolate::Delete(isolate);
8706 }
8707
DumpAndResetStats()8708 void Isolate::DumpAndResetStats() {
8709 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8710 isolate->DumpAndResetStats();
8711 }
8712
DiscardThreadSpecificMetadata()8713 void Isolate::DiscardThreadSpecificMetadata() {
8714 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8715 isolate->DiscardPerThreadDataForThisThread();
8716 }
8717
Enter()8718 void Isolate::Enter() {
8719 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8720 isolate->Enter();
8721 }
8722
Exit()8723 void Isolate::Exit() {
8724 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8725 isolate->Exit();
8726 }
8727
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8728 void Isolate::SetAbortOnUncaughtExceptionCallback(
8729 AbortOnUncaughtExceptionCallback callback) {
8730 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8731 isolate->SetAbortOnUncaughtExceptionCallback(callback);
8732 }
8733
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8734 void Isolate::SetHostImportModuleDynamicallyCallback(
8735 HostImportModuleDynamicallyWithImportAssertionsCallback callback) {
8736 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8737 isolate->SetHostImportModuleDynamicallyCallback(callback);
8738 }
8739
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8740 void Isolate::SetHostImportModuleDynamicallyCallback(
8741 HostImportModuleDynamicallyCallback callback) {
8742 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8743 isolate->SetHostImportModuleDynamicallyCallback(callback);
8744 }
8745
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8746 void Isolate::SetHostInitializeImportMetaObjectCallback(
8747 HostInitializeImportMetaObjectCallback callback) {
8748 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8749 isolate->SetHostInitializeImportMetaObjectCallback(callback);
8750 }
8751
SetHostCreateShadowRealmContextCallback(HostCreateShadowRealmContextCallback callback)8752 void Isolate::SetHostCreateShadowRealmContextCallback(
8753 HostCreateShadowRealmContextCallback callback) {
8754 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8755 isolate->SetHostCreateShadowRealmContextCallback(callback);
8756 }
8757
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8758 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8759 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8760 isolate->SetPrepareStackTraceCallback(callback);
8761 }
8762
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8763 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8764 Isolate* isolate,
8765 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8766 : on_failure_(on_failure), isolate_(isolate) {
8767 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8768 switch (on_failure_) {
8769 case CRASH_ON_FAILURE:
8770 i::DisallowJavascriptExecution::Open(i_isolate,
8771 &was_execution_allowed_assert_);
8772 break;
8773 case THROW_ON_FAILURE:
8774 i::ThrowOnJavascriptExecution::Open(i_isolate,
8775 &was_execution_allowed_throws_);
8776 break;
8777 case DUMP_ON_FAILURE:
8778 i::DumpOnJavascriptExecution::Open(i_isolate,
8779 &was_execution_allowed_dump_);
8780 break;
8781 default:
8782 UNREACHABLE();
8783 }
8784 }
8785
~DisallowJavascriptExecutionScope()8786 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8787 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8788 switch (on_failure_) {
8789 case CRASH_ON_FAILURE:
8790 i::DisallowJavascriptExecution::Close(i_isolate,
8791 was_execution_allowed_assert_);
8792 break;
8793 case THROW_ON_FAILURE:
8794 i::ThrowOnJavascriptExecution::Close(i_isolate,
8795 was_execution_allowed_throws_);
8796 break;
8797 case DUMP_ON_FAILURE:
8798 i::DumpOnJavascriptExecution::Close(i_isolate,
8799 was_execution_allowed_dump_);
8800 break;
8801 default:
8802 UNREACHABLE();
8803 }
8804 }
8805
AllowJavascriptExecutionScope(Isolate * isolate)8806 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8807 Isolate* isolate)
8808 : isolate_(isolate) {
8809 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8810 i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_);
8811 i::NoThrowOnJavascriptExecution::Open(i_isolate,
8812 &was_execution_allowed_throws_);
8813 i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_);
8814 }
8815
~AllowJavascriptExecutionScope()8816 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8817 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
8818 i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_);
8819 i::NoThrowOnJavascriptExecution::Close(i_isolate,
8820 was_execution_allowed_throws_);
8821 i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_);
8822 }
8823
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8824 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8825 Isolate* isolate, MicrotaskQueue* microtask_queue)
8826 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8827 microtask_queue_(microtask_queue
8828 ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8829 : isolate_->default_microtask_queue()) {
8830 isolate_->thread_local_top()->IncrementCallDepth(this);
8831 microtask_queue_->IncrementMicrotasksSuppressions();
8832 }
8833
~SuppressMicrotaskExecutionScope()8834 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8835 microtask_queue_->DecrementMicrotasksSuppressions();
8836 isolate_->thread_local_top()->DecrementCallDepth(this);
8837 }
8838
SafeForTerminationScope(v8::Isolate * isolate)8839 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8840 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8841 prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8842 isolate_->set_next_v8_call_is_safe_for_termination(true);
8843 }
8844
~SafeForTerminationScope()8845 Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8846 isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8847 }
8848
GetDataFromSnapshotOnce(size_t index)8849 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8850 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8851 i::FixedArray list = i_isolate->heap()->serialized_objects();
8852 return GetSerializedDataFromFixedArray(i_isolate, list, index);
8853 }
8854
GetHeapStatistics(HeapStatistics * heap_statistics)8855 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8856 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8857 i::Heap* heap = isolate->heap();
8858
8859 // The order of acquiring memory statistics is important here. We query in
8860 // this order because of concurrent allocation: 1) used memory 2) comitted
8861 // physical memory 3) committed memory. Therefore the condition used <=
8862 // committed physical <= committed should hold.
8863 heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8864 heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8865 DCHECK_LE(heap_statistics->used_global_handles_size_,
8866 heap_statistics->total_global_handles_size_);
8867
8868 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8869 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8870 heap_statistics->total_heap_size_ = heap->CommittedMemory();
8871
8872 heap_statistics->total_available_size_ = heap->Available();
8873
8874 if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8875 i::ReadOnlySpace* ro_space = heap->read_only_space();
8876 heap_statistics->used_heap_size_ += ro_space->Size();
8877 heap_statistics->total_physical_size_ +=
8878 ro_space->CommittedPhysicalMemory();
8879 heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8880 }
8881
8882 // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8883 // this and add DCHECK.
8884 DCHECK_LE(heap_statistics->used_heap_size_,
8885 heap_statistics->total_heap_size_);
8886
8887 heap_statistics->total_heap_size_executable_ =
8888 heap->CommittedMemoryExecutable();
8889 heap_statistics->heap_size_limit_ = heap->MaxReserved();
8890 // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8891 // API becomes available we should report the malloced memory separately. For
8892 // now we just add the values, thereby over-approximating the peak slightly.
8893 heap_statistics->malloced_memory_ =
8894 isolate->allocator()->GetCurrentMemoryUsage() +
8895 isolate->string_table()->GetCurrentMemoryUsage();
8896 // On 32-bit systems backing_store_bytes() might overflow size_t temporarily
8897 // due to concurrent array buffer sweeping.
8898 heap_statistics->external_memory_ =
8899 isolate->heap()->backing_store_bytes() < SIZE_MAX
8900 ? static_cast<size_t>(isolate->heap()->backing_store_bytes())
8901 : SIZE_MAX;
8902 heap_statistics->peak_malloced_memory_ =
8903 isolate->allocator()->GetMaxMemoryUsage();
8904 heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8905 heap_statistics->number_of_detached_contexts_ =
8906 heap->NumberOfDetachedContexts();
8907 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8908
8909 #if V8_ENABLE_WEBASSEMBLY
8910 heap_statistics->malloced_memory_ +=
8911 i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage();
8912 heap_statistics->peak_malloced_memory_ +=
8913 i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage();
8914 #endif // V8_ENABLE_WEBASSEMBLY
8915 }
8916
NumberOfHeapSpaces()8917 size_t Isolate::NumberOfHeapSpaces() {
8918 return i::LAST_SPACE - i::FIRST_SPACE + 1;
8919 }
8920
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8921 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8922 size_t index) {
8923 if (!space_statistics) return false;
8924 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8925 return false;
8926
8927 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8928 i::Heap* heap = isolate->heap();
8929
8930 i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
8931 space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
8932
8933 if (allocation_space == i::RO_SPACE) {
8934 if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8935 // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
8936 space_statistics->space_size_ = 0;
8937 space_statistics->space_used_size_ = 0;
8938 space_statistics->space_available_size_ = 0;
8939 space_statistics->physical_space_size_ = 0;
8940 } else {
8941 i::ReadOnlySpace* space = heap->read_only_space();
8942 space_statistics->space_size_ = space->CommittedMemory();
8943 space_statistics->space_used_size_ = space->Size();
8944 space_statistics->space_available_size_ = 0;
8945 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8946 }
8947 } else {
8948 i::Space* space = heap->space(static_cast<int>(index));
8949 space_statistics->space_size_ = space ? space->CommittedMemory() : 0;
8950 space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0;
8951 space_statistics->space_available_size_ = space ? space->Available() : 0;
8952 space_statistics->physical_space_size_ =
8953 space ? space->CommittedPhysicalMemory() : 0;
8954 }
8955 return true;
8956 }
8957
NumberOfTrackedHeapObjectTypes()8958 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8959 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8960 i::Heap* heap = isolate->heap();
8961 return heap->NumberOfTrackedHeapObjectTypes();
8962 }
8963
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8964 bool Isolate::GetHeapObjectStatisticsAtLastGC(
8965 HeapObjectStatistics* object_statistics, size_t type_index) {
8966 if (!object_statistics) return false;
8967 if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
8968
8969 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8970 i::Heap* heap = isolate->heap();
8971 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8972
8973 const char* object_type;
8974 const char* object_sub_type;
8975 size_t object_count = heap->ObjectCountAtLastGC(type_index);
8976 size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8977 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8978 // There should be no objects counted when the type is unknown.
8979 DCHECK_EQ(object_count, 0U);
8980 DCHECK_EQ(object_size, 0U);
8981 return false;
8982 }
8983
8984 object_statistics->object_type_ = object_type;
8985 object_statistics->object_sub_type_ = object_sub_type;
8986 object_statistics->object_count_ = object_count;
8987 object_statistics->object_size_ = object_size;
8988 return true;
8989 }
8990
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)8991 bool Isolate::GetHeapCodeAndMetadataStatistics(
8992 HeapCodeStatistics* code_statistics) {
8993 if (!code_statistics) return false;
8994
8995 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8996 isolate->heap()->CollectCodeStatistics();
8997
8998 code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8999 code_statistics->bytecode_and_metadata_size_ =
9000 isolate->bytecode_and_metadata_size();
9001 code_statistics->external_script_source_size_ =
9002 isolate->external_script_source_size();
9003 code_statistics->cpu_profiler_metadata_size_ =
9004 i::CpuProfiler::GetAllProfilersMemorySize(
9005 reinterpret_cast<i::Isolate*>(isolate));
9006
9007 return true;
9008 }
9009
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)9010 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
9011 MeasureMemoryExecution execution) {
9012 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9013 return isolate->heap()->MeasureMemory(std::move(delegate), execution);
9014 }
9015
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)9016 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
9017 Isolate* isolate, Local<Context> context,
9018 Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
9019 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9020 i::Handle<i::NativeContext> native_context =
9021 handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
9022 i::Handle<i::JSPromise> js_promise =
9023 i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
9024 return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
9025 mode);
9026 }
9027
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)9028 void Isolate::GetStackSample(const RegisterState& state, void** frames,
9029 size_t frames_limit, SampleInfo* sample_info) {
9030 RegisterState regs = state;
9031 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9032 if (i::TickSample::GetStackSample(isolate, ®s,
9033 i::TickSample::kSkipCEntryFrame, frames,
9034 frames_limit, sample_info)) {
9035 return;
9036 }
9037 sample_info->frames_count = 0;
9038 sample_info->vm_state = OTHER;
9039 sample_info->external_callback_entry = nullptr;
9040 }
9041
NumberOfPhantomHandleResetsSinceLastCall()9042 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
9043 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9044 return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
9045 }
9046
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)9047 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
9048 int64_t change_in_bytes) {
9049 // Try to check for unreasonably large or small values from the embedder.
9050 const int64_t kMaxReasonableBytes = int64_t(1) << 60;
9051 const int64_t kMinReasonableBytes = -kMaxReasonableBytes;
9052 STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength);
9053
9054 CHECK(kMinReasonableBytes <= change_in_bytes &&
9055 change_in_bytes < kMaxReasonableBytes);
9056
9057 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9058 int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
9059
9060 if (change_in_bytes <= 0) return amount;
9061
9062 if (amount > i_isolate->heap()->external_memory_limit()) {
9063 ReportExternalAllocationLimitReached();
9064 }
9065 return amount;
9066 }
9067
SetEventLogger(LogEventCallback that)9068 void Isolate::SetEventLogger(LogEventCallback that) {
9069 // Do not overwrite the event logger if we want to log explicitly.
9070 if (i::FLAG_log_internal_timer_events) return;
9071 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9072 isolate->set_event_logger(that);
9073 }
9074
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9075 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
9076 if (callback == nullptr) return;
9077 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9078 isolate->AddBeforeCallEnteredCallback(callback);
9079 }
9080
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9081 void Isolate::RemoveBeforeCallEnteredCallback(
9082 BeforeCallEnteredCallback callback) {
9083 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9084 isolate->RemoveBeforeCallEnteredCallback(callback);
9085 }
9086
AddCallCompletedCallback(CallCompletedCallback callback)9087 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
9088 if (callback == nullptr) return;
9089 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9090 isolate->AddCallCompletedCallback(callback);
9091 }
9092
RemoveCallCompletedCallback(CallCompletedCallback callback)9093 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
9094 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9095 isolate->RemoveCallCompletedCallback(callback);
9096 }
9097
Wake()9098 void Isolate::AtomicsWaitWakeHandle::Wake() {
9099 reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
9100 }
9101
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)9102 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
9103 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9104 isolate->SetAtomicsWaitCallback(callback, data);
9105 }
9106
SetPromiseHook(PromiseHook hook)9107 void Isolate::SetPromiseHook(PromiseHook hook) {
9108 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9109 isolate->SetPromiseHook(hook);
9110 }
9111
SetPromiseRejectCallback(PromiseRejectCallback callback)9112 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
9113 if (callback == nullptr) return;
9114 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9115 isolate->SetPromiseRejectCallback(callback);
9116 }
9117
PerformMicrotaskCheckpoint()9118 void Isolate::PerformMicrotaskCheckpoint() {
9119 DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
9120 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9121 isolate->default_microtask_queue()->PerformCheckpoint(this);
9122 }
9123
EnqueueMicrotask(Local<Function> v8_function)9124 void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
9125 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9126 i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
9127 i::Handle<i::NativeContext> handler_context;
9128 if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
9129 &handler_context))
9130 handler_context = isolate->native_context();
9131 MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
9132 if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
9133 }
9134
EnqueueMicrotask(MicrotaskCallback callback,void * data)9135 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
9136 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9137 isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
9138 }
9139
SetMicrotasksPolicy(MicrotasksPolicy policy)9140 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9141 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9142 isolate->default_microtask_queue()->set_microtasks_policy(policy);
9143 }
9144
GetMicrotasksPolicy() const9145 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
9146 i::Isolate* isolate =
9147 reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
9148 return isolate->default_microtask_queue()->microtasks_policy();
9149 }
9150
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9151 void Isolate::AddMicrotasksCompletedCallback(
9152 MicrotasksCompletedCallbackWithData callback, void* data) {
9153 DCHECK(callback);
9154 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9155 isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
9156 data);
9157 }
9158
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9159 void Isolate::RemoveMicrotasksCompletedCallback(
9160 MicrotasksCompletedCallbackWithData callback, void* data) {
9161 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9162 isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
9163 callback, data);
9164 }
9165
SetUseCounterCallback(UseCounterCallback callback)9166 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9167 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9168 }
9169
SetCounterFunction(CounterLookupCallback callback)9170 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9171 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9172 isolate->counters()->ResetCounterFunction(callback);
9173 }
9174
SetCreateHistogramFunction(CreateHistogramCallback callback)9175 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9176 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9177 isolate->counters()->ResetCreateHistogramFunction(callback);
9178 }
9179
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)9180 void Isolate::SetAddHistogramSampleFunction(
9181 AddHistogramSampleCallback callback) {
9182 reinterpret_cast<i::Isolate*>(this)
9183 ->counters()
9184 ->SetAddHistogramSampleFunction(callback);
9185 }
9186
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)9187 void Isolate::SetMetricsRecorder(
9188 const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
9189 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9190 isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder);
9191 }
9192
SetAddCrashKeyCallback(AddCrashKeyCallback callback)9193 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
9194 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9195 isolate->SetAddCrashKeyCallback(callback);
9196 }
9197
IdleNotificationDeadline(double deadline_in_seconds)9198 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
9199 // Returning true tells the caller that it need not
9200 // continue to call IdleNotification.
9201 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9202 if (!i::FLAG_use_idle_notification) return true;
9203 return isolate->heap()->IdleNotification(deadline_in_seconds);
9204 }
9205
LowMemoryNotification()9206 void Isolate::LowMemoryNotification() {
9207 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9208 {
9209 i::NestedTimedHistogramScope idle_notification_scope(
9210 isolate->counters()->gc_low_memory_notification());
9211 TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9212 isolate->heap()->CollectAllAvailableGarbage(
9213 i::GarbageCollectionReason::kLowMemoryNotification);
9214 }
9215 }
9216
ContextDisposedNotification(bool dependant_context)9217 int Isolate::ContextDisposedNotification(bool dependant_context) {
9218 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9219 #if V8_ENABLE_WEBASSEMBLY
9220 if (!dependant_context) {
9221 if (!isolate->context().is_null()) {
9222 // We left the current context, we can abort all WebAssembly compilations
9223 // of that context.
9224 // A handle scope for the native context.
9225 i::HandleScope handle_scope(isolate);
9226 i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext(
9227 isolate->native_context());
9228 }
9229 }
9230 #endif // V8_ENABLE_WEBASSEMBLY
9231 // TODO(ahaas): move other non-heap activity out of the heap call.
9232 return isolate->heap()->NotifyContextDisposed(dependant_context);
9233 }
9234
IsolateInForegroundNotification()9235 void Isolate::IsolateInForegroundNotification() {
9236 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9237 return isolate->IsolateInForegroundNotification();
9238 }
9239
IsolateInBackgroundNotification()9240 void Isolate::IsolateInBackgroundNotification() {
9241 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9242 return isolate->IsolateInBackgroundNotification();
9243 }
9244
MemoryPressureNotification(MemoryPressureLevel level)9245 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9246 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9247 bool on_isolate_thread =
9248 isolate->was_locker_ever_used()
9249 ? isolate->thread_manager()->IsLockedByCurrentThread()
9250 : i::ThreadId::Current() == isolate->thread_id();
9251 isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9252 }
9253
ClearCachesForTesting()9254 void Isolate::ClearCachesForTesting() {
9255 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9256 isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock);
9257 isolate->ClearSerializerData();
9258 }
9259
EnableMemorySavingsMode()9260 void Isolate::EnableMemorySavingsMode() {
9261 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9262 isolate->EnableMemorySavingsMode();
9263 }
9264
DisableMemorySavingsMode()9265 void Isolate::DisableMemorySavingsMode() {
9266 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9267 isolate->DisableMemorySavingsMode();
9268 }
9269
SetRAILMode(RAILMode rail_mode)9270 void Isolate::SetRAILMode(RAILMode rail_mode) {
9271 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9272 return isolate->SetRAILMode(rail_mode);
9273 }
9274
UpdateLoadStartTime()9275 void Isolate::UpdateLoadStartTime() {
9276 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9277 isolate->UpdateLoadStartTime();
9278 }
9279
IncreaseHeapLimitForDebugging()9280 void Isolate::IncreaseHeapLimitForDebugging() {
9281 // No-op.
9282 }
9283
RestoreOriginalHeapLimit()9284 void Isolate::RestoreOriginalHeapLimit() {
9285 // No-op.
9286 }
9287
IsHeapLimitIncreasedForDebugging()9288 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
9289
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9290 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9291 JitCodeEventHandler event_handler) {
9292 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9293 // Ensure that logging is initialized for our isolate.
9294 isolate->InitializeLoggingAndCounters();
9295 isolate->logger()->SetCodeEventHandler(options, event_handler);
9296 }
9297
SetStackLimit(uintptr_t stack_limit)9298 void Isolate::SetStackLimit(uintptr_t stack_limit) {
9299 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9300 CHECK(stack_limit);
9301 isolate->stack_guard()->SetStackLimit(stack_limit);
9302 }
9303
GetCodeRange(void ** start,size_t * length_in_bytes)9304 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9305 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9306 const base::AddressRegion& code_region = isolate->heap()->code_region();
9307 *start = reinterpret_cast<void*>(code_region.begin());
9308 *length_in_bytes = code_region.size();
9309 }
9310
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9311 void Isolate::GetEmbeddedCodeRange(const void** start,
9312 size_t* length_in_bytes) {
9313 // Note, we should return the embedded code rande from the .text section here.
9314 i::EmbeddedData d = i::EmbeddedData::FromBlob();
9315 *start = reinterpret_cast<const void*>(d.code());
9316 *length_in_bytes = d.code_size();
9317 }
9318
GetJSEntryStubs()9319 JSEntryStubs Isolate::GetJSEntryStubs() {
9320 JSEntryStubs entry_stubs;
9321
9322 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9323 std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = {
9324 {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub},
9325 {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9326 {i::Builtin::kJSRunMicrotasksEntry,
9327 &entry_stubs.js_run_microtasks_entry_stub}}};
9328 for (auto& pair : stubs) {
9329 i::Code js_entry = FromCodeT(isolate->builtins()->code(pair.first));
9330 pair.second->code.start =
9331 reinterpret_cast<const void*>(js_entry.InstructionStart());
9332 pair.second->code.length_in_bytes = js_entry.InstructionSize();
9333 }
9334
9335 return entry_stubs;
9336 }
9337
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9338 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9339 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9340 // Not implemented on other platforms.
9341 UNREACHABLE();
9342 #else
9343
9344 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9345 std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9346
9347 DCHECK_NOT_NULL(code_pages);
9348
9349 // Copy as many elements into the output vector as we can. If the
9350 // caller-provided buffer is not big enough, we fill it, and the caller can
9351 // provide a bigger one next time. We do it this way because allocation is not
9352 // allowed in signal handlers.
9353 size_t limit = std::min(capacity, code_pages->size());
9354 for (size_t i = 0; i < limit; i++) {
9355 code_pages_out[i] = code_pages->at(i);
9356 }
9357 return code_pages->size();
9358 #endif
9359 }
9360
9361 #define CALLBACK_SETTER(ExternalName, Type, InternalName) \
9362 void Isolate::Set##ExternalName(Type callback) { \
9363 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9364 isolate->set_##InternalName(callback); \
9365 }
9366
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9367 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9368 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9369 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9370 ModifyCodeGenerationFromStringsCallback2,
9371 modify_code_gen_callback2)
9372 CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9373 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9374
9375 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9376 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9377
9378 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9379 wasm_streaming_callback)
9380
9381 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9382 wasm_load_source_map_callback)
9383
9384 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9385 wasm_simd_enabled_callback)
9386
9387 CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback,
9388 wasm_exceptions_enabled_callback)
9389
9390 CALLBACK_SETTER(WasmDynamicTieringEnabledCallback,
9391 WasmDynamicTieringEnabledCallback,
9392 wasm_dynamic_tiering_enabled_callback)
9393
9394 CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
9395 SharedArrayBufferConstructorEnabledCallback,
9396 sharedarraybuffer_constructor_enabled_callback)
9397
9398 void Isolate::InstallConditionalFeatures(Local<Context> context) {
9399 v8::HandleScope handle_scope(this);
9400 v8::Context::Scope context_scope(context);
9401 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9402 isolate->InstallConditionalFeatures(Utils::OpenHandle(*context));
9403 #if V8_ENABLE_WEBASSEMBLY
9404 if (i::FLAG_expose_wasm) {
9405 i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context));
9406 }
9407 #endif // V8_ENABLE_WEBASSEMBLY
9408 }
9409
AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9410 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9411 void* data) {
9412 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9413 isolate->heap()->AddNearHeapLimitCallback(callback, data);
9414 }
9415
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9416 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9417 size_t heap_limit) {
9418 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9419 isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9420 }
9421
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9422 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9423 DCHECK_GT(threshold_percent, 0.0);
9424 DCHECK_LT(threshold_percent, 1.0);
9425 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9426 isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9427 }
9428
IsDead()9429 bool Isolate::IsDead() {
9430 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9431 return isolate->IsDead();
9432 }
9433
AddMessageListener(MessageCallback that,Local<Value> data)9434 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9435 return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9436 }
9437
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9438 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9439 int message_levels,
9440 Local<Value> data) {
9441 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9442 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9443 i::HandleScope scope(isolate);
9444 i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9445 i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9446 i::Handle<i::Foreign> foreign =
9447 isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9448 listener->set(0, *foreign);
9449 listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9450 : *Utils::OpenHandle(*data));
9451 listener->set(2, i::Smi::FromInt(message_levels));
9452 list = i::TemplateList::Add(isolate, list, listener);
9453 isolate->heap()->SetMessageListeners(*list);
9454 return true;
9455 }
9456
RemoveMessageListeners(MessageCallback that)9457 void Isolate::RemoveMessageListeners(MessageCallback that) {
9458 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9459 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9460 i::HandleScope scope(isolate);
9461 i::DisallowGarbageCollection no_gc;
9462 i::TemplateList listeners = isolate->heap()->message_listeners();
9463 for (int i = 0; i < listeners.length(); i++) {
9464 if (listeners.get(i).IsUndefined(isolate)) continue; // skip deleted ones
9465 i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9466 i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9467 if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9468 listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9469 }
9470 }
9471 }
9472
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9473 void Isolate::SetFailedAccessCheckCallbackFunction(
9474 FailedAccessCheckCallback callback) {
9475 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9476 isolate->SetFailedAccessCheckCallback(callback);
9477 }
9478
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9479 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9480 bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9481 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9482 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9483 options);
9484 }
9485
VisitExternalResources(ExternalResourceVisitor * visitor)9486 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9487 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9488 isolate->heap()->VisitExternalResources(visitor);
9489 }
9490
IsInUse()9491 bool Isolate::IsInUse() {
9492 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9493 return isolate->IsInUse();
9494 }
9495
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9496 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9497 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9498 i::DisallowGarbageCollection no_gc;
9499 isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9500 }
9501
VisitWeakHandles(PersistentHandleVisitor * visitor)9502 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9503 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9504 i::DisallowGarbageCollection no_gc;
9505 isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9506 }
9507
SetAllowAtomicsWait(bool allow)9508 void Isolate::SetAllowAtomicsWait(bool allow) {
9509 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9510 isolate->set_allow_atomics_wait(allow);
9511 }
9512
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9513 void v8::Isolate::DateTimeConfigurationChangeNotification(
9514 TimeZoneDetection time_zone_detection) {
9515 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9516 API_RCS_SCOPE(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9517 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9518 i_isolate->date_cache()->ResetDateCache(
9519 static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9520 #ifdef V8_INTL_SUPPORT
9521 i_isolate->clear_cached_icu_object(
9522 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9523 i_isolate->clear_cached_icu_object(
9524 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9525 i_isolate->clear_cached_icu_object(
9526 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9527 #endif // V8_INTL_SUPPORT
9528 }
9529
LocaleConfigurationChangeNotification()9530 void v8::Isolate::LocaleConfigurationChangeNotification() {
9531 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9532 API_RCS_SCOPE(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9533 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9534
9535 #ifdef V8_INTL_SUPPORT
9536 i_isolate->ResetDefaultLocale();
9537 #endif // V8_INTL_SUPPORT
9538 }
9539
IsCodeLike(v8::Isolate * isolate) const9540 bool v8::Object::IsCodeLike(v8::Isolate* isolate) const {
9541 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9542 API_RCS_SCOPE(i_isolate, Object, IsCodeLike);
9543 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9544 i::HandleScope scope(i_isolate);
9545 return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9546 }
9547
9548 // static
New(Isolate * isolate,MicrotasksPolicy policy)9549 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9550 MicrotasksPolicy policy) {
9551 auto microtask_queue =
9552 i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9553 microtask_queue->set_microtasks_policy(policy);
9554 std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9555 return ret;
9556 }
9557
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9558 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9559 : MicrotasksScope(isolate, nullptr, type) {}
9560
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9561 MicrotasksScope::MicrotasksScope(Isolate* isolate,
9562 MicrotaskQueue* microtask_queue,
9563 MicrotasksScope::Type type)
9564 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9565 microtask_queue_(microtask_queue
9566 ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9567 : isolate_->default_microtask_queue()),
9568 run_(type == MicrotasksScope::kRunMicrotasks) {
9569 if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9570 #ifdef DEBUG
9571 if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9572 #endif
9573 }
9574
~MicrotasksScope()9575 MicrotasksScope::~MicrotasksScope() {
9576 if (run_) {
9577 microtask_queue_->DecrementMicrotasksScopeDepth();
9578 if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9579 !isolate_->has_scheduled_exception()) {
9580 DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9581 isolate_->scheduled_exception() ==
9582 i::ReadOnlyRoots(isolate_).termination_exception());
9583 microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9584 }
9585 }
9586 #ifdef DEBUG
9587 if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9588 #endif
9589 }
9590
9591 // static
PerformCheckpoint(Isolate * v8_isolate)9592 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9593 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9594 auto* microtask_queue = isolate->default_microtask_queue();
9595 microtask_queue->PerformCheckpoint(v8_isolate);
9596 }
9597
9598 // static
GetCurrentDepth(Isolate * v8_isolate)9599 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9600 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9601 auto* microtask_queue = isolate->default_microtask_queue();
9602 return microtask_queue->GetMicrotasksScopeDepth();
9603 }
9604
9605 // static
IsRunningMicrotasks(Isolate * v8_isolate)9606 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9607 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9608 auto* microtask_queue = isolate->default_microtask_queue();
9609 return microtask_queue->IsRunningMicrotasks();
9610 }
9611
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9612 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9613 : str_(nullptr), length_(0) {
9614 if (obj.IsEmpty()) return;
9615 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9616 ENTER_V8_DO_NOT_USE(i_isolate);
9617 i::HandleScope scope(i_isolate);
9618 Local<Context> context = isolate->GetCurrentContext();
9619 TryCatch try_catch(isolate);
9620 Local<String> str;
9621 if (!obj->ToString(context).ToLocal(&str)) return;
9622 length_ = str->Utf8Length(isolate);
9623 str_ = i::NewArray<char>(length_ + 1);
9624 str->WriteUtf8(isolate, str_);
9625 }
9626
~Utf8Value()9627 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9628
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9629 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9630 : str_(nullptr), length_(0) {
9631 if (obj.IsEmpty()) return;
9632 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9633 ENTER_V8_DO_NOT_USE(i_isolate);
9634 i::HandleScope scope(i_isolate);
9635 Local<Context> context = isolate->GetCurrentContext();
9636 TryCatch try_catch(isolate);
9637 Local<String> str;
9638 if (!obj->ToString(context).ToLocal(&str)) return;
9639 length_ = str->Length();
9640 str_ = i::NewArray<uint16_t>(length_ + 1);
9641 str->Write(isolate, str_);
9642 }
9643
~Value()9644 String::Value::~Value() { i::DeleteArray(str_); }
9645
9646 #define DEFINE_ERROR(NAME, name) \
9647 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
9648 i::Isolate* isolate = i::Isolate::Current(); \
9649 API_RCS_SCOPE(isolate, NAME, New); \
9650 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
9651 i::Object error; \
9652 { \
9653 i::HandleScope scope(isolate); \
9654 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
9655 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9656 error = *isolate->factory()->NewError(constructor, message); \
9657 } \
9658 i::Handle<i::Object> result(error, isolate); \
9659 return Utils::ToLocal(result); \
9660 }
9661
DEFINE_ERROR(RangeError,range_error)9662 DEFINE_ERROR(RangeError, range_error)
9663 DEFINE_ERROR(ReferenceError, reference_error)
9664 DEFINE_ERROR(SyntaxError, syntax_error)
9665 DEFINE_ERROR(TypeError, type_error)
9666 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9667 DEFINE_ERROR(WasmLinkError, wasm_link_error)
9668 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9669 DEFINE_ERROR(Error, error)
9670
9671 #undef DEFINE_ERROR
9672
9673 Local<Message> Exception::CreateMessage(Isolate* isolate,
9674 Local<Value> exception) {
9675 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9676 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9677 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9678 i::HandleScope scope(i_isolate);
9679 return Utils::MessageToLocal(
9680 scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9681 }
9682
GetStackTrace(Local<Value> exception)9683 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9684 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9685 if (!obj->IsJSObject()) return Local<StackTrace>();
9686 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9687 i::Isolate* isolate = js_obj->GetIsolate();
9688 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9689 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9690 }
9691
PreviewEntries(bool * is_key_value)9692 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
9693 if (IsMap()) {
9694 *is_key_value = true;
9695 return Map::Cast(this)->AsArray();
9696 }
9697 if (IsSet()) {
9698 *is_key_value = false;
9699 return Set::Cast(this)->AsArray();
9700 }
9701
9702 i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
9703 i::Isolate* isolate = object->GetIsolate();
9704 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
9705 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9706 if (object->IsJSWeakCollection()) {
9707 *is_key_value = object->IsJSWeakMap();
9708 return Utils::ToLocal(i::JSWeakCollection::GetEntries(
9709 i::Handle<i::JSWeakCollection>::cast(object), 0));
9710 }
9711 if (object->IsJSMapIterator()) {
9712 i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
9713 MapAsArrayKind const kind =
9714 static_cast<MapAsArrayKind>(it->map().instance_type());
9715 *is_key_value = kind == MapAsArrayKind::kEntries;
9716 if (!it->HasMore()) return v8::Array::New(v8_isolate);
9717 return Utils::ToLocal(
9718 MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9719 }
9720 if (object->IsJSSetIterator()) {
9721 i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
9722 SetAsArrayKind const kind =
9723 static_cast<SetAsArrayKind>(it->map().instance_type());
9724 *is_key_value = kind == SetAsArrayKind::kEntries;
9725 if (!it->HasMore()) return v8::Array::New(v8_isolate);
9726 return Utils::ToLocal(
9727 SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
9728 }
9729 return v8::MaybeLocal<v8::Array>();
9730 }
9731
GetFunctionName() const9732 Local<String> CpuProfileNode::GetFunctionName() const {
9733 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9734 i::Isolate* isolate = node->isolate();
9735 const i::CodeEntry* entry = node->entry();
9736 i::Handle<i::String> name =
9737 isolate->factory()->InternalizeUtf8String(entry->name());
9738 return ToApiHandle<String>(name);
9739 }
9740
GetFunctionNameStr() const9741 const char* CpuProfileNode::GetFunctionNameStr() const {
9742 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9743 return node->entry()->name();
9744 }
9745
GetScriptId() const9746 int CpuProfileNode::GetScriptId() const {
9747 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9748 const i::CodeEntry* entry = node->entry();
9749 return entry->script_id();
9750 }
9751
GetScriptResourceName() const9752 Local<String> CpuProfileNode::GetScriptResourceName() const {
9753 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9754 i::Isolate* isolate = node->isolate();
9755 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
9756 node->entry()->resource_name()));
9757 }
9758
GetScriptResourceNameStr() const9759 const char* CpuProfileNode::GetScriptResourceNameStr() const {
9760 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9761 return node->entry()->resource_name();
9762 }
9763
IsScriptSharedCrossOrigin() const9764 bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
9765 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9766 return node->entry()->is_shared_cross_origin();
9767 }
9768
GetLineNumber() const9769 int CpuProfileNode::GetLineNumber() const {
9770 return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
9771 }
9772
GetColumnNumber() const9773 int CpuProfileNode::GetColumnNumber() const {
9774 return reinterpret_cast<const i::ProfileNode*>(this)
9775 ->entry()
9776 ->column_number();
9777 }
9778
GetHitLineCount() const9779 unsigned int CpuProfileNode::GetHitLineCount() const {
9780 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9781 return node->GetHitLineCount();
9782 }
9783
GetLineTicks(LineTick * entries,unsigned int length) const9784 bool CpuProfileNode::GetLineTicks(LineTick* entries,
9785 unsigned int length) const {
9786 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9787 return node->GetLineTicks(entries, length);
9788 }
9789
GetBailoutReason() const9790 const char* CpuProfileNode::GetBailoutReason() const {
9791 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9792 return node->entry()->bailout_reason();
9793 }
9794
GetHitCount() const9795 unsigned CpuProfileNode::GetHitCount() const {
9796 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
9797 }
9798
GetNodeId() const9799 unsigned CpuProfileNode::GetNodeId() const {
9800 return reinterpret_cast<const i::ProfileNode*>(this)->id();
9801 }
9802
GetSourceType() const9803 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
9804 return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
9805 }
9806
GetChildrenCount() const9807 int CpuProfileNode::GetChildrenCount() const {
9808 return static_cast<int>(
9809 reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
9810 }
9811
GetChild(int index) const9812 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
9813 const i::ProfileNode* child =
9814 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
9815 return reinterpret_cast<const CpuProfileNode*>(child);
9816 }
9817
GetParent() const9818 const CpuProfileNode* CpuProfileNode::GetParent() const {
9819 const i::ProfileNode* parent =
9820 reinterpret_cast<const i::ProfileNode*>(this)->parent();
9821 return reinterpret_cast<const CpuProfileNode*>(parent);
9822 }
9823
GetDeoptInfos() const9824 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
9825 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
9826 return node->deopt_infos();
9827 }
9828
Delete()9829 void CpuProfile::Delete() {
9830 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
9831 i::CpuProfiler* profiler = profile->cpu_profiler();
9832 DCHECK_NOT_NULL(profiler);
9833 profiler->DeleteProfile(profile);
9834 }
9835
GetTitle() const9836 Local<String> CpuProfile::GetTitle() const {
9837 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9838 i::Isolate* isolate = profile->top_down()->isolate();
9839 return ToApiHandle<String>(
9840 isolate->factory()->InternalizeUtf8String(profile->title()));
9841 }
9842
GetTopDownRoot() const9843 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
9844 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9845 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
9846 }
9847
GetSample(int index) const9848 const CpuProfileNode* CpuProfile::GetSample(int index) const {
9849 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9850 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
9851 }
9852
9853 const int CpuProfileNode::kNoLineNumberInfo;
9854 const int CpuProfileNode::kNoColumnNumberInfo;
9855
GetSampleTimestamp(int index) const9856 int64_t CpuProfile::GetSampleTimestamp(int index) const {
9857 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9858 return profile->sample(index).timestamp.since_origin().InMicroseconds();
9859 }
9860
GetSampleState(int index) const9861 StateTag CpuProfile::GetSampleState(int index) const {
9862 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9863 return profile->sample(index).state_tag;
9864 }
9865
GetSampleEmbedderState(int index) const9866 EmbedderStateTag CpuProfile::GetSampleEmbedderState(int index) const {
9867 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9868 return profile->sample(index).embedder_state_tag;
9869 }
9870
GetStartTime() const9871 int64_t CpuProfile::GetStartTime() const {
9872 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9873 return profile->start_time().since_origin().InMicroseconds();
9874 }
9875
GetEndTime() const9876 int64_t CpuProfile::GetEndTime() const {
9877 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
9878 return profile->end_time().since_origin().InMicroseconds();
9879 }
9880
GetSamplesCount() const9881 int CpuProfile::GetSamplesCount() const {
9882 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
9883 }
9884
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)9885 CpuProfiler* CpuProfiler::New(Isolate* isolate,
9886 CpuProfilingNamingMode naming_mode,
9887 CpuProfilingLoggingMode logging_mode) {
9888 return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
9889 reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
9890 }
9891
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)9892 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
9893 unsigned max_samples,
9894 int sampling_interval_us,
9895 MaybeLocal<Context> filter_context)
9896 : mode_(mode),
9897 max_samples_(max_samples),
9898 sampling_interval_us_(sampling_interval_us) {
9899 if (!filter_context.IsEmpty()) {
9900 Local<Context> local_filter_context = filter_context.ToLocalChecked();
9901 filter_context_.Reset(local_filter_context->GetIsolate(),
9902 local_filter_context);
9903 filter_context_.SetWeak();
9904 }
9905 }
9906
raw_filter_context() const9907 void* CpuProfilingOptions::raw_filter_context() const {
9908 return reinterpret_cast<void*>(
9909 i::Context::cast(*Utils::OpenPersistent(filter_context_))
9910 .native_context()
9911 .address());
9912 }
9913
Dispose()9914 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
9915
9916 // static
CollectSample(Isolate * isolate)9917 void CpuProfiler::CollectSample(Isolate* isolate) {
9918 i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
9919 }
9920
SetSamplingInterval(int us)9921 void CpuProfiler::SetSamplingInterval(int us) {
9922 DCHECK_GE(us, 0);
9923 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
9924 base::TimeDelta::FromMicroseconds(us));
9925 }
9926
SetUsePreciseSampling(bool use_precise_sampling)9927 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
9928 reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
9929 use_precise_sampling);
9930 }
9931
Start(CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9932 CpuProfilingResult CpuProfiler::Start(
9933 CpuProfilingOptions options,
9934 std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9935 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9936 options, std::move(delegate));
9937 }
9938
Start(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9939 CpuProfilingResult CpuProfiler::Start(
9940 Local<String> title, CpuProfilingOptions options,
9941 std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9942 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9943 *Utils::OpenHandle(*title), options, std::move(delegate));
9944 }
9945
Start(Local<String> title,bool record_samples)9946 CpuProfilingResult CpuProfiler::Start(Local<String> title,
9947 bool record_samples) {
9948 CpuProfilingOptions options(
9949 kLeafNodeLineNumbers,
9950 record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
9951 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9952 *Utils::OpenHandle(*title), options);
9953 }
9954
Start(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9955 CpuProfilingResult CpuProfiler::Start(Local<String> title,
9956 CpuProfilingMode mode,
9957 bool record_samples,
9958 unsigned max_samples) {
9959 CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
9960 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
9961 *Utils::OpenHandle(*title), options);
9962 }
9963
StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9964 CpuProfilingStatus CpuProfiler::StartProfiling(
9965 Local<String> title, CpuProfilingOptions options,
9966 std::unique_ptr<DiscardedSamplesDelegate> delegate) {
9967 return Start(title, options, std::move(delegate)).status;
9968 }
9969
StartProfiling(Local<String> title,bool record_samples)9970 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9971 bool record_samples) {
9972 return Start(title, record_samples).status;
9973 }
9974
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9975 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
9976 CpuProfilingMode mode,
9977 bool record_samples,
9978 unsigned max_samples) {
9979 return Start(title, mode, record_samples, max_samples).status;
9980 }
9981
StopProfiling(Local<String> title)9982 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
9983 return reinterpret_cast<CpuProfile*>(
9984 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
9985 *Utils::OpenHandle(*title)));
9986 }
9987
Stop(ProfilerId id)9988 CpuProfile* CpuProfiler::Stop(ProfilerId id) {
9989 return reinterpret_cast<CpuProfile*>(
9990 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id));
9991 }
9992
UseDetailedSourcePositionsForProfiling(Isolate * isolate)9993 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
9994 reinterpret_cast<i::Isolate*>(isolate)
9995 ->SetDetailedSourcePositionsForProfiling(true);
9996 }
9997
GetCodeStartAddress()9998 uintptr_t CodeEvent::GetCodeStartAddress() {
9999 return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10000 }
10001
GetCodeSize()10002 size_t CodeEvent::GetCodeSize() {
10003 return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10004 }
10005
GetFunctionName()10006 Local<String> CodeEvent::GetFunctionName() {
10007 return ToApiHandle<String>(
10008 reinterpret_cast<i::CodeEvent*>(this)->function_name);
10009 }
10010
GetScriptName()10011 Local<String> CodeEvent::GetScriptName() {
10012 return ToApiHandle<String>(
10013 reinterpret_cast<i::CodeEvent*>(this)->script_name);
10014 }
10015
GetScriptLine()10016 int CodeEvent::GetScriptLine() {
10017 return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10018 }
10019
GetScriptColumn()10020 int CodeEvent::GetScriptColumn() {
10021 return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10022 }
10023
GetCodeType()10024 CodeEventType CodeEvent::GetCodeType() {
10025 return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10026 }
10027
GetComment()10028 const char* CodeEvent::GetComment() {
10029 return reinterpret_cast<i::CodeEvent*>(this)->comment;
10030 }
10031
GetPreviousCodeStartAddress()10032 uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10033 return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10034 }
10035
GetCodeEventTypeName(CodeEventType code_event_type)10036 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
10037 switch (code_event_type) {
10038 case kUnknownType:
10039 return "Unknown";
10040 #define V(Name) \
10041 case k##Name##Type: \
10042 return #Name;
10043 CODE_EVENTS_LIST(V)
10044 #undef V
10045 }
10046 // The execution should never pass here
10047 UNREACHABLE();
10048 }
10049
CodeEventHandler(Isolate * isolate)10050 CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10051 internal_listener_ =
10052 new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10053 }
10054
~CodeEventHandler()10055 CodeEventHandler::~CodeEventHandler() {
10056 delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10057 }
10058
Enable()10059 void CodeEventHandler::Enable() {
10060 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10061 ->StartListening(this);
10062 }
10063
Disable()10064 void CodeEventHandler::Disable() {
10065 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10066 ->StopListening();
10067 }
10068
ToInternal(const HeapGraphEdge * edge)10069 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10070 return const_cast<i::HeapGraphEdge*>(
10071 reinterpret_cast<const i::HeapGraphEdge*>(edge));
10072 }
10073
GetType() const10074 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10075 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10076 }
10077
GetName() const10078 Local<Value> HeapGraphEdge::GetName() const {
10079 i::HeapGraphEdge* edge = ToInternal(this);
10080 i::Isolate* isolate = edge->isolate();
10081 switch (edge->type()) {
10082 case i::HeapGraphEdge::kContextVariable:
10083 case i::HeapGraphEdge::kInternal:
10084 case i::HeapGraphEdge::kProperty:
10085 case i::HeapGraphEdge::kShortcut:
10086 case i::HeapGraphEdge::kWeak:
10087 return ToApiHandle<String>(
10088 isolate->factory()->InternalizeUtf8String(edge->name()));
10089 case i::HeapGraphEdge::kElement:
10090 case i::HeapGraphEdge::kHidden:
10091 return ToApiHandle<Number>(
10092 isolate->factory()->NewNumberFromInt(edge->index()));
10093 default:
10094 UNREACHABLE();
10095 }
10096 }
10097
GetFromNode() const10098 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10099 const i::HeapEntry* from = ToInternal(this)->from();
10100 return reinterpret_cast<const HeapGraphNode*>(from);
10101 }
10102
GetToNode() const10103 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10104 const i::HeapEntry* to = ToInternal(this)->to();
10105 return reinterpret_cast<const HeapGraphNode*>(to);
10106 }
10107
ToInternal(const HeapGraphNode * entry)10108 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10109 return const_cast<i::HeapEntry*>(
10110 reinterpret_cast<const i::HeapEntry*>(entry));
10111 }
10112
GetType() const10113 HeapGraphNode::Type HeapGraphNode::GetType() const {
10114 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10115 }
10116
GetName() const10117 Local<String> HeapGraphNode::GetName() const {
10118 i::Isolate* isolate = ToInternal(this)->isolate();
10119 return ToApiHandle<String>(
10120 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10121 }
10122
GetId() const10123 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10124
GetShallowSize() const10125 size_t HeapGraphNode::GetShallowSize() const {
10126 return ToInternal(this)->self_size();
10127 }
10128
GetChildrenCount() const10129 int HeapGraphNode::GetChildrenCount() const {
10130 return ToInternal(this)->children_count();
10131 }
10132
GetChild(int index) const10133 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10134 return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10135 }
10136
ToInternal(const HeapSnapshot * snapshot)10137 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10138 return const_cast<i::HeapSnapshot*>(
10139 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10140 }
10141
Delete()10142 void HeapSnapshot::Delete() {
10143 i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10144 if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
10145 isolate->heap_profiler()->IsTakingSnapshot()) {
10146 ToInternal(this)->Delete();
10147 } else {
10148 // If this is the last snapshot, clean up all accessory data as well.
10149 isolate->heap_profiler()->DeleteAllSnapshots();
10150 }
10151 }
10152
GetRoot() const10153 const HeapGraphNode* HeapSnapshot::GetRoot() const {
10154 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10155 }
10156
GetNodeById(SnapshotObjectId id) const10157 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10158 return reinterpret_cast<const HeapGraphNode*>(
10159 ToInternal(this)->GetEntryById(id));
10160 }
10161
GetNodesCount() const10162 int HeapSnapshot::GetNodesCount() const {
10163 return static_cast<int>(ToInternal(this)->entries().size());
10164 }
10165
GetNode(int index) const10166 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10167 return reinterpret_cast<const HeapGraphNode*>(
10168 &ToInternal(this)->entries().at(index));
10169 }
10170
GetMaxSnapshotJSObjectId() const10171 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10172 return ToInternal(this)->max_snapshot_js_object_id();
10173 }
10174
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10175 void HeapSnapshot::Serialize(OutputStream* stream,
10176 HeapSnapshot::SerializationFormat format) const {
10177 Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
10178 "Unknown serialization format");
10179 Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
10180 "Invalid stream chunk size");
10181 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10182 serializer.Serialize(stream);
10183 }
10184
10185 // static
10186 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10187 HeapProfiler::kUnknownObjectId;
10188
GetSnapshotCount()10189 int HeapProfiler::GetSnapshotCount() {
10190 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10191 }
10192
GetHeapSnapshot(int index)10193 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10194 return reinterpret_cast<const HeapSnapshot*>(
10195 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10196 }
10197
GetObjectId(Local<Value> value)10198 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10199 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10200 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10201 }
10202
GetObjectId(NativeObject value)10203 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10204 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10205 }
10206
FindObjectById(SnapshotObjectId id)10207 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10208 i::Handle<i::Object> obj =
10209 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10210 if (obj.is_null()) return Local<Value>();
10211 return Utils::ToLocal(obj);
10212 }
10213
ClearObjectIds()10214 void HeapProfiler::ClearObjectIds() {
10215 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10216 }
10217
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)10218 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
10219 ActivityControl* control, ObjectNameResolver* resolver,
10220 bool treat_global_objects_as_roots, bool capture_numeric_value) {
10221 return reinterpret_cast<const HeapSnapshot*>(
10222 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
10223 control, resolver, treat_global_objects_as_roots,
10224 capture_numeric_value));
10225 }
10226
StartTrackingHeapObjects(bool track_allocations)10227 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10228 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10229 track_allocations);
10230 }
10231
StopTrackingHeapObjects()10232 void HeapProfiler::StopTrackingHeapObjects() {
10233 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10234 }
10235
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)10236 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
10237 int64_t* timestamp_us) {
10238 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
10239 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
10240 }
10241
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)10242 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
10243 int stack_depth,
10244 SamplingFlags flags) {
10245 return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
10246 sample_interval, stack_depth, flags);
10247 }
10248
StopSamplingHeapProfiler()10249 void HeapProfiler::StopSamplingHeapProfiler() {
10250 reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10251 }
10252
GetAllocationProfile()10253 AllocationProfile* HeapProfiler::GetAllocationProfile() {
10254 return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10255 }
10256
DeleteAllHeapSnapshots()10257 void HeapProfiler::DeleteAllHeapSnapshots() {
10258 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10259 }
10260
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10261 void HeapProfiler::AddBuildEmbedderGraphCallback(
10262 BuildEmbedderGraphCallback callback, void* data) {
10263 reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
10264 callback, data);
10265 }
10266
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10267 void HeapProfiler::RemoveBuildEmbedderGraphCallback(
10268 BuildEmbedderGraphCallback callback, void* data) {
10269 reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
10270 callback, data);
10271 }
10272
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10273 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
10274 void* data) {
10275 reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
10276 data);
10277 }
10278
SetStackStart(void * stack_start)10279 void EmbedderHeapTracer::SetStackStart(void* stack_start) {
10280 CHECK(isolate_);
10281 reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
10282 stack_start);
10283 }
10284
FinalizeTracing()10285 void EmbedderHeapTracer::FinalizeTracing() {
10286 if (isolate_) {
10287 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10288 if (isolate->heap()->incremental_marking()->IsMarking()) {
10289 isolate->heap()->FinalizeIncrementalMarkingAtomically(
10290 i::GarbageCollectionReason::kExternalFinalize);
10291 }
10292 }
10293 }
10294
IncreaseAllocatedSize(size_t bytes)10295 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
10296 if (isolate_) {
10297 i::LocalEmbedderHeapTracer* const tracer =
10298 reinterpret_cast<i::Isolate*>(isolate_)
10299 ->heap()
10300 ->local_embedder_heap_tracer();
10301 DCHECK_NOT_NULL(tracer);
10302 tracer->IncreaseAllocatedSize(bytes);
10303 }
10304 }
10305
DecreaseAllocatedSize(size_t bytes)10306 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
10307 if (isolate_) {
10308 i::LocalEmbedderHeapTracer* const tracer =
10309 reinterpret_cast<i::Isolate*>(isolate_)
10310 ->heap()
10311 ->local_embedder_heap_tracer();
10312 DCHECK_NOT_NULL(tracer);
10313 tracer->DecreaseAllocatedSize(bytes);
10314 }
10315 }
10316
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10317 void EmbedderHeapTracer::RegisterEmbedderReference(
10318 const BasicTracedReference<v8::Data>& ref) {
10319 if (ref.IsEmpty()) return;
10320
10321 i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
10322 heap->RegisterExternallyReferencedObject(
10323 reinterpret_cast<i::Address*>(ref.val_));
10324 }
10325
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10326 void EmbedderHeapTracer::IterateTracedGlobalHandles(
10327 TracedGlobalHandleVisitor* visitor) {
10328 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
10329 i::DisallowGarbageCollection no_gc;
10330 isolate->global_handles()->IterateTracedNodes(visitor);
10331 }
10332
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10333 bool EmbedderHeapTracer::IsRootForNonTracingGC(
10334 const v8::TracedReference<v8::Value>& handle) {
10335 return true;
10336 }
10337
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10338 void EmbedderHeapTracer::ResetHandleInNonTracingGC(
10339 const v8::TracedReference<v8::Value>& handle) {
10340 UNREACHABLE();
10341 }
10342
EmbedderStateScope(Isolate * isolate,Local<v8::Context> context,EmbedderStateTag tag)10343 EmbedderStateScope::EmbedderStateScope(Isolate* isolate,
10344 Local<v8::Context> context,
10345 EmbedderStateTag tag)
10346 : embedder_state_(new internal::EmbedderState(isolate, context, tag)) {}
10347
10348 // std::unique_ptr's destructor is not compatible with Forward declared
10349 // EmbedderState class.
10350 // Default destructor must be defined in implementation file.
10351 EmbedderStateScope::~EmbedderStateScope() = default;
10352
CheckValue() const10353 void TracedReferenceBase::CheckValue() const {
10354 #ifdef V8_HOST_ARCH_64_BIT
10355 if (!val_) return;
10356
10357 CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_));
10358 #endif // V8_HOST_ARCH_64_BIT
10359 }
10360
CFunction(const void * address,const CFunctionInfo * type_info)10361 CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
10362 : address_(address), type_info_(type_info) {
10363 CHECK_NOT_NULL(address_);
10364 CHECK_NOT_NULL(type_info_);
10365 }
10366
CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10367 CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info,
10368 unsigned int arg_count, const CTypeInfo* arg_info)
10369 : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) {
10370 if (arg_count_ > 0) {
10371 for (unsigned int i = 0; i < arg_count_ - 1; ++i) {
10372 DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType);
10373 }
10374 }
10375 }
10376
ArgumentInfo(unsigned int index) const10377 const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const {
10378 DCHECK_LT(index, ArgumentCount());
10379 return arg_info_[index];
10380 }
10381
ValidateIndex(size_t index) const10382 void FastApiTypedArrayBase::ValidateIndex(size_t index) const {
10383 DCHECK_LT(index, length_);
10384 }
10385
RegisterState()10386 RegisterState::RegisterState()
10387 : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
10388 RegisterState::~RegisterState() = default;
10389
RegisterState(const RegisterState & other)10390 RegisterState::RegisterState(const RegisterState& other) { *this = other; }
10391
operator =(const RegisterState & other)10392 RegisterState& RegisterState::operator=(const RegisterState& other) {
10393 if (&other != this) {
10394 pc = other.pc;
10395 sp = other.sp;
10396 fp = other.fp;
10397 lr = other.lr;
10398 if (other.callee_saved) {
10399 // Make a deep copy if {other.callee_saved} is non-null.
10400 callee_saved =
10401 std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
10402 } else {
10403 // Otherwise, set {callee_saved} to null to match {other}.
10404 callee_saved.reset();
10405 }
10406 }
10407 return *this;
10408 }
10409
10410 #if !V8_ENABLE_WEBASSEMBLY
10411 // If WebAssembly is disabled, we still need to provide an implementation of the
10412 // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all
10413 // methods are unreachable.
10414
10415 class WasmStreaming::WasmStreamingImpl {};
10416
WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10417 WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) {
10418 UNREACHABLE();
10419 }
10420
10421 WasmStreaming::~WasmStreaming() = default;
10422
OnBytesReceived(const uint8_t * bytes,size_t size)10423 void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) {
10424 UNREACHABLE();
10425 }
10426
Finish(bool can_use_compiled_module)10427 void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); }
10428
Abort(MaybeLocal<Value> exception)10429 void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); }
10430
SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10431 bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) {
10432 UNREACHABLE();
10433 }
10434
SetClient(std::shared_ptr<Client> client)10435 void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); }
10436
SetUrl(const char * url,size_t length)10437 void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); }
10438
10439 // static
Unpack(Isolate * isolate,Local<Value> value)10440 std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
10441 Local<Value> value) {
10442 FATAL("WebAssembly is disabled");
10443 }
10444 #endif // !V8_ENABLE_WEBASSEMBLY
10445
10446 namespace internal {
10447
10448 const size_t HandleScopeImplementer::kEnteredContextsOffset =
10449 offsetof(HandleScopeImplementer, entered_contexts_);
10450 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
10451 offsetof(HandleScopeImplementer, is_microtask_context_);
10452
FreeThreadResources()10453 void HandleScopeImplementer::FreeThreadResources() { Free(); }
10454
ArchiveThread(char * storage)10455 char* HandleScopeImplementer::ArchiveThread(char* storage) {
10456 HandleScopeData* current = isolate_->handle_scope_data();
10457 handle_scope_data_ = *current;
10458 MemCopy(storage, this, sizeof(*this));
10459
10460 ResetAfterArchive();
10461 current->Initialize();
10462
10463 return storage + ArchiveSpacePerThread();
10464 }
10465
ArchiveSpacePerThread()10466 int HandleScopeImplementer::ArchiveSpacePerThread() {
10467 return sizeof(HandleScopeImplementer);
10468 }
10469
RestoreThread(char * storage)10470 char* HandleScopeImplementer::RestoreThread(char* storage) {
10471 MemCopy(this, storage, sizeof(*this));
10472 *isolate_->handle_scope_data() = handle_scope_data_;
10473 return storage + ArchiveSpacePerThread();
10474 }
10475
IterateThis(RootVisitor * v)10476 void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10477 #ifdef DEBUG
10478 bool found_block_before_deferred = false;
10479 #endif
10480 // Iterate over all handles in the blocks except for the last.
10481 for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10482 Address* block = blocks()->at(i);
10483 // Cast possibly-unrelated pointers to plain Address before comparing them
10484 // to avoid undefined behavior.
10485 if (last_handle_before_deferred_block_ != nullptr &&
10486 (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
10487 reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
10488 (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
10489 reinterpret_cast<Address>(block))) {
10490 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10491 FullObjectSlot(last_handle_before_deferred_block_));
10492 DCHECK(!found_block_before_deferred);
10493 #ifdef DEBUG
10494 found_block_before_deferred = true;
10495 #endif
10496 } else {
10497 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
10498 FullObjectSlot(&block[kHandleBlockSize]));
10499 }
10500 }
10501
10502 DCHECK(last_handle_before_deferred_block_ == nullptr ||
10503 found_block_before_deferred);
10504
10505 // Iterate over live handles in the last block (if any).
10506 if (!blocks()->empty()) {
10507 v->VisitRootPointers(Root::kHandleScope, nullptr,
10508 FullObjectSlot(blocks()->back()),
10509 FullObjectSlot(handle_scope_data_.next));
10510 }
10511
10512 DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
10513 &entered_contexts_};
10514 for (unsigned i = 0; i < arraysize(context_lists); i++) {
10515 context_lists[i]->shrink_to_fit();
10516 if (context_lists[i]->empty()) continue;
10517 FullObjectSlot start(&context_lists[i]->front());
10518 v->VisitRootPointers(Root::kHandleScope, nullptr, start,
10519 start + static_cast<int>(context_lists[i]->size()));
10520 }
10521 // The shape of |entered_contexts_| and |is_microtask_context_| stacks must
10522 // be in sync.
10523 is_microtask_context_.shrink_to_fit();
10524 DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
10525 DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
10526 }
10527
Iterate(RootVisitor * v)10528 void HandleScopeImplementer::Iterate(RootVisitor* v) {
10529 HandleScopeData* current = isolate_->handle_scope_data();
10530 handle_scope_data_ = *current;
10531 IterateThis(v);
10532 }
10533
Iterate(RootVisitor * v,char * storage)10534 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10535 HandleScopeImplementer* scope_implementer =
10536 reinterpret_cast<HandleScopeImplementer*>(storage);
10537 scope_implementer->IterateThis(v);
10538 return storage + ArchiveSpacePerThread();
10539 }
10540
DetachPersistent(Address * prev_limit)10541 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
10542 Address* prev_limit) {
10543 std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
10544 DCHECK_NOT_NULL(prev_limit);
10545
10546 while (!blocks_.empty()) {
10547 Address* block_start = blocks_.back();
10548 Address* block_limit = &block_start[kHandleBlockSize];
10549 // We should not need to check for SealHandleScope here. Assert this.
10550 DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
10551 prev_limit == block_limit);
10552 if (prev_limit == block_limit) break;
10553 ph->blocks_.push_back(blocks_.back());
10554 #if DEBUG
10555 ph->ordered_blocks_.insert(blocks_.back());
10556 #endif
10557 blocks_.pop_back();
10558 }
10559
10560 // ph->blocks_ now contains the blocks installed on the
10561 // HandleScope stack since BeginDeferredScope was called, but in
10562 // reverse order.
10563
10564 // Switch first and last blocks, such that the last block is the one
10565 // that is potentially half full.
10566 DCHECK(!blocks_.empty() && !ph->blocks_.empty());
10567 std::swap(ph->blocks_.front(), ph->blocks_.back());
10568
10569 ph->block_next_ = isolate()->handle_scope_data()->next;
10570 Address* block_start = ph->blocks_.back();
10571 ph->block_limit_ = block_start + kHandleBlockSize;
10572
10573 DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10574 last_handle_before_deferred_block_ = nullptr;
10575 return ph;
10576 }
10577
BeginDeferredScope()10578 void HandleScopeImplementer::BeginDeferredScope() {
10579 DCHECK_NULL(last_handle_before_deferred_block_);
10580 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10581 }
10582
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10583 void InvokeAccessorGetterCallback(
10584 v8::Local<v8::Name> property,
10585 const v8::PropertyCallbackInfo<v8::Value>& info,
10586 v8::AccessorNameGetterCallback getter) {
10587 // Leaving JavaScript.
10588 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10589 RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback);
10590 Address getter_address = reinterpret_cast<Address>(getter);
10591 ExternalCallbackScope call_scope(isolate, getter_address);
10592 getter(property, info);
10593 }
10594
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10595 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10596 v8::FunctionCallback callback) {
10597 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10598 RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback);
10599 Address callback_address = reinterpret_cast<Address>(callback);
10600 ExternalCallbackScope call_scope(isolate, callback_address);
10601 callback(info);
10602 }
10603
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10604 void InvokeFinalizationRegistryCleanupFromTask(
10605 Handle<Context> context,
10606 Handle<JSFinalizationRegistry> finalization_registry,
10607 Handle<Object> callback) {
10608 Isolate* isolate = finalization_registry->native_context().GetIsolate();
10609 RCS_SCOPE(isolate,
10610 RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
10611 // Do not use ENTER_V8 because this is always called from a running
10612 // FinalizationRegistryCleanupTask within V8 and we should not log it as an
10613 // API call. This method is implemented here to avoid duplication of the
10614 // exception handling and microtask running logic in CallDepthScope.
10615 if (IsExecutionTerminatingCheck(isolate)) return;
10616 Local<v8::Context> api_context = Utils::ToLocal(context);
10617 CallDepthScope<true> call_depth_scope(isolate, api_context);
10618 VMState<OTHER> state(isolate);
10619 Handle<Object> argv[] = {callback};
10620 if (Execution::CallBuiltin(isolate,
10621 isolate->finalization_registry_cleanup_some(),
10622 finalization_registry, arraysize(argv), argv)
10623 .is_null()) {
10624 call_depth_scope.Escape();
10625 }
10626 }
10627
10628 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10629 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10630 int32_t ConvertDouble(double d) {
10631 return internal::DoubleToInt32(d);
10632 }
10633
10634 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10635 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10636 uint32_t ConvertDouble(double d) {
10637 return internal::DoubleToUint32(d);
10638 }
10639
10640 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10641 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10642 float ConvertDouble(double d) {
10643 return internal::DoubleToFloat32(d);
10644 }
10645
10646 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10647 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10648 double ConvertDouble(double d) {
10649 return d;
10650 }
10651
10652 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10653 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10654 int64_t ConvertDouble(double d) {
10655 return internal::DoubleToWebIDLInt64(d);
10656 }
10657
10658 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10659 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10660 uint64_t ConvertDouble(double d) {
10661 return internal::DoubleToWebIDLUint64(d);
10662 }
10663
10664 template <>
EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10665 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
10666 bool ConvertDouble(double d) {
10667 // Implements https://tc39.es/ecma262/#sec-toboolean.
10668 return !std::isnan(d) && d != 0;
10669 }
10670
10671 // Undefine macros for jumbo build.
10672 #undef SET_FIELD_WRAPPED
10673 #undef NEW_STRING
10674 #undef CALLBACK_SETTER
10675
10676 } // namespace internal
10677
10678 template <>
10679 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10680 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(),
10681 int32_t>(Local<Array> src, int32_t* dst,
10682 uint32_t max_length) {
10683 return CopyAndConvertArrayToCppBuffer<
10684 CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence)
10685 .GetId(),
10686 int32_t>(src, dst, max_length);
10687 }
10688
10689 template <>
10690 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10691 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(),
10692 uint32_t>(Local<Array> src, uint32_t* dst,
10693 uint32_t max_length) {
10694 return CopyAndConvertArrayToCppBuffer<
10695 CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence)
10696 .GetId(),
10697 uint32_t>(src, dst, max_length);
10698 }
10699
10700 template <>
10701 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10702 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(),
10703 float>(Local<Array> src, float* dst,
10704 uint32_t max_length) {
10705 return CopyAndConvertArrayToCppBuffer<
10706 CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence)
10707 .GetId(),
10708 float>(src, dst, max_length);
10709 }
10710
10711 template <>
10712 bool V8_EXPORT V8_WARN_UNUSED_RESULT
TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10713 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(),
10714 double>(Local<Array> src, double* dst,
10715 uint32_t max_length) {
10716 return CopyAndConvertArrayToCppBuffer<
10717 CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence)
10718 .GetId(),
10719 double>(src, dst, max_length);
10720 }
10721
10722 } // namespace v8
10723
10724 #undef TRACE_BS
10725 #include "src/api/api-macros-undef.h"
10726