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::__anon1d4f464a0111::SnapshotCreatorData435 explicit SnapshotCreatorData(Isolate* isolate) 436 : isolate_(isolate), 437 default_context_(), 438 contexts_(isolate), 439 created_(false) {} 440 castv8::__anon1d4f464a0111::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 5951 template<typename T> SetInternalFieldImpl(v8::Object * receiver,int index,v8::Local<T> value)5952 void SetInternalFieldImpl(v8::Object* receiver, int index, v8::Local<T> value) { 5953 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(receiver); 5954 const char* location = "v8::Object::SetInternalField()"; 5955 if (!InternalFieldOK(obj, index, location)) return; 5956 i::Handle<i::Object> val = Utils::OpenHandle(*value); 5957 i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val); 5958 } 5959 SetInternalField(int index,v8::Local<Value> value)5960 void v8::Object::SetInternalField(int index, v8::Local<Value> value) { 5961 SetInternalFieldImpl(this, index, value); 5962 } 5963 5964 /** 5965 * These are Node.js-specific extentions used to avoid breaking changes in 5966 * Node.js v20.x. 5967 */ SetInternalFieldForNodeCore(int index,v8::Local<Module> value)5968 void v8::Object::SetInternalFieldForNodeCore(int index, 5969 v8::Local<Module> value) { 5970 SetInternalFieldImpl(this, index, value); 5971 } 5972 SetInternalFieldForNodeCore(int index,v8::Local<UnboundScript> value)5973 void v8::Object::SetInternalFieldForNodeCore(int index, 5974 v8::Local<UnboundScript> value) { 5975 SetInternalFieldImpl(this, index, value); 5976 } 5977 SlowGetAlignedPointerFromInternalField(int index)5978 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) { 5979 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5980 const char* location = "v8::Object::GetAlignedPointerFromInternalField()"; 5981 if (!InternalFieldOK(obj, index, location)) return nullptr; 5982 void* result; 5983 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index) 5984 .ToAlignedPointer(obj->GetIsolate(), &result), 5985 location, "Unaligned pointer"); 5986 return result; 5987 } 5988 SetAlignedPointerInInternalField(int index,void * value)5989 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) { 5990 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5991 const char* location = "v8::Object::SetAlignedPointerInInternalField()"; 5992 if (!InternalFieldOK(obj, index, location)) return; 5993 5994 i::DisallowGarbageCollection no_gc; 5995 5996 // There's no need to invalidate slots as embedder fields are always 5997 // tagged. 5998 obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc, 5999 i::InvalidateRecordedSlots::kNo); 6000 6001 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index) 6002 .store_aligned_pointer(obj->GetIsolate(), value), 6003 location, "Unaligned pointer"); 6004 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index)); 6005 internal::WriteBarrier::MarkingFromInternalFields(i::JSObject::cast(*obj)); 6006 6007 #ifdef VERIFY_HEAP 6008 obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map()); 6009 #endif // VERIFY_HEAP 6010 } 6011 SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])6012 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[], 6013 void* values[]) { 6014 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 6015 6016 i::DisallowGarbageCollection no_gc; 6017 // There's no need to invalidate slots as embedder fields are always 6018 // tagged. 6019 obj->GetHeap()->NotifyObjectLayoutChange(*obj, no_gc, 6020 i::InvalidateRecordedSlots::kNo); 6021 6022 const char* location = "v8::Object::SetAlignedPointerInInternalFields()"; 6023 i::JSObject js_obj = i::JSObject::cast(*obj); 6024 int nof_embedder_fields = js_obj.GetEmbedderFieldCount(); 6025 for (int i = 0; i < argc; i++) { 6026 int index = indices[i]; 6027 if (!Utils::ApiCheck(index < nof_embedder_fields, location, 6028 "Internal field out of bounds")) { 6029 return; 6030 } 6031 void* value = values[i]; 6032 Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index) 6033 .store_aligned_pointer(obj->GetIsolate(), value), 6034 location, "Unaligned pointer"); 6035 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index)); 6036 } 6037 internal::WriteBarrier::MarkingFromInternalFields(js_obj); 6038 6039 #ifdef VERIFY_HEAP 6040 obj->GetHeap()->VerifyObjectLayoutChange(*obj, obj->map()); 6041 #endif // VERIFY_HEAP 6042 } 6043 6044 // --- E n v i r o n m e n t --- 6045 InitializePlatform(Platform * platform)6046 void v8::V8::InitializePlatform(Platform* platform) { 6047 i::V8::InitializePlatform(platform); 6048 } 6049 6050 #ifdef V8_SANDBOX InitializeSandbox()6051 bool v8::V8::InitializeSandbox() { return i::V8::InitializeSandbox(); } 6052 #endif 6053 DisposePlatform()6054 void v8::V8::DisposePlatform() { i::V8::DisposePlatform(); } 6055 Initialize(const int build_config)6056 bool v8::V8::Initialize(const int build_config) { 6057 const bool kEmbedderPointerCompression = 6058 (build_config & kPointerCompression) != 0; 6059 if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) { 6060 FATAL( 6061 "Embedder-vs-V8 build configuration mismatch. On embedder side " 6062 "pointer compression is %s while on V8 side it's %s.", 6063 kEmbedderPointerCompression ? "ENABLED" : "DISABLED", 6064 COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED"); 6065 } 6066 6067 const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32; 6068 if (kEmbedderSmiValueSize != internal::kSmiValueSize) { 6069 FATAL( 6070 "Embedder-vs-V8 build configuration mismatch. On embedder side " 6071 "Smi value size is %d while on V8 side it's %d.", 6072 kEmbedderSmiValueSize, internal::kSmiValueSize); 6073 } 6074 6075 const bool kEmbedderSandboxedExternalPointers = 6076 (build_config & kSandboxedExternalPointers) != 0; 6077 if (kEmbedderSandboxedExternalPointers != 6078 V8_SANDBOXED_EXTERNAL_POINTERS_BOOL) { 6079 FATAL( 6080 "Embedder-vs-V8 build configuration mismatch. On embedder side " 6081 "sandboxed external pointers is %s while on V8 side it's %s.", 6082 kEmbedderSandboxedExternalPointers ? "ENABLED" : "DISABLED", 6083 V8_SANDBOXED_EXTERNAL_POINTERS_BOOL ? "ENABLED" : "DISABLED"); 6084 } 6085 6086 const bool kEmbedderSandbox = (build_config & kSandbox) != 0; 6087 if (kEmbedderSandbox != V8_SANDBOX_BOOL) { 6088 FATAL( 6089 "Embedder-vs-V8 build configuration mismatch. On embedder side " 6090 "sandbox is %s while on V8 side it's %s.", 6091 kEmbedderSandbox ? "ENABLED" : "DISABLED", 6092 V8_SANDBOX_BOOL ? "ENABLED" : "DISABLED"); 6093 } 6094 6095 i::V8::Initialize(); 6096 return true; 6097 } 6098 6099 #if V8_OS_LINUX || V8_OS_DARWIN TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)6100 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info, 6101 void* context) { 6102 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED 6103 return i::trap_handler::TryHandleSignal(sig_code, info, context); 6104 #else 6105 return false; 6106 #endif 6107 } 6108 #endif 6109 6110 #if V8_OS_WIN TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)6111 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) { 6112 #if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED 6113 return i::trap_handler::TryHandleWasmTrap(exception); 6114 #else 6115 return false; 6116 #endif 6117 } 6118 #endif 6119 EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)6120 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) { 6121 #if V8_ENABLE_WEBASSEMBLY 6122 return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler); 6123 #else 6124 return false; 6125 #endif 6126 } 6127 6128 #if defined(V8_OS_WIN) SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)6129 void V8::SetUnhandledExceptionCallback( 6130 UnhandledExceptionCallback unhandled_exception_callback) { 6131 #if defined(V8_OS_WIN64) 6132 v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback( 6133 unhandled_exception_callback); 6134 #else 6135 // Not implemented, port needed. 6136 #endif // V8_OS_WIN64 6137 } 6138 #endif // V8_OS_WIN 6139 SetFatalMemoryErrorCallback(v8::OOMErrorCallback oom_error_callback)6140 void v8::V8::SetFatalMemoryErrorCallback( 6141 v8::OOMErrorCallback oom_error_callback) { 6142 g_oom_error_callback = oom_error_callback; 6143 } 6144 SetEntropySource(EntropySource entropy_source)6145 void v8::V8::SetEntropySource(EntropySource entropy_source) { 6146 base::RandomNumberGenerator::SetEntropySource(entropy_source); 6147 } 6148 SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)6149 void v8::V8::SetReturnAddressLocationResolver( 6150 ReturnAddressLocationResolver return_address_resolver) { 6151 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver); 6152 } 6153 Dispose()6154 bool v8::V8::Dispose() { 6155 i::V8::Dispose(); 6156 return true; 6157 } 6158 SharedMemoryStatistics()6159 SharedMemoryStatistics::SharedMemoryStatistics() 6160 : read_only_space_size_(0), 6161 read_only_space_used_size_(0), 6162 read_only_space_physical_size_(0) {} 6163 HeapStatistics()6164 HeapStatistics::HeapStatistics() 6165 : total_heap_size_(0), 6166 total_heap_size_executable_(0), 6167 total_physical_size_(0), 6168 total_available_size_(0), 6169 used_heap_size_(0), 6170 heap_size_limit_(0), 6171 malloced_memory_(0), 6172 external_memory_(0), 6173 peak_malloced_memory_(0), 6174 does_zap_garbage_(false), 6175 number_of_native_contexts_(0), 6176 number_of_detached_contexts_(0) {} 6177 HeapSpaceStatistics()6178 HeapSpaceStatistics::HeapSpaceStatistics() 6179 : space_name_(nullptr), 6180 space_size_(0), 6181 space_used_size_(0), 6182 space_available_size_(0), 6183 physical_space_size_(0) {} 6184 HeapObjectStatistics()6185 HeapObjectStatistics::HeapObjectStatistics() 6186 : object_type_(nullptr), 6187 object_sub_type_(nullptr), 6188 object_count_(0), 6189 object_size_(0) {} 6190 HeapCodeStatistics()6191 HeapCodeStatistics::HeapCodeStatistics() 6192 : code_and_metadata_size_(0), 6193 bytecode_and_metadata_size_(0), 6194 external_script_source_size_(0), 6195 cpu_profiler_metadata_size_(0) {} 6196 InitializeICU(const char * icu_data_file)6197 bool v8::V8::InitializeICU(const char* icu_data_file) { 6198 return i::InitializeICU(icu_data_file); 6199 } 6200 InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)6201 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path, 6202 const char* icu_data_file) { 6203 return i::InitializeICUDefaultLocation(exec_path, icu_data_file); 6204 } 6205 InitializeExternalStartupData(const char * directory_path)6206 void v8::V8::InitializeExternalStartupData(const char* directory_path) { 6207 i::InitializeExternalStartupData(directory_path); 6208 } 6209 6210 // static InitializeExternalStartupDataFromFile(const char * snapshot_blob)6211 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) { 6212 i::InitializeExternalStartupDataFromFile(snapshot_blob); 6213 } 6214 GetVersion()6215 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); } 6216 6217 #ifdef V8_SANDBOX GetSandboxAddressSpace()6218 VirtualAddressSpace* v8::V8::GetSandboxAddressSpace() { 6219 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(), 6220 "v8::V8::GetSandboxAddressSpace", 6221 "The sandbox must be initialized first."); 6222 return i::GetProcessWideSandbox()->address_space(); 6223 } 6224 GetVirtualMemoryCagePageAllocator()6225 PageAllocator* v8::V8::GetVirtualMemoryCagePageAllocator() { 6226 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(), 6227 "v8::V8::GetVirtualMemoryCagePageAllocator", 6228 "The sandbox must be initialized first."); 6229 return i::GetProcessWideSandbox()->page_allocator(); 6230 } 6231 GetSandboxSizeInBytes()6232 size_t v8::V8::GetSandboxSizeInBytes() { 6233 if (!i::GetProcessWideSandbox()->is_initialized()) { 6234 return 0; 6235 } else { 6236 return i::GetProcessWideSandbox()->size(); 6237 } 6238 } 6239 IsSandboxConfiguredSecurely()6240 bool v8::V8::IsSandboxConfiguredSecurely() { 6241 Utils::ApiCheck(i::GetProcessWideSandbox()->is_initialized(), 6242 "v8::V8::IsSandoxConfiguredSecurely", 6243 "The sandbox must be initialized first."); 6244 // TODO(saelo) For now, we only treat a partially reserved sandbox as 6245 // insecure. Once we use sandboxed pointers, which assume that the sandbox 6246 // has a fixed size, we'll also treat sandboxes with a smaller size as 6247 // insecure because these pointers can then access memory outside of them. 6248 return !i::GetProcessWideSandbox()->is_partially_reserved(); 6249 } 6250 #endif 6251 GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)6252 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) { 6253 i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics); 6254 } 6255 6256 template <typename ObjectType> 6257 struct InvokeBootstrapper; 6258 6259 template <> 6260 struct InvokeBootstrapper<i::Context> { Invokev8::InvokeBootstrapper6261 i::Handle<i::Context> Invoke( 6262 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy, 6263 v8::Local<v8::ObjectTemplate> global_proxy_template, 6264 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, 6265 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, 6266 v8::MicrotaskQueue* microtask_queue) { 6267 return isolate->bootstrapper()->CreateEnvironment( 6268 maybe_global_proxy, global_proxy_template, extensions, 6269 context_snapshot_index, embedder_fields_deserializer, microtask_queue); 6270 } 6271 }; 6272 6273 template <> 6274 struct InvokeBootstrapper<i::JSGlobalProxy> { Invokev8::InvokeBootstrapper6275 i::Handle<i::JSGlobalProxy> Invoke( 6276 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy, 6277 v8::Local<v8::ObjectTemplate> global_proxy_template, 6278 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index, 6279 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, 6280 v8::MicrotaskQueue* microtask_queue) { 6281 USE(extensions); 6282 USE(context_snapshot_index); 6283 return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy, 6284 global_proxy_template); 6285 } 6286 }; 6287 6288 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)6289 static i::Handle<ObjectType> CreateEnvironment( 6290 i::Isolate* isolate, v8::ExtensionConfiguration* extensions, 6291 v8::MaybeLocal<ObjectTemplate> maybe_global_template, 6292 v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index, 6293 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, 6294 v8::MicrotaskQueue* microtask_queue) { 6295 i::Handle<ObjectType> result; 6296 6297 { 6298 ENTER_V8_FOR_NEW_CONTEXT(isolate); 6299 v8::Local<ObjectTemplate> proxy_template; 6300 i::Handle<i::FunctionTemplateInfo> proxy_constructor; 6301 i::Handle<i::FunctionTemplateInfo> global_constructor; 6302 i::Handle<i::HeapObject> named_interceptor( 6303 isolate->factory()->undefined_value()); 6304 i::Handle<i::HeapObject> indexed_interceptor( 6305 isolate->factory()->undefined_value()); 6306 6307 if (!maybe_global_template.IsEmpty()) { 6308 v8::Local<v8::ObjectTemplate> global_template = 6309 maybe_global_template.ToLocalChecked(); 6310 // Make sure that the global_template has a constructor. 6311 global_constructor = EnsureConstructor(isolate, *global_template); 6312 6313 // Create a fresh template for the global proxy object. 6314 proxy_template = 6315 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate)); 6316 proxy_constructor = EnsureConstructor(isolate, *proxy_template); 6317 6318 // Set the global template to be the prototype template of 6319 // global proxy template. 6320 i::FunctionTemplateInfo::SetPrototypeTemplate( 6321 isolate, proxy_constructor, Utils::OpenHandle(*global_template)); 6322 6323 proxy_template->SetInternalFieldCount( 6324 global_template->InternalFieldCount()); 6325 6326 // Migrate security handlers from global_template to 6327 // proxy_template. Temporarily removing access check 6328 // information from the global template. 6329 if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) { 6330 i::FunctionTemplateInfo::SetAccessCheckInfo( 6331 isolate, proxy_constructor, 6332 i::handle(global_constructor->GetAccessCheckInfo(), isolate)); 6333 proxy_constructor->set_needs_access_check( 6334 global_constructor->needs_access_check()); 6335 global_constructor->set_needs_access_check(false); 6336 i::FunctionTemplateInfo::SetAccessCheckInfo( 6337 isolate, global_constructor, 6338 i::ReadOnlyRoots(isolate).undefined_value_handle()); 6339 } 6340 6341 // Same for other interceptors. If the global constructor has 6342 // interceptors, we need to replace them temporarily with noop 6343 // interceptors, so the map is correctly marked as having interceptors, 6344 // but we don't invoke any. 6345 if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) { 6346 named_interceptor = 6347 handle(global_constructor->GetNamedPropertyHandler(), isolate); 6348 i::FunctionTemplateInfo::SetNamedPropertyHandler( 6349 isolate, global_constructor, 6350 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle()); 6351 } 6352 if (!global_constructor->GetIndexedPropertyHandler().IsUndefined( 6353 isolate)) { 6354 indexed_interceptor = 6355 handle(global_constructor->GetIndexedPropertyHandler(), isolate); 6356 i::FunctionTemplateInfo::SetIndexedPropertyHandler( 6357 isolate, global_constructor, 6358 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle()); 6359 } 6360 } 6361 6362 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy; 6363 if (!maybe_global_proxy.IsEmpty()) { 6364 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast( 6365 Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked())); 6366 } 6367 // Create the environment. 6368 InvokeBootstrapper<ObjectType> invoke; 6369 result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions, 6370 context_snapshot_index, embedder_fields_deserializer, 6371 microtask_queue); 6372 6373 // Restore the access check info and interceptors on the global template. 6374 if (!maybe_global_template.IsEmpty()) { 6375 DCHECK(!global_constructor.is_null()); 6376 DCHECK(!proxy_constructor.is_null()); 6377 i::FunctionTemplateInfo::SetAccessCheckInfo( 6378 isolate, global_constructor, 6379 i::handle(proxy_constructor->GetAccessCheckInfo(), isolate)); 6380 global_constructor->set_needs_access_check( 6381 proxy_constructor->needs_access_check()); 6382 i::FunctionTemplateInfo::SetNamedPropertyHandler( 6383 isolate, global_constructor, named_interceptor); 6384 i::FunctionTemplateInfo::SetIndexedPropertyHandler( 6385 isolate, global_constructor, indexed_interceptor); 6386 } 6387 } 6388 // Leave V8. 6389 6390 return result; 6391 } 6392 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)6393 Local<Context> NewContext( 6394 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions, 6395 v8::MaybeLocal<ObjectTemplate> global_template, 6396 v8::MaybeLocal<Value> global_object, size_t context_snapshot_index, 6397 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, 6398 v8::MicrotaskQueue* microtask_queue) { 6399 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); 6400 // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't 6401 // fail. 6402 // Sanity-check that the isolate is initialized and usable. 6403 CHECK(isolate->builtins()->code(i::Builtin::kIllegal).IsCodeT()); 6404 6405 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext"); 6406 API_RCS_SCOPE(isolate, Context, New); 6407 i::HandleScope scope(isolate); 6408 ExtensionConfiguration no_extensions; 6409 if (extensions == nullptr) extensions = &no_extensions; 6410 i::Handle<i::Context> env = CreateEnvironment<i::Context>( 6411 isolate, extensions, global_template, global_object, 6412 context_snapshot_index, embedder_fields_deserializer, microtask_queue); 6413 if (env.is_null()) { 6414 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 6415 return Local<Context>(); 6416 } 6417 return Utils::ToLocal(scope.CloseAndEscape(env)); 6418 } 6419 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)6420 Local<Context> v8::Context::New( 6421 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions, 6422 v8::MaybeLocal<ObjectTemplate> global_template, 6423 v8::MaybeLocal<Value> global_object, 6424 DeserializeInternalFieldsCallback internal_fields_deserializer, 6425 v8::MicrotaskQueue* microtask_queue) { 6426 return NewContext(external_isolate, extensions, global_template, 6427 global_object, 0, internal_fields_deserializer, 6428 microtask_queue); 6429 } 6430 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)6431 MaybeLocal<Context> v8::Context::FromSnapshot( 6432 v8::Isolate* external_isolate, size_t context_snapshot_index, 6433 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer, 6434 v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object, 6435 v8::MicrotaskQueue* microtask_queue) { 6436 size_t index_including_default_context = context_snapshot_index + 1; 6437 if (!i::Snapshot::HasContextSnapshot( 6438 reinterpret_cast<i::Isolate*>(external_isolate), 6439 index_including_default_context)) { 6440 return MaybeLocal<Context>(); 6441 } 6442 return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(), 6443 global_object, index_including_default_context, 6444 embedder_fields_deserializer, microtask_queue); 6445 } 6446 NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6447 MaybeLocal<Object> v8::Context::NewRemoteContext( 6448 v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template, 6449 v8::MaybeLocal<v8::Value> global_object) { 6450 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); 6451 API_RCS_SCOPE(isolate, Context, NewRemoteContext); 6452 i::HandleScope scope(isolate); 6453 i::Handle<i::FunctionTemplateInfo> global_constructor = 6454 EnsureConstructor(isolate, *global_template); 6455 Utils::ApiCheck(global_constructor->needs_access_check(), 6456 "v8::Context::NewRemoteContext", 6457 "Global template needs to have access checks enabled."); 6458 i::Handle<i::AccessCheckInfo> access_check_info = i::handle( 6459 i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()), 6460 isolate); 6461 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(), 6462 "v8::Context::NewRemoteContext", 6463 "Global template needs to have access check handlers."); 6464 i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>( 6465 isolate, nullptr, global_template, global_object, 0, 6466 DeserializeInternalFieldsCallback(), nullptr); 6467 if (global_proxy.is_null()) { 6468 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); 6469 return MaybeLocal<Object>(); 6470 } 6471 return Utils::ToLocal(scope.CloseAndEscape(global_proxy)); 6472 } 6473 SetSecurityToken(Local<Value> token)6474 void v8::Context::SetSecurityToken(Local<Value> token) { 6475 i::Handle<i::Context> env = Utils::OpenHandle(this); 6476 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token); 6477 env->set_security_token(*token_handle); 6478 } 6479 UseDefaultSecurityToken()6480 void v8::Context::UseDefaultSecurityToken() { 6481 i::Handle<i::Context> env = Utils::OpenHandle(this); 6482 env->set_security_token(env->global_object()); 6483 } 6484 GetSecurityToken()6485 Local<Value> v8::Context::GetSecurityToken() { 6486 i::Handle<i::Context> env = Utils::OpenHandle(this); 6487 i::Isolate* isolate = env->GetIsolate(); 6488 i::Object security_token = env->security_token(); 6489 i::Handle<i::Object> token_handle(security_token, isolate); 6490 return Utils::ToLocal(token_handle); 6491 } 6492 GetIsolate()6493 v8::Isolate* Context::GetIsolate() { 6494 i::Handle<i::Context> env = Utils::OpenHandle(this); 6495 return reinterpret_cast<Isolate*>(env->GetIsolate()); 6496 } 6497 GetMicrotaskQueue()6498 v8::MicrotaskQueue* Context::GetMicrotaskQueue() { 6499 i::Handle<i::Context> env = Utils::OpenHandle(this); 6500 Utils::ApiCheck(env->IsNativeContext(), "v8::Context::GetMicrotaskQueue", 6501 "Must be calld on a native context"); 6502 return i::Handle<i::NativeContext>::cast(env)->microtask_queue(); 6503 } 6504 Global()6505 v8::Local<v8::Object> Context::Global() { 6506 i::Handle<i::Context> context = Utils::OpenHandle(this); 6507 i::Isolate* isolate = context->GetIsolate(); 6508 i::Handle<i::Object> global(context->global_proxy(), isolate); 6509 // TODO(chromium:324812): This should always return the global proxy 6510 // but can't presently as calls to GetProtoype will return the wrong result. 6511 if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom( 6512 context->global_object())) { 6513 global = i::Handle<i::Object>(context->global_object(), isolate); 6514 } 6515 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global)); 6516 } 6517 DetachGlobal()6518 void Context::DetachGlobal() { 6519 i::Handle<i::Context> context = Utils::OpenHandle(this); 6520 i::Isolate* isolate = context->GetIsolate(); 6521 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 6522 isolate->DetachGlobal(context); 6523 } 6524 GetExtrasBindingObject()6525 Local<v8::Object> Context::GetExtrasBindingObject() { 6526 i::Handle<i::Context> context = Utils::OpenHandle(this); 6527 i::Isolate* isolate = context->GetIsolate(); 6528 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate); 6529 return Utils::ToLocal(binding); 6530 } 6531 AllowCodeGenerationFromStrings(bool allow)6532 void Context::AllowCodeGenerationFromStrings(bool allow) { 6533 i::Handle<i::Context> context = Utils::OpenHandle(this); 6534 i::Isolate* isolate = context->GetIsolate(); 6535 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 6536 context->set_allow_code_gen_from_strings( 6537 allow ? i::ReadOnlyRoots(isolate).true_value() 6538 : i::ReadOnlyRoots(isolate).false_value()); 6539 } 6540 IsCodeGenerationFromStringsAllowed() const6541 bool Context::IsCodeGenerationFromStringsAllowed() const { 6542 i::Context context = *Utils::OpenHandle(this); 6543 return !context.allow_code_gen_from_strings().IsFalse(context.GetIsolate()); 6544 } 6545 SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6546 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) { 6547 i::Handle<i::Context> context = Utils::OpenHandle(this); 6548 i::Handle<i::String> error_handle = Utils::OpenHandle(*error); 6549 context->set_error_message_for_code_gen_from_strings(*error_handle); 6550 } 6551 SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6552 void Context::SetAbortScriptExecution( 6553 Context::AbortScriptExecutionCallback callback) { 6554 i::Handle<i::Context> context = Utils::OpenHandle(this); 6555 i::Isolate* isolate = context->GetIsolate(); 6556 if (callback == nullptr) { 6557 context->set_script_execution_callback( 6558 i::ReadOnlyRoots(isolate).undefined_value()); 6559 } else { 6560 SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback, 6561 callback); 6562 } 6563 } 6564 GetContinuationPreservedEmbedderData() const6565 Local<Value> Context::GetContinuationPreservedEmbedderData() const { 6566 i::Handle<i::Context> context = Utils::OpenHandle(this); 6567 i::Isolate* isolate = context->GetIsolate(); 6568 i::Handle<i::Object> data( 6569 context->native_context().continuation_preserved_embedder_data(), 6570 isolate); 6571 return ToApiHandle<Object>(data); 6572 } 6573 SetContinuationPreservedEmbedderData(Local<Value> data)6574 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) { 6575 i::Handle<i::Context> context = Utils::OpenHandle(this); 6576 i::Isolate* isolate = context->GetIsolate(); 6577 if (data.IsEmpty()) 6578 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 6579 context->native_context().set_continuation_preserved_embedder_data( 6580 *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data))); 6581 } 6582 SetPromiseHooks(Local<Function> init_hook,Local<Function> before_hook,Local<Function> after_hook,Local<Function> resolve_hook)6583 void v8::Context::SetPromiseHooks(Local<Function> init_hook, 6584 Local<Function> before_hook, 6585 Local<Function> after_hook, 6586 Local<Function> resolve_hook) { 6587 #ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS 6588 i::Handle<i::Context> context = Utils::OpenHandle(this); 6589 i::Isolate* isolate = context->GetIsolate(); 6590 6591 i::Handle<i::Object> init = isolate->factory()->undefined_value(); 6592 i::Handle<i::Object> before = isolate->factory()->undefined_value(); 6593 i::Handle<i::Object> after = isolate->factory()->undefined_value(); 6594 i::Handle<i::Object> resolve = isolate->factory()->undefined_value(); 6595 6596 bool has_hook = false; 6597 6598 if (!init_hook.IsEmpty()) { 6599 init = Utils::OpenHandle(*init_hook); 6600 has_hook = true; 6601 } 6602 if (!before_hook.IsEmpty()) { 6603 before = Utils::OpenHandle(*before_hook); 6604 has_hook = true; 6605 } 6606 if (!after_hook.IsEmpty()) { 6607 after = Utils::OpenHandle(*after_hook); 6608 has_hook = true; 6609 } 6610 if (!resolve_hook.IsEmpty()) { 6611 resolve = Utils::OpenHandle(*resolve_hook); 6612 has_hook = true; 6613 } 6614 6615 isolate->SetHasContextPromiseHooks(has_hook); 6616 6617 context->native_context().set_promise_hook_init_function(*init); 6618 context->native_context().set_promise_hook_before_function(*before); 6619 context->native_context().set_promise_hook_after_function(*after); 6620 context->native_context().set_promise_hook_resolve_function(*resolve); 6621 #else // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS 6622 Utils::ApiCheck(false, "v8::Context::SetPromiseHook", 6623 "V8 was compiled without JavaScript Promise hooks"); 6624 #endif // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS 6625 } 6626 GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6627 MaybeLocal<Context> metrics::Recorder::GetContext( 6628 Isolate* isolate, metrics::Recorder::ContextId id) { 6629 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6630 return i_isolate->GetContextFromRecorderContextId(id); 6631 } 6632 GetContextId(Local<Context> context)6633 metrics::Recorder::ContextId metrics::Recorder::GetContextId( 6634 Local<Context> context) { 6635 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 6636 i::Isolate* isolate = i_context->GetIsolate(); 6637 return isolate->GetOrRegisterRecorderContextId( 6638 handle(i_context->native_context(), isolate)); 6639 } 6640 Get(v8::Isolate * isolate)6641 metrics::LongTaskStats metrics::LongTaskStats::Get(v8::Isolate* isolate) { 6642 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6643 return *i_isolate->GetCurrentLongTaskStats(); 6644 } 6645 6646 namespace { GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6647 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate, 6648 i::FixedArray list, size_t index) { 6649 if (index < static_cast<size_t>(list.length())) { 6650 int int_index = static_cast<int>(index); 6651 i::Object object = list.get(int_index); 6652 if (!object.IsTheHole(isolate)) { 6653 list.set_the_hole(isolate, int_index); 6654 // Shrink the list so that the last element is not the hole (unless it's 6655 // the first element, because we don't want to end up with a non-canonical 6656 // empty FixedArray). 6657 int last = list.length() - 1; 6658 while (last >= 0 && list.is_the_hole(isolate, last)) last--; 6659 if (last != -1) list.Shrink(isolate, last + 1); 6660 return i::Handle<i::Object>(object, isolate).location(); 6661 } 6662 } 6663 return nullptr; 6664 } 6665 } // anonymous namespace 6666 GetDataFromSnapshotOnce(size_t index)6667 i::Address* Context::GetDataFromSnapshotOnce(size_t index) { 6668 auto context = Utils::OpenHandle(this); 6669 i::Isolate* i_isolate = context->GetIsolate(); 6670 i::FixedArray list = context->serialized_objects(); 6671 return GetSerializedDataFromFixedArray(i_isolate, list, index); 6672 } 6673 NewInstance(Local<Context> context)6674 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) { 6675 PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object); 6676 auto self = Utils::OpenHandle(this); 6677 Local<Object> result; 6678 has_pending_exception = !ToLocal<Object>( 6679 i::ApiNatives::InstantiateObject(isolate, self), &result); 6680 RETURN_ON_FAILED_EXECUTION(Object); 6681 RETURN_ESCAPED(result); 6682 } 6683 CheckCast(Data * that)6684 void v8::ObjectTemplate::CheckCast(Data* that) { 6685 i::Handle<i::Object> obj = Utils::OpenHandle(that); 6686 Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast", 6687 "Value is not an ObjectTemplate"); 6688 } 6689 CheckCast(Data * that)6690 void v8::FunctionTemplate::CheckCast(Data* that) { 6691 i::Handle<i::Object> obj = Utils::OpenHandle(that); 6692 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast", 6693 "Value is not a FunctionTemplate"); 6694 } 6695 CheckCast(Data * that)6696 void v8::Signature::CheckCast(Data* that) { 6697 i::Handle<i::Object> obj = Utils::OpenHandle(that); 6698 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast", 6699 "Value is not a Signature"); 6700 } 6701 CheckCast(Data * that)6702 void v8::AccessorSignature::CheckCast(Data* that) { 6703 i::Handle<i::Object> obj = Utils::OpenHandle(that); 6704 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast", 6705 "Value is not an AccessorSignature"); 6706 } 6707 GetFunction(Local<Context> context)6708 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) { 6709 PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function); 6710 auto self = Utils::OpenHandle(this); 6711 Local<Function> result; 6712 has_pending_exception = 6713 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result); 6714 RETURN_ON_FAILED_EXECUTION(Function); 6715 RETURN_ESCAPED(result); 6716 } 6717 NewRemoteInstance()6718 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() { 6719 auto self = Utils::OpenHandle(this); 6720 i::Isolate* isolate = self->GetIsolate(); 6721 API_RCS_SCOPE(isolate, FunctionTemplate, NewRemoteInstance); 6722 i::HandleScope scope(isolate); 6723 i::Handle<i::FunctionTemplateInfo> constructor = 6724 EnsureConstructor(isolate, *InstanceTemplate()); 6725 Utils::ApiCheck(constructor->needs_access_check(), 6726 "v8::FunctionTemplate::NewRemoteInstance", 6727 "InstanceTemplate needs to have access checks enabled."); 6728 i::Handle<i::AccessCheckInfo> access_check_info = i::handle( 6729 i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate); 6730 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(), 6731 "v8::FunctionTemplate::NewRemoteInstance", 6732 "InstanceTemplate needs to have access check handlers."); 6733 i::Handle<i::JSObject> object; 6734 if (!i::ApiNatives::InstantiateRemoteObject( 6735 Utils::OpenHandle(*InstanceTemplate())) 6736 .ToHandle(&object)) { 6737 if (isolate->has_pending_exception()) { 6738 isolate->OptionalRescheduleException(true); 6739 } 6740 return MaybeLocal<Object>(); 6741 } 6742 return Utils::ToLocal(scope.CloseAndEscape(object)); 6743 } 6744 HasInstance(v8::Local<v8::Value> value)6745 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) { 6746 auto self = Utils::OpenHandle(this); 6747 auto obj = Utils::OpenHandle(*value); 6748 if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) { 6749 return true; 6750 } 6751 if (obj->IsJSGlobalProxy()) { 6752 // If it's a global proxy, then test with the global object. Note that the 6753 // inner global object may not necessarily be a JSGlobalObject. 6754 i::PrototypeIterator iter(self->GetIsolate(), 6755 i::JSObject::cast(*obj).map()); 6756 // The global proxy should always have a prototype, as it is a bug to call 6757 // this on a detached JSGlobalProxy. 6758 DCHECK(!iter.IsAtEnd()); 6759 return self->IsTemplateFor(iter.GetCurrent<i::JSObject>()); 6760 } 6761 return false; 6762 } 6763 IsLeafTemplateForApiObject(v8::Local<v8::Value> value) const6764 bool FunctionTemplate::IsLeafTemplateForApiObject( 6765 v8::Local<v8::Value> value) const { 6766 i::DisallowGarbageCollection no_gc; 6767 6768 i::Object object = *Utils::OpenHandle(*value); 6769 6770 auto self = Utils::OpenHandle(this); 6771 return self->IsLeafTemplateForApiObject(object); 6772 } 6773 New(Isolate * isolate,void * value)6774 Local<External> v8::External::New(Isolate* isolate, void* value) { 6775 STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); 6776 // Nullptr is not allowed here because serialization/deserialization of 6777 // nullptr external api references is not possible as nullptr is used as an 6778 // external_references table terminator, see v8::SnapshotCreator() 6779 // constructors. 6780 DCHECK_NOT_NULL(value); 6781 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6782 API_RCS_SCOPE(i_isolate, External, New); 6783 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 6784 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value); 6785 return Utils::ExternalToLocal(external); 6786 } 6787 Value() const6788 void* External::Value() const { 6789 auto self = Utils::OpenHandle(this); 6790 return i::JSExternalObject::cast(*self).value(); 6791 } 6792 6793 // anonymous namespace for string creation helper functions 6794 namespace { 6795 StringLength(const char * string)6796 inline int StringLength(const char* string) { 6797 size_t len = strlen(string); 6798 CHECK_GE(i::kMaxInt, len); 6799 return static_cast<int>(len); 6800 } 6801 StringLength(const uint8_t * string)6802 inline int StringLength(const uint8_t* string) { 6803 return StringLength(reinterpret_cast<const char*>(string)); 6804 } 6805 StringLength(const uint16_t * string)6806 inline int StringLength(const uint16_t* string) { 6807 size_t length = 0; 6808 while (string[length] != '\0') length++; 6809 CHECK_GE(i::kMaxInt, length); 6810 return static_cast<int>(length); 6811 } 6812 6813 V8_WARN_UNUSED_RESULT NewString(i::Factory * factory,NewStringType type,base::Vector<const char> string)6814 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, 6815 NewStringType type, 6816 base::Vector<const char> string) { 6817 if (type == NewStringType::kInternalized) { 6818 return factory->InternalizeUtf8String(string); 6819 } 6820 return factory->NewStringFromUtf8(string); 6821 } 6822 6823 V8_WARN_UNUSED_RESULT NewString(i::Factory * factory,NewStringType type,base::Vector<const uint8_t> string)6824 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, 6825 NewStringType type, 6826 base::Vector<const uint8_t> string) { 6827 if (type == NewStringType::kInternalized) { 6828 return factory->InternalizeString(string); 6829 } 6830 return factory->NewStringFromOneByte(string); 6831 } 6832 6833 V8_WARN_UNUSED_RESULT NewString(i::Factory * factory,NewStringType type,base::Vector<const uint16_t> string)6834 inline i::MaybeHandle<i::String> NewString( 6835 i::Factory* factory, NewStringType type, 6836 base::Vector<const uint16_t> string) { 6837 if (type == NewStringType::kInternalized) { 6838 return factory->InternalizeString(string); 6839 } 6840 return factory->NewStringFromTwoByte(string); 6841 } 6842 6843 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); 6844 6845 } // anonymous namespace 6846 6847 // TODO(dcarney): throw a context free exception. 6848 #define NEW_STRING(isolate, class_name, function_name, Char, data, type, \ 6849 length) \ 6850 MaybeLocal<String> result; \ 6851 if (length == 0) { \ 6852 result = String::Empty(isolate); \ 6853 } else if (length > i::String::kMaxLength) { \ 6854 result = MaybeLocal<String>(); \ 6855 } else { \ 6856 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \ 6857 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); \ 6858 API_RCS_SCOPE(i_isolate, class_name, function_name); \ 6859 if (length < 0) length = StringLength(data); \ 6860 i::Handle<i::String> handle_result = \ 6861 NewString(i_isolate->factory(), type, \ 6862 base::Vector<const Char>(data, length)) \ 6863 .ToHandleChecked(); \ 6864 result = Utils::ToLocal(handle_result); \ 6865 } 6866 NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6867 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal, 6868 NewStringType type, int length) { 6869 DCHECK_LE(length, i::String::kMaxLength); 6870 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); 6871 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 6872 API_RCS_SCOPE(i_isolate, String, NewFromUtf8Literal); 6873 i::Handle<i::String> handle_result = 6874 NewString(i_isolate->factory(), type, 6875 base::Vector<const char>(literal, length)) 6876 .ToHandleChecked(); 6877 return Utils::ToLocal(handle_result); 6878 } 6879 NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6880 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data, 6881 NewStringType type, int length) { 6882 NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length); 6883 return result; 6884 } 6885 NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6886 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data, 6887 NewStringType type, int length) { 6888 NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length); 6889 return result; 6890 } 6891 NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6892 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate, 6893 const uint16_t* data, 6894 NewStringType type, int length) { 6895 NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length); 6896 return result; 6897 } 6898 Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6899 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left, 6900 Local<String> right) { 6901 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 6902 i::Handle<i::String> left_string = Utils::OpenHandle(*left); 6903 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 6904 API_RCS_SCOPE(isolate, String, Concat); 6905 i::Handle<i::String> right_string = Utils::OpenHandle(*right); 6906 // If we are steering towards a range error, do not wait for the error to be 6907 // thrown, and return the null handle instead. 6908 if (left_string->length() + right_string->length() > i::String::kMaxLength) { 6909 return Local<String>(); 6910 } 6911 i::Handle<i::String> result = isolate->factory() 6912 ->NewConsString(left_string, right_string) 6913 .ToHandleChecked(); 6914 return Utils::ToLocal(result); 6915 } 6916 NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6917 MaybeLocal<String> v8::String::NewExternalTwoByte( 6918 Isolate* isolate, v8::String::ExternalStringResource* resource) { 6919 CHECK(resource && resource->data()); 6920 // TODO(dcarney): throw a context free exception. 6921 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 6922 return MaybeLocal<String>(); 6923 } 6924 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6925 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 6926 API_RCS_SCOPE(i_isolate, String, NewExternalTwoByte); 6927 if (resource->length() > 0) { 6928 i::Handle<i::String> string = i_isolate->factory() 6929 ->NewExternalStringFromTwoByte(resource) 6930 .ToHandleChecked(); 6931 return Utils::ToLocal(string); 6932 } else { 6933 // The resource isn't going to be used, free it immediately. 6934 resource->Dispose(); 6935 return Utils::ToLocal(i_isolate->factory()->empty_string()); 6936 } 6937 } 6938 NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6939 MaybeLocal<String> v8::String::NewExternalOneByte( 6940 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { 6941 CHECK_NOT_NULL(resource); 6942 // TODO(dcarney): throw a context free exception. 6943 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 6944 return MaybeLocal<String>(); 6945 } 6946 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6947 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 6948 API_RCS_SCOPE(i_isolate, String, NewExternalOneByte); 6949 if (resource->length() == 0) { 6950 // The resource isn't going to be used, free it immediately. 6951 resource->Dispose(); 6952 return Utils::ToLocal(i_isolate->factory()->empty_string()); 6953 } 6954 CHECK_NOT_NULL(resource->data()); 6955 i::Handle<i::String> string = i_isolate->factory() 6956 ->NewExternalStringFromOneByte(resource) 6957 .ToHandleChecked(); 6958 return Utils::ToLocal(string); 6959 } 6960 MakeExternal(v8::String::ExternalStringResource * resource)6961 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { 6962 i::DisallowGarbageCollection no_gc; 6963 6964 i::String obj = *Utils::OpenHandle(this); 6965 6966 if (obj.IsThinString()) { 6967 obj = i::ThinString::cast(obj).actual(); 6968 } 6969 6970 if (!obj.SupportsExternalization()) { 6971 return false; 6972 } 6973 6974 // It is safe to call GetIsolateFromWritableHeapObject because 6975 // SupportsExternalization already checked that the object is writable. 6976 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj); 6977 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 6978 6979 CHECK(resource && resource->data()); 6980 6981 bool result = obj.MakeExternal(resource); 6982 DCHECK(result); 6983 DCHECK(obj.IsExternalString()); 6984 return result; 6985 } 6986 MakeExternal(v8::String::ExternalOneByteStringResource * resource)6987 bool v8::String::MakeExternal( 6988 v8::String::ExternalOneByteStringResource* resource) { 6989 i::DisallowGarbageCollection no_gc; 6990 6991 i::String obj = *Utils::OpenHandle(this); 6992 6993 if (obj.IsThinString()) { 6994 obj = i::ThinString::cast(obj).actual(); 6995 } 6996 6997 if (!obj.SupportsExternalization()) { 6998 return false; 6999 } 7000 7001 // It is safe to call GetIsolateFromWritableHeapObject because 7002 // SupportsExternalization already checked that the object is writable. 7003 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj); 7004 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7005 7006 CHECK(resource && resource->data()); 7007 7008 bool result = obj.MakeExternal(resource); 7009 DCHECK_IMPLIES(result, obj.IsExternalString()); 7010 return result; 7011 } 7012 CanMakeExternal() const7013 bool v8::String::CanMakeExternal() const { 7014 i::String obj = *Utils::OpenHandle(this); 7015 7016 if (obj.IsThinString()) { 7017 obj = i::ThinString::cast(obj).actual(); 7018 } 7019 7020 if (!obj.SupportsExternalization()) { 7021 return false; 7022 } 7023 7024 // Only old space strings should be externalized. 7025 return !i::Heap::InYoungGeneration(obj); 7026 } 7027 StringEquals(Local<String> that) const7028 bool v8::String::StringEquals(Local<String> that) const { 7029 auto self = Utils::OpenHandle(this); 7030 auto other = Utils::OpenHandle(*that); 7031 return self->Equals(*other); 7032 } 7033 GetIsolate()7034 Isolate* v8::Object::GetIsolate() { 7035 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate(); 7036 return reinterpret_cast<Isolate*>(i_isolate); 7037 } 7038 New(Isolate * isolate)7039 Local<v8::Object> v8::Object::New(Isolate* isolate) { 7040 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7041 API_RCS_SCOPE(i_isolate, Object, New); 7042 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7043 i::Handle<i::JSObject> obj = 7044 i_isolate->factory()->NewJSObject(i_isolate->object_function()); 7045 return Utils::ToLocal(obj); 7046 } 7047 7048 namespace { 7049 7050 // TODO(v8:7569): This is a workaround for the Handle vs MaybeHandle difference 7051 // in the return types of the different Add functions: 7052 // OrderedNameDictionary::Add returns MaybeHandle, NameDictionary::Add returns 7053 // Handle. 7054 template <typename T> ToHandle(i::Handle<T> h)7055 i::Handle<T> ToHandle(i::Handle<T> h) { 7056 return h; 7057 } 7058 template <typename T> ToHandle(i::MaybeHandle<T> h)7059 i::Handle<T> ToHandle(i::MaybeHandle<T> h) { 7060 return h.ToHandleChecked(); 7061 } 7062 7063 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)7064 void AddPropertiesAndElementsToObject(i::Isolate* i_isolate, 7065 i::Handle<Dictionary>& properties, 7066 i::Handle<i::FixedArrayBase>& elements, 7067 Local<Name>* names, Local<Value>* values, 7068 size_t length) { 7069 for (size_t i = 0; i < length; ++i) { 7070 i::Handle<i::Name> name = Utils::OpenHandle(*names[i]); 7071 i::Handle<i::Object> value = Utils::OpenHandle(*values[i]); 7072 7073 // See if the {name} is a valid array index, in which case we need to 7074 // add the {name}/{value} pair to the {elements}, otherwise they end 7075 // up in the {properties} backing store. 7076 uint32_t index; 7077 if (name->AsArrayIndex(&index)) { 7078 // If this is the first element, allocate a proper 7079 // dictionary elements backing store for {elements}. 7080 if (!elements->IsNumberDictionary()) { 7081 elements = 7082 i::NumberDictionary::New(i_isolate, static_cast<int>(length)); 7083 } 7084 elements = i::NumberDictionary::Set( 7085 i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index, 7086 value); 7087 } else { 7088 // Internalize the {name} first. 7089 name = i_isolate->factory()->InternalizeName(name); 7090 i::InternalIndex const entry = properties->FindEntry(i_isolate, name); 7091 if (entry.is_not_found()) { 7092 // Add the {name}/{value} pair as a new entry. 7093 properties = ToHandle(Dictionary::Add( 7094 i_isolate, properties, name, value, i::PropertyDetails::Empty())); 7095 } else { 7096 // Overwrite the {entry} with the {value}. 7097 properties->ValueAtPut(entry, *value); 7098 } 7099 } 7100 } 7101 } 7102 7103 } // namespace 7104 New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)7105 Local<v8::Object> v8::Object::New(Isolate* isolate, 7106 Local<Value> prototype_or_null, 7107 Local<Name>* names, Local<Value>* values, 7108 size_t length) { 7109 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7110 i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null); 7111 if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(), 7112 "v8::Object::New", "prototype must be null or object")) { 7113 return Local<v8::Object>(); 7114 } 7115 API_RCS_SCOPE(i_isolate, Object, New); 7116 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7117 7118 i::Handle<i::FixedArrayBase> elements = 7119 i_isolate->factory()->empty_fixed_array(); 7120 7121 // We assume that this API is mostly used to create objects with named 7122 // properties, and so we default to creating a properties backing store 7123 // large enough to hold all of them, while we start with no elements 7124 // (see http://bit.ly/v8-fast-object-create-cpp for the motivation). 7125 if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) { 7126 i::Handle<i::SwissNameDictionary> properties = 7127 i_isolate->factory()->NewSwissNameDictionary(static_cast<int>(length)); 7128 AddPropertiesAndElementsToObject(i_isolate, properties, elements, names, 7129 values, length); 7130 i::Handle<i::JSObject> obj = 7131 i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements( 7132 i::Handle<i::HeapObject>::cast(proto), properties, elements); 7133 return Utils::ToLocal(obj); 7134 } else { 7135 i::Handle<i::NameDictionary> properties = 7136 i::NameDictionary::New(i_isolate, static_cast<int>(length)); 7137 AddPropertiesAndElementsToObject(i_isolate, properties, elements, names, 7138 values, length); 7139 i::Handle<i::JSObject> obj = 7140 i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements( 7141 i::Handle<i::HeapObject>::cast(proto), properties, elements); 7142 return Utils::ToLocal(obj); 7143 } 7144 } 7145 New(Isolate * isolate,double value)7146 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) { 7147 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7148 API_RCS_SCOPE(i_isolate, NumberObject, New); 7149 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7150 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value); 7151 i::Handle<i::Object> obj = 7152 i::Object::ToObject(i_isolate, number).ToHandleChecked(); 7153 return Utils::ToLocal(obj); 7154 } 7155 ValueOf() const7156 double v8::NumberObject::ValueOf() const { 7157 i::Handle<i::Object> obj = Utils::OpenHandle(this); 7158 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper = 7159 i::Handle<i::JSPrimitiveWrapper>::cast(obj); 7160 API_RCS_SCOPE(js_primitive_wrapper->GetIsolate(), NumberObject, NumberValue); 7161 return js_primitive_wrapper->value().Number(); 7162 } 7163 New(Isolate * isolate,int64_t value)7164 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) { 7165 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7166 API_RCS_SCOPE(i_isolate, BigIntObject, New); 7167 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7168 i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value); 7169 i::Handle<i::Object> obj = 7170 i::Object::ToObject(i_isolate, bigint).ToHandleChecked(); 7171 return Utils::ToLocal(obj); 7172 } 7173 ValueOf() const7174 Local<v8::BigInt> v8::BigIntObject::ValueOf() const { 7175 i::Handle<i::Object> obj = Utils::OpenHandle(this); 7176 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper = 7177 i::Handle<i::JSPrimitiveWrapper>::cast(obj); 7178 i::Isolate* isolate = js_primitive_wrapper->GetIsolate(); 7179 API_RCS_SCOPE(isolate, BigIntObject, BigIntValue); 7180 return Utils::ToLocal(i::Handle<i::BigInt>( 7181 i::BigInt::cast(js_primitive_wrapper->value()), isolate)); 7182 } 7183 New(Isolate * isolate,bool value)7184 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) { 7185 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7186 API_RCS_SCOPE(i_isolate, BooleanObject, New); 7187 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7188 i::Handle<i::Object> boolean(value 7189 ? i::ReadOnlyRoots(i_isolate).true_value() 7190 : i::ReadOnlyRoots(i_isolate).false_value(), 7191 i_isolate); 7192 i::Handle<i::Object> obj = 7193 i::Object::ToObject(i_isolate, boolean).ToHandleChecked(); 7194 return Utils::ToLocal(obj); 7195 } 7196 ValueOf() const7197 bool v8::BooleanObject::ValueOf() const { 7198 i::Object obj = *Utils::OpenHandle(this); 7199 i::JSPrimitiveWrapper js_primitive_wrapper = i::JSPrimitiveWrapper::cast(obj); 7200 i::Isolate* isolate = js_primitive_wrapper.GetIsolate(); 7201 API_RCS_SCOPE(isolate, BooleanObject, BooleanValue); 7202 return js_primitive_wrapper.value().IsTrue(isolate); 7203 } 7204 New(Isolate * v8_isolate,Local<String> value)7205 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate, 7206 Local<String> value) { 7207 i::Handle<i::String> string = Utils::OpenHandle(*value); 7208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 7209 API_RCS_SCOPE(isolate, StringObject, New); 7210 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7211 i::Handle<i::Object> obj = 7212 i::Object::ToObject(isolate, string).ToHandleChecked(); 7213 return Utils::ToLocal(obj); 7214 } 7215 ValueOf() const7216 Local<v8::String> v8::StringObject::ValueOf() const { 7217 i::Handle<i::Object> obj = Utils::OpenHandle(this); 7218 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper = 7219 i::Handle<i::JSPrimitiveWrapper>::cast(obj); 7220 i::Isolate* isolate = js_primitive_wrapper->GetIsolate(); 7221 API_RCS_SCOPE(isolate, StringObject, StringValue); 7222 return Utils::ToLocal(i::Handle<i::String>( 7223 i::String::cast(js_primitive_wrapper->value()), isolate)); 7224 } 7225 New(Isolate * isolate,Local<Symbol> value)7226 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) { 7227 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7228 API_RCS_SCOPE(i_isolate, SymbolObject, New); 7229 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7230 i::Handle<i::Object> obj = 7231 i::Object::ToObject(i_isolate, Utils::OpenHandle(*value)) 7232 .ToHandleChecked(); 7233 return Utils::ToLocal(obj); 7234 } 7235 ValueOf() const7236 Local<v8::Symbol> v8::SymbolObject::ValueOf() const { 7237 i::Handle<i::Object> obj = Utils::OpenHandle(this); 7238 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper = 7239 i::Handle<i::JSPrimitiveWrapper>::cast(obj); 7240 i::Isolate* isolate = js_primitive_wrapper->GetIsolate(); 7241 API_RCS_SCOPE(isolate, SymbolObject, SymbolValue); 7242 return Utils::ToLocal(i::Handle<i::Symbol>( 7243 i::Symbol::cast(js_primitive_wrapper->value()), isolate)); 7244 } 7245 New(Local<Context> context,double time)7246 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) { 7247 if (std::isnan(time)) { 7248 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. 7249 time = std::numeric_limits<double>::quiet_NaN(); 7250 } 7251 PREPARE_FOR_EXECUTION(context, Date, New, Value); 7252 Local<Value> result; 7253 has_pending_exception = !ToLocal<Value>( 7254 i::JSDate::New(isolate->date_function(), isolate->date_function(), time), 7255 &result); 7256 RETURN_ON_FAILED_EXECUTION(Value); 7257 RETURN_ESCAPED(result); 7258 } 7259 ValueOf() const7260 double v8::Date::ValueOf() const { 7261 i::Handle<i::Object> obj = Utils::OpenHandle(this); 7262 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj); 7263 API_RCS_SCOPE(jsdate->GetIsolate(), Date, NumberValue); 7264 return jsdate->value().Number(); 7265 } 7266 7267 // Assert that the static TimeZoneDetection cast in 7268 // DateTimeConfigurationChangeNotification is valid. 7269 #define TIME_ZONE_DETECTION_ASSERT_EQ(value) \ 7270 STATIC_ASSERT( \ 7271 static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \ 7272 static_cast<int>(base::TimezoneCache::TimeZoneDetection::value)); 7273 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip) TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)7274 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect) 7275 #undef TIME_ZONE_DETECTION_ASSERT_EQ 7276 7277 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context, 7278 Local<String> pattern, Flags flags) { 7279 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp); 7280 Local<v8::RegExp> result; 7281 has_pending_exception = 7282 !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern), 7283 static_cast<i::JSRegExp::Flags>(flags)), 7284 &result); 7285 RETURN_ON_FAILED_EXECUTION(RegExp); 7286 RETURN_ESCAPED(result); 7287 } 7288 NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)7289 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit( 7290 Local<Context> context, Local<String> pattern, Flags flags, 7291 uint32_t backtrack_limit) { 7292 Utils::ApiCheck(i::Smi::IsValid(backtrack_limit), 7293 "v8::RegExp::NewWithBacktrackLimit", 7294 "backtrack_limit is too large or too small."); 7295 Utils::ApiCheck(backtrack_limit != i::JSRegExp::kNoBacktrackLimit, 7296 "v8::RegExp::NewWithBacktrackLimit", 7297 "Must set backtrack_limit"); 7298 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp); 7299 Local<v8::RegExp> result; 7300 has_pending_exception = !ToLocal<RegExp>( 7301 i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern), 7302 static_cast<i::JSRegExp::Flags>(flags), backtrack_limit), 7303 &result); 7304 RETURN_ON_FAILED_EXECUTION(RegExp); 7305 RETURN_ESCAPED(result); 7306 } 7307 GetSource() const7308 Local<v8::String> v8::RegExp::GetSource() const { 7309 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this); 7310 return Utils::ToLocal( 7311 i::Handle<i::String>(obj->EscapedPattern(), obj->GetIsolate())); 7312 } 7313 7314 // Assert that the static flags cast in GetFlags is valid. 7315 #define REGEXP_FLAG_ASSERT_EQ(flag) \ 7316 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \ 7317 static_cast<int>(i::JSRegExp::flag)) 7318 REGEXP_FLAG_ASSERT_EQ(kNone); 7319 REGEXP_FLAG_ASSERT_EQ(kGlobal); 7320 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase); 7321 REGEXP_FLAG_ASSERT_EQ(kMultiline); 7322 REGEXP_FLAG_ASSERT_EQ(kSticky); 7323 REGEXP_FLAG_ASSERT_EQ(kUnicode); 7324 REGEXP_FLAG_ASSERT_EQ(kHasIndices); 7325 REGEXP_FLAG_ASSERT_EQ(kLinear); 7326 #undef REGEXP_FLAG_ASSERT_EQ 7327 GetFlags() const7328 v8::RegExp::Flags v8::RegExp::GetFlags() const { 7329 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this); 7330 return RegExp::Flags(static_cast<int>(obj->flags())); 7331 } 7332 Exec(Local<Context> context,Local<v8::String> subject)7333 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context, 7334 Local<v8::String> subject) { 7335 PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object); 7336 7337 i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this); 7338 i::Handle<i::String> subject_string = Utils::OpenHandle(*subject); 7339 7340 // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in 7341 // mind. It fetches the 'exec' property and then calls it through JSEntry. 7342 // Unfortunately, this is currently the only full implementation of 7343 // RegExp.prototype.exec available in C++. 7344 Local<v8::Object> result; 7345 has_pending_exception = !ToLocal<Object>( 7346 i::RegExpUtils::RegExpExec(isolate, regexp, subject_string, 7347 isolate->factory()->undefined_value()), 7348 &result); 7349 7350 RETURN_ON_FAILED_EXECUTION(Object); 7351 RETURN_ESCAPED(result); 7352 } 7353 New(Isolate * isolate,int length)7354 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) { 7355 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7356 API_RCS_SCOPE(i_isolate, Array, New); 7357 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7358 int real_length = length > 0 ? length : 0; 7359 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length); 7360 i::Handle<i::Object> length_obj = 7361 i_isolate->factory()->NewNumberFromInt(real_length); 7362 obj->set_length(*length_obj); 7363 return Utils::ToLocal(obj); 7364 } 7365 New(Isolate * isolate,Local<Value> * elements,size_t length)7366 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements, 7367 size_t length) { 7368 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7369 i::Factory* factory = i_isolate->factory(); 7370 API_RCS_SCOPE(i_isolate, Array, New); 7371 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7372 int len = static_cast<int>(length); 7373 7374 i::Handle<i::FixedArray> result = factory->NewFixedArray(len); 7375 for (int i = 0; i < len; i++) { 7376 i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]); 7377 result->set(i, *element); 7378 } 7379 7380 return Utils::ToLocal( 7381 factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len)); 7382 } 7383 Length() const7384 uint32_t v8::Array::Length() const { 7385 i::Handle<i::JSArray> obj = Utils::OpenHandle(this); 7386 i::Object length = obj->length(); 7387 if (length.IsSmi()) { 7388 return i::Smi::ToInt(length); 7389 } else { 7390 return static_cast<uint32_t>(length.Number()); 7391 } 7392 } 7393 New(Isolate * isolate)7394 Local<v8::Map> v8::Map::New(Isolate* isolate) { 7395 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7396 API_RCS_SCOPE(i_isolate, Map, New); 7397 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7398 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap(); 7399 return Utils::ToLocal(obj); 7400 } 7401 Size() const7402 size_t v8::Map::Size() const { 7403 i::Handle<i::JSMap> obj = Utils::OpenHandle(this); 7404 return i::OrderedHashMap::cast(obj->table()).NumberOfElements(); 7405 } 7406 Clear()7407 void Map::Clear() { 7408 auto self = Utils::OpenHandle(this); 7409 i::Isolate* isolate = self->GetIsolate(); 7410 API_RCS_SCOPE(isolate, Map, Clear); 7411 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7412 i::JSMap::Clear(isolate, self); 7413 } 7414 Get(Local<Context> context,Local<Value> key)7415 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) { 7416 PREPARE_FOR_EXECUTION(context, Map, Get, Value); 7417 auto self = Utils::OpenHandle(this); 7418 Local<Value> result; 7419 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7420 has_pending_exception = 7421 !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(), 7422 self, arraysize(argv), argv), 7423 &result); 7424 RETURN_ON_FAILED_EXECUTION(Value); 7425 RETURN_ESCAPED(result); 7426 } 7427 Set(Local<Context> context,Local<Value> key,Local<Value> value)7428 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key, 7429 Local<Value> value) { 7430 PREPARE_FOR_EXECUTION(context, Map, Set, Map); 7431 auto self = Utils::OpenHandle(this); 7432 i::Handle<i::Object> result; 7433 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key), 7434 Utils::OpenHandle(*value)}; 7435 has_pending_exception = 7436 !i::Execution::CallBuiltin(isolate, isolate->map_set(), self, 7437 arraysize(argv), argv) 7438 .ToHandle(&result); 7439 RETURN_ON_FAILED_EXECUTION(Map); 7440 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result))); 7441 } 7442 Has(Local<Context> context,Local<Value> key)7443 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) { 7444 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7445 ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope); 7446 auto self = Utils::OpenHandle(this); 7447 i::Handle<i::Object> result; 7448 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7449 has_pending_exception = 7450 !i::Execution::CallBuiltin(isolate, isolate->map_has(), self, 7451 arraysize(argv), argv) 7452 .ToHandle(&result); 7453 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7454 return Just(result->IsTrue(isolate)); 7455 } 7456 Delete(Local<Context> context,Local<Value> key)7457 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) { 7458 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7459 ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope); 7460 auto self = Utils::OpenHandle(this); 7461 i::Handle<i::Object> result; 7462 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7463 has_pending_exception = 7464 !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self, 7465 arraysize(argv), argv) 7466 .ToHandle(&result); 7467 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7468 return Just(result->IsTrue(isolate)); 7469 } 7470 7471 namespace { 7472 7473 enum class MapAsArrayKind { 7474 kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE, 7475 kKeys = i::JS_MAP_KEY_ITERATOR_TYPE, 7476 kValues = i::JS_MAP_VALUE_ITERATOR_TYPE 7477 }; 7478 7479 enum class SetAsArrayKind { 7480 kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE, 7481 kValues = i::JS_SET_VALUE_ITERATOR_TYPE 7482 }; 7483 MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7484 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj, 7485 int offset, MapAsArrayKind kind) { 7486 i::Factory* factory = isolate->factory(); 7487 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj), 7488 isolate); 7489 const bool collect_keys = 7490 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys; 7491 const bool collect_values = 7492 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues; 7493 int capacity = table->UsedCapacity(); 7494 int max_length = 7495 (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1); 7496 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length); 7497 int result_index = 0; 7498 { 7499 i::DisallowGarbageCollection no_gc; 7500 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value(); 7501 for (int i = offset; i < capacity; ++i) { 7502 i::InternalIndex entry(i); 7503 i::Object key = table->KeyAt(entry); 7504 if (key == the_hole) continue; 7505 if (collect_keys) result->set(result_index++, key); 7506 if (collect_values) result->set(result_index++, table->ValueAt(entry)); 7507 } 7508 } 7509 DCHECK_GE(max_length, result_index); 7510 if (result_index == 0) return factory->NewJSArray(0); 7511 result->Shrink(isolate, result_index); 7512 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, 7513 result_index); 7514 } 7515 7516 } // namespace 7517 AsArray() const7518 Local<Array> Map::AsArray() const { 7519 i::Handle<i::JSMap> obj = Utils::OpenHandle(this); 7520 i::Isolate* isolate = obj->GetIsolate(); 7521 API_RCS_SCOPE(isolate, Map, AsArray); 7522 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7523 return Utils::ToLocal( 7524 MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries)); 7525 } 7526 New(Isolate * isolate)7527 Local<v8::Set> v8::Set::New(Isolate* isolate) { 7528 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7529 API_RCS_SCOPE(i_isolate, Set, New); 7530 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7531 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet(); 7532 return Utils::ToLocal(obj); 7533 } 7534 Size() const7535 size_t v8::Set::Size() const { 7536 i::Handle<i::JSSet> obj = Utils::OpenHandle(this); 7537 return i::OrderedHashSet::cast(obj->table()).NumberOfElements(); 7538 } 7539 Clear()7540 void Set::Clear() { 7541 auto self = Utils::OpenHandle(this); 7542 i::Isolate* isolate = self->GetIsolate(); 7543 API_RCS_SCOPE(isolate, Set, Clear); 7544 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7545 i::JSSet::Clear(isolate, self); 7546 } 7547 Add(Local<Context> context,Local<Value> key)7548 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) { 7549 PREPARE_FOR_EXECUTION(context, Set, Add, Set); 7550 auto self = Utils::OpenHandle(this); 7551 i::Handle<i::Object> result; 7552 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7553 has_pending_exception = 7554 !i::Execution::CallBuiltin(isolate, isolate->set_add(), self, 7555 arraysize(argv), argv) 7556 .ToHandle(&result); 7557 RETURN_ON_FAILED_EXECUTION(Set); 7558 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result))); 7559 } 7560 Has(Local<Context> context,Local<Value> key)7561 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) { 7562 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7563 ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope); 7564 auto self = Utils::OpenHandle(this); 7565 i::Handle<i::Object> result; 7566 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7567 has_pending_exception = 7568 !i::Execution::CallBuiltin(isolate, isolate->set_has(), self, 7569 arraysize(argv), argv) 7570 .ToHandle(&result); 7571 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7572 return Just(result->IsTrue(isolate)); 7573 } 7574 Delete(Local<Context> context,Local<Value> key)7575 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) { 7576 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7577 ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope); 7578 auto self = Utils::OpenHandle(this); 7579 i::Handle<i::Object> result; 7580 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 7581 has_pending_exception = 7582 !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self, 7583 arraysize(argv), argv) 7584 .ToHandle(&result); 7585 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7586 return Just(result->IsTrue(isolate)); 7587 } 7588 7589 namespace { SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7590 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj, 7591 int offset, SetAsArrayKind kind) { 7592 i::Factory* factory = isolate->factory(); 7593 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj), 7594 isolate); 7595 // Elements skipped by |offset| may already be deleted. 7596 int capacity = table->UsedCapacity(); 7597 const bool collect_key_values = kind == SetAsArrayKind::kEntries; 7598 int max_length = (capacity - offset) * (collect_key_values ? 2 : 1); 7599 if (max_length == 0) return factory->NewJSArray(0); 7600 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length); 7601 int result_index = 0; 7602 { 7603 i::DisallowGarbageCollection no_gc; 7604 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value(); 7605 for (int i = offset; i < capacity; ++i) { 7606 i::InternalIndex entry(i); 7607 i::Object key = table->KeyAt(entry); 7608 if (key == the_hole) continue; 7609 result->set(result_index++, key); 7610 if (collect_key_values) result->set(result_index++, key); 7611 } 7612 } 7613 DCHECK_GE(max_length, result_index); 7614 if (result_index == 0) return factory->NewJSArray(0); 7615 result->Shrink(isolate, result_index); 7616 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, 7617 result_index); 7618 } 7619 } // namespace 7620 AsArray() const7621 Local<Array> Set::AsArray() const { 7622 i::Handle<i::JSSet> obj = Utils::OpenHandle(this); 7623 i::Isolate* isolate = obj->GetIsolate(); 7624 API_RCS_SCOPE(isolate, Set, AsArray); 7625 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7626 return Utils::ToLocal( 7627 SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues)); 7628 } 7629 New(Local<Context> context)7630 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) { 7631 PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver); 7632 Local<Promise::Resolver> result; 7633 has_pending_exception = 7634 !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result); 7635 RETURN_ON_FAILED_EXECUTION(Promise::Resolver); 7636 RETURN_ESCAPED(result); 7637 } 7638 GetPromise()7639 Local<Promise> Promise::Resolver::GetPromise() { 7640 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); 7641 return Local<Promise>::Cast(Utils::ToLocal(promise)); 7642 } 7643 Resolve(Local<Context> context,Local<Value> value)7644 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context, 7645 Local<Value> value) { 7646 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7647 ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(), 7648 i::HandleScope); 7649 auto self = Utils::OpenHandle(this); 7650 auto promise = i::Handle<i::JSPromise>::cast(self); 7651 7652 if (promise->status() != Promise::kPending) { 7653 return Just(true); 7654 } 7655 7656 has_pending_exception = 7657 i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null(); 7658 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7659 return Just(true); 7660 } 7661 Reject(Local<Context> context,Local<Value> value)7662 Maybe<bool> Promise::Resolver::Reject(Local<Context> context, 7663 Local<Value> value) { 7664 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 7665 ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(), 7666 i::HandleScope); 7667 auto self = Utils::OpenHandle(this); 7668 auto promise = i::Handle<i::JSPromise>::cast(self); 7669 7670 if (promise->status() != Promise::kPending) { 7671 return Just(true); 7672 } 7673 7674 has_pending_exception = 7675 i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null(); 7676 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 7677 return Just(true); 7678 } 7679 Catch(Local<Context> context,Local<Function> handler)7680 MaybeLocal<Promise> Promise::Catch(Local<Context> context, 7681 Local<Function> handler) { 7682 PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise); 7683 auto self = Utils::OpenHandle(this); 7684 i::Handle<i::Object> argv[] = {isolate->factory()->undefined_value(), 7685 Utils::OpenHandle(*handler)}; 7686 i::Handle<i::Object> result; 7687 // Do not call the built-in Promise.prototype.catch! 7688 // v8::Promise should not call out to a monkeypatched Promise.prototype.then 7689 // as the implementation of Promise.prototype.catch does. 7690 has_pending_exception = 7691 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self, 7692 arraysize(argv), argv) 7693 .ToHandle(&result); 7694 RETURN_ON_FAILED_EXECUTION(Promise); 7695 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 7696 } 7697 Then(Local<Context> context,Local<Function> handler)7698 MaybeLocal<Promise> Promise::Then(Local<Context> context, 7699 Local<Function> handler) { 7700 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise); 7701 auto self = Utils::OpenHandle(this); 7702 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)}; 7703 i::Handle<i::Object> result; 7704 has_pending_exception = 7705 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self, 7706 arraysize(argv), argv) 7707 .ToHandle(&result); 7708 RETURN_ON_FAILED_EXECUTION(Promise); 7709 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 7710 } 7711 Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7712 MaybeLocal<Promise> Promise::Then(Local<Context> context, 7713 Local<Function> on_fulfilled, 7714 Local<Function> on_rejected) { 7715 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise); 7716 auto self = Utils::OpenHandle(this); 7717 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled), 7718 Utils::OpenHandle(*on_rejected)}; 7719 i::Handle<i::Object> result; 7720 has_pending_exception = 7721 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self, 7722 arraysize(argv), argv) 7723 .ToHandle(&result); 7724 RETURN_ON_FAILED_EXECUTION(Promise); 7725 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 7726 } 7727 HasHandler() const7728 bool Promise::HasHandler() const { 7729 i::JSReceiver promise = *Utils::OpenHandle(this); 7730 i::Isolate* isolate = promise.GetIsolate(); 7731 API_RCS_SCOPE(isolate, Promise, HasRejectHandler); 7732 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7733 if (!promise.IsJSPromise()) return false; 7734 return i::JSPromise::cast(promise).has_handler(); 7735 } 7736 Result()7737 Local<Value> Promise::Result() { 7738 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); 7739 i::Isolate* isolate = promise->GetIsolate(); 7740 API_RCS_SCOPE(isolate, Promise, Result); 7741 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise); 7742 Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result", 7743 "Promise is still pending"); 7744 i::Handle<i::Object> result(js_promise->result(), isolate); 7745 return Utils::ToLocal(result); 7746 } 7747 State()7748 Promise::PromiseState Promise::State() { 7749 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); 7750 API_RCS_SCOPE(promise->GetIsolate(), Promise, Status); 7751 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise); 7752 return static_cast<PromiseState>(js_promise->status()); 7753 } 7754 MarkAsHandled()7755 void Promise::MarkAsHandled() { 7756 i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this); 7757 js_promise->set_has_handler(true); 7758 } 7759 MarkAsSilent()7760 void Promise::MarkAsSilent() { 7761 i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this); 7762 js_promise->set_is_silent(true); 7763 } 7764 GetTarget()7765 Local<Value> Proxy::GetTarget() { 7766 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 7767 i::Handle<i::Object> target(self->target(), self->GetIsolate()); 7768 return Utils::ToLocal(target); 7769 } 7770 GetHandler()7771 Local<Value> Proxy::GetHandler() { 7772 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 7773 i::Handle<i::Object> handler(self->handler(), self->GetIsolate()); 7774 return Utils::ToLocal(handler); 7775 } 7776 IsRevoked() const7777 bool Proxy::IsRevoked() const { 7778 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 7779 return self->IsRevoked(); 7780 } 7781 Revoke()7782 void Proxy::Revoke() { 7783 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 7784 i::JSProxy::Revoke(self); 7785 } 7786 New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7787 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target, 7788 Local<Object> local_handler) { 7789 PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy); 7790 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target); 7791 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler); 7792 Local<Proxy> result; 7793 has_pending_exception = 7794 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result); 7795 RETURN_ON_FAILED_EXECUTION(Proxy); 7796 RETURN_ESCAPED(result); 7797 } 7798 CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7799 CompiledWasmModule::CompiledWasmModule( 7800 std::shared_ptr<internal::wasm::NativeModule> native_module, 7801 const char* source_url, size_t url_length) 7802 : native_module_(std::move(native_module)), 7803 source_url_(source_url, url_length) { 7804 CHECK_NOT_NULL(native_module_); 7805 } 7806 Serialize()7807 OwnedBuffer CompiledWasmModule::Serialize() { 7808 #if V8_ENABLE_WEBASSEMBLY 7809 TRACE_EVENT0("v8.wasm", "wasm.SerializeModule"); 7810 i::wasm::WasmSerializer wasm_serializer(native_module_.get()); 7811 size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize(); 7812 std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); 7813 if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size})) 7814 return {}; 7815 return {std::move(buffer), buffer_size}; 7816 #else 7817 UNREACHABLE(); 7818 #endif // V8_ENABLE_WEBASSEMBLY 7819 } 7820 GetWireBytesRef()7821 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() { 7822 #if V8_ENABLE_WEBASSEMBLY 7823 base::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes(); 7824 return {bytes_vec.begin(), bytes_vec.size()}; 7825 #else 7826 UNREACHABLE(); 7827 #endif // V8_ENABLE_WEBASSEMBLY 7828 } 7829 Buffer()7830 Local<ArrayBuffer> v8::WasmMemoryObject::Buffer() { 7831 #if V8_ENABLE_WEBASSEMBLY 7832 i::Handle<i::WasmMemoryObject> obj = Utils::OpenHandle(this); 7833 i::Handle<i::JSArrayBuffer> buffer(obj->array_buffer(), obj->GetIsolate()); 7834 return Utils::ToLocal(buffer); 7835 #else 7836 UNREACHABLE(); 7837 #endif // V8_ENABLE_WEBASSEMBLY 7838 } 7839 GetCompiledModule()7840 CompiledWasmModule WasmModuleObject::GetCompiledModule() { 7841 #if V8_ENABLE_WEBASSEMBLY 7842 auto obj = i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this)); 7843 auto url = 7844 i::handle(i::String::cast(obj->script().name()), obj->GetIsolate()); 7845 int length; 7846 std::unique_ptr<char[]> cstring = 7847 url->ToCString(i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length); 7848 return CompiledWasmModule(std::move(obj->shared_native_module()), 7849 cstring.get(), length); 7850 #else 7851 UNREACHABLE(); 7852 #endif // V8_ENABLE_WEBASSEMBLY 7853 } 7854 FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7855 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule( 7856 Isolate* isolate, const CompiledWasmModule& compiled_module) { 7857 #if V8_ENABLE_WEBASSEMBLY 7858 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7859 i::Handle<i::WasmModuleObject> module_object = 7860 i::wasm::GetWasmEngine()->ImportNativeModule( 7861 i_isolate, compiled_module.native_module_, 7862 base::VectorOf(compiled_module.source_url())); 7863 return Local<WasmModuleObject>::Cast( 7864 Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object))); 7865 #else 7866 UNREACHABLE(); 7867 #endif // V8_ENABLE_WEBASSEMBLY 7868 } 7869 Compile(Isolate * isolate,MemorySpan<const uint8_t> wire_bytes)7870 MaybeLocal<WasmModuleObject> WasmModuleObject::Compile( 7871 Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) { 7872 #if V8_ENABLE_WEBASSEMBLY 7873 const uint8_t* start = wire_bytes.data(); 7874 size_t length = wire_bytes.size(); 7875 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7876 if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) { 7877 return MaybeLocal<WasmModuleObject>(); 7878 } 7879 i::MaybeHandle<i::JSObject> maybe_compiled; 7880 { 7881 i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()"); 7882 auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate); 7883 maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile( 7884 i_isolate, enabled_features, &thrower, 7885 i::wasm::ModuleWireBytes(start, start + length)); 7886 } 7887 CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception()); 7888 if (maybe_compiled.is_null()) { 7889 i_isolate->OptionalRescheduleException(false); 7890 return MaybeLocal<WasmModuleObject>(); 7891 } 7892 return Local<WasmModuleObject>::Cast( 7893 Utils::ToLocal(maybe_compiled.ToHandleChecked())); 7894 #else 7895 Utils::ApiCheck(false, "WasmModuleObject::Compile", 7896 "WebAssembly support is not enabled."); 7897 UNREACHABLE(); 7898 #endif // V8_ENABLE_WEBASSEMBLY 7899 } 7900 WasmModuleObjectBuilderStreaming(Isolate * isolate)7901 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming( 7902 Isolate* isolate) { 7903 USE(isolate_); 7904 } 7905 GetPromise()7906 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; } 7907 OnBytesReceived(const uint8_t * bytes,size_t size)7908 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes, 7909 size_t size) {} 7910 Finish()7911 void WasmModuleObjectBuilderStreaming::Finish() {} 7912 Abort(MaybeLocal<Value> exception)7913 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {} 7914 Reallocate(void * data,size_t old_length,size_t new_length)7915 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length, 7916 size_t new_length) { 7917 if (old_length == new_length) return data; 7918 uint8_t* new_data = 7919 reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length)); 7920 if (new_data == nullptr) return nullptr; 7921 size_t bytes_to_copy = std::min(old_length, new_length); 7922 memcpy(new_data, data, bytes_to_copy); 7923 if (new_length > bytes_to_copy) { 7924 memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy); 7925 } 7926 Free(data, old_length); 7927 return new_data; 7928 } 7929 7930 // static NewDefaultAllocator()7931 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() { 7932 return new ArrayBufferAllocator(); 7933 } 7934 IsDetachable() const7935 bool v8::ArrayBuffer::IsDetachable() const { 7936 return Utils::OpenHandle(this)->is_detachable(); 7937 } 7938 WasDetached() const7939 bool v8::ArrayBuffer::WasDetached() const { 7940 return Utils::OpenHandle(this)->was_detached(); 7941 } 7942 7943 namespace { ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7944 std::shared_ptr<i::BackingStore> ToInternal( 7945 std::shared_ptr<i::BackingStoreBase> backing_store) { 7946 return std::static_pointer_cast<i::BackingStore>(backing_store); 7947 } 7948 } // namespace 7949 Detach()7950 void v8::ArrayBuffer::Detach() { 7951 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 7952 i::Isolate* isolate = obj->GetIsolate(); 7953 Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach", 7954 "Only detachable ArrayBuffers can be detached"); 7955 API_RCS_SCOPE(isolate, ArrayBuffer, Detach); 7956 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 7957 obj->Detach(); 7958 } 7959 ByteLength() const7960 size_t v8::ArrayBuffer::ByteLength() const { 7961 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 7962 return obj->byte_length(); 7963 } 7964 New(Isolate * isolate,size_t byte_length)7965 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { 7966 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7967 API_RCS_SCOPE(i_isolate, ArrayBuffer, New); 7968 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7969 i::MaybeHandle<i::JSArrayBuffer> result = 7970 i_isolate->factory()->NewJSArrayBufferAndBackingStore( 7971 byte_length, i::InitializedFlag::kZeroInitialized); 7972 7973 i::Handle<i::JSArrayBuffer> array_buffer; 7974 if (!result.ToHandle(&array_buffer)) { 7975 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal 7976 // version that throws an exception or otherwise does not crash. 7977 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New"); 7978 } 7979 7980 return Utils::ToLocal(array_buffer); 7981 } 7982 New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7983 Local<ArrayBuffer> v8::ArrayBuffer::New( 7984 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) { 7985 CHECK_IMPLIES(backing_store->ByteLength() != 0, 7986 backing_store->Data() != nullptr); 7987 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7988 API_RCS_SCOPE(i_isolate, ArrayBuffer, New); 7989 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 7990 std::shared_ptr<i::BackingStore> i_backing_store( 7991 ToInternal(std::move(backing_store))); 7992 Utils::ApiCheck( 7993 !i_backing_store->is_shared(), "v8_ArrayBuffer_New", 7994 "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer"); 7995 i::Handle<i::JSArrayBuffer> obj = 7996 i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store)); 7997 return Utils::ToLocal(obj); 7998 } 7999 NewBackingStore(Isolate * isolate,size_t byte_length)8000 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore( 8001 Isolate* isolate, size_t byte_length) { 8002 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8003 API_RCS_SCOPE(i_isolate, ArrayBuffer, NewBackingStore); 8004 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); 8005 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8006 std::unique_ptr<i::BackingStoreBase> backing_store = 8007 i::BackingStore::Allocate(i_isolate, byte_length, 8008 i::SharedFlag::kNotShared, 8009 i::InitializedFlag::kZeroInitialized); 8010 if (!backing_store) { 8011 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore"); 8012 } 8013 return std::unique_ptr<v8::BackingStore>( 8014 static_cast<v8::BackingStore*>(backing_store.release())); 8015 } 8016 NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8017 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore( 8018 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, 8019 void* deleter_data) { 8020 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); 8021 std::unique_ptr<i::BackingStoreBase> backing_store = 8022 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data, 8023 i::SharedFlag::kNotShared); 8024 return std::unique_ptr<v8::BackingStore>( 8025 static_cast<v8::BackingStore*>(backing_store.release())); 8026 } 8027 Buffer()8028 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() { 8029 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 8030 i::Handle<i::JSArrayBuffer> buffer; 8031 if (obj->IsJSDataView()) { 8032 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj), 8033 obj->GetIsolate()); 8034 DCHECK(data_view->buffer().IsJSArrayBuffer()); 8035 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()), 8036 data_view->GetIsolate()); 8037 } else { 8038 DCHECK(obj->IsJSTypedArray()); 8039 buffer = i::JSTypedArray::cast(*obj).GetBuffer(); 8040 } 8041 return Utils::ToLocal(buffer); 8042 } 8043 CopyContents(void * dest,size_t byte_length)8044 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { 8045 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this); 8046 size_t bytes_to_copy = std::min(byte_length, self->byte_length()); 8047 if (bytes_to_copy) { 8048 i::DisallowGarbageCollection no_gc; 8049 i::Isolate* isolate = self->GetIsolate(); 8050 const char* source; 8051 if (self->IsJSTypedArray()) { 8052 i::Handle<i::JSTypedArray> array(i::JSTypedArray::cast(*self), isolate); 8053 source = reinterpret_cast<char*>(array->DataPtr()); 8054 } else { 8055 DCHECK(self->IsJSDataView()); 8056 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*self), isolate); 8057 source = reinterpret_cast<char*>(data_view->data_pointer()); 8058 } 8059 memcpy(dest, source, bytes_to_copy); 8060 } 8061 return bytes_to_copy; 8062 } 8063 HasBuffer() const8064 bool v8::ArrayBufferView::HasBuffer() const { 8065 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this); 8066 if (!self->IsJSTypedArray()) return true; 8067 auto typed_array = i::Handle<i::JSTypedArray>::cast(self); 8068 return !typed_array->is_on_heap(); 8069 } 8070 ByteOffset()8071 size_t v8::ArrayBufferView::ByteOffset() { 8072 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 8073 return obj->WasDetached() ? 0 : obj->byte_offset(); 8074 } 8075 ByteLength()8076 size_t v8::ArrayBufferView::ByteLength() { 8077 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 8078 return obj->WasDetached() ? 0 : obj->byte_length(); 8079 } 8080 Length()8081 size_t v8::TypedArray::Length() { 8082 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); 8083 return obj->WasDetached() ? 0 : obj->length(); 8084 } 8085 8086 static_assert( 8087 v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength, 8088 "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength"); 8089 8090 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype) \ 8091 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \ 8092 size_t byte_offset, size_t length) { \ 8093 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ 8094 API_RCS_SCOPE(isolate, Type##Array, New); \ 8095 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \ 8096 if (!Utils::ApiCheck(length <= kMaxLength, \ 8097 "v8::" #Type \ 8098 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \ 8099 "length exceeds max allowed value")) { \ 8100 return Local<Type##Array>(); \ 8101 } \ 8102 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \ 8103 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \ 8104 i::kExternal##Type##Array, buffer, byte_offset, length); \ 8105 return Utils::ToLocal##Type##Array(obj); \ 8106 } \ 8107 Local<Type##Array> Type##Array::New( \ 8108 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \ 8109 size_t length) { \ 8110 CHECK(i::FLAG_harmony_sharedarraybuffer); \ 8111 i::Isolate* isolate = \ 8112 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \ 8113 API_RCS_SCOPE(isolate, Type##Array, New); \ 8114 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \ 8115 if (!Utils::ApiCheck( \ 8116 length <= kMaxLength, \ 8117 "v8::" #Type \ 8118 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \ 8119 "length exceeds max allowed value")) { \ 8120 return Local<Type##Array>(); \ 8121 } \ 8122 i::Handle<i::JSArrayBuffer> buffer = \ 8123 Utils::OpenHandle(*shared_array_buffer); \ 8124 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \ 8125 i::kExternal##Type##Array, buffer, byte_offset, length); \ 8126 return Utils::ToLocal##Type##Array(obj); \ 8127 } 8128 TYPED_ARRAYS(TYPED_ARRAY_NEW)8129 TYPED_ARRAYS(TYPED_ARRAY_NEW) 8130 #undef TYPED_ARRAY_NEW 8131 8132 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer, 8133 size_t byte_offset, size_t byte_length) { 8134 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); 8135 i::Isolate* isolate = buffer->GetIsolate(); 8136 API_RCS_SCOPE(isolate, DataView, New); 8137 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 8138 i::Handle<i::JSDataView> obj = 8139 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length); 8140 return Utils::ToLocal(obj); 8141 } 8142 New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)8143 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer, 8144 size_t byte_offset, size_t byte_length) { 8145 CHECK(i::FLAG_harmony_sharedarraybuffer); 8146 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer); 8147 i::Isolate* isolate = buffer->GetIsolate(); 8148 API_RCS_SCOPE(isolate, DataView, New); 8149 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 8150 i::Handle<i::JSDataView> obj = 8151 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length); 8152 return Utils::ToLocal(obj); 8153 } 8154 ByteLength() const8155 size_t v8::SharedArrayBuffer::ByteLength() const { 8156 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 8157 return obj->byte_length(); 8158 } 8159 New(Isolate * isolate,size_t byte_length)8160 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate, 8161 size_t byte_length) { 8162 CHECK(i::FLAG_harmony_sharedarraybuffer); 8163 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8164 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New); 8165 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8166 8167 std::unique_ptr<i::BackingStore> backing_store = 8168 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared, 8169 i::InitializedFlag::kZeroInitialized); 8170 8171 if (!backing_store) { 8172 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal 8173 // version that throws an exception or otherwise does not crash. 8174 i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New"); 8175 } 8176 8177 i::Handle<i::JSArrayBuffer> obj = 8178 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store)); 8179 return Utils::ToLocalShared(obj); 8180 } 8181 New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)8182 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( 8183 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) { 8184 CHECK(i::FLAG_harmony_sharedarraybuffer); 8185 CHECK_IMPLIES(backing_store->ByteLength() != 0, 8186 backing_store->Data() != nullptr); 8187 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8188 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, New); 8189 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8190 std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store)); 8191 Utils::ApiCheck( 8192 i_backing_store->is_shared(), "v8_SharedArrayBuffer_New", 8193 "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer"); 8194 i::Handle<i::JSArrayBuffer> obj = 8195 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store)); 8196 return Utils::ToLocalShared(obj); 8197 } 8198 NewBackingStore(Isolate * isolate,size_t byte_length)8199 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore( 8200 Isolate* isolate, size_t byte_length) { 8201 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8202 API_RCS_SCOPE(i_isolate, SharedArrayBuffer, NewBackingStore); 8203 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); 8204 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8205 std::unique_ptr<i::BackingStoreBase> backing_store = 8206 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared, 8207 i::InitializedFlag::kZeroInitialized); 8208 if (!backing_store) { 8209 i::FatalProcessOutOfMemory(i_isolate, 8210 "v8::SharedArrayBuffer::NewBackingStore"); 8211 } 8212 return std::unique_ptr<v8::BackingStore>( 8213 static_cast<v8::BackingStore*>(backing_store.release())); 8214 } 8215 NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)8216 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore( 8217 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter, 8218 void* deleter_data) { 8219 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); 8220 std::unique_ptr<i::BackingStoreBase> backing_store = 8221 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data, 8222 i::SharedFlag::kShared); 8223 return std::unique_ptr<v8::BackingStore>( 8224 static_cast<v8::BackingStore*>(backing_store.release())); 8225 } 8226 New(Isolate * isolate,Local<String> name)8227 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) { 8228 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8229 API_RCS_SCOPE(i_isolate, Symbol, New); 8230 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8231 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol(); 8232 if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name)); 8233 return Utils::ToLocal(result); 8234 } 8235 For(Isolate * isolate,Local<String> name)8236 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) { 8237 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8238 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 8239 return Utils::ToLocal( 8240 i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false)); 8241 } 8242 ForApi(Isolate * isolate,Local<String> name)8243 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) { 8244 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8245 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 8246 return Utils::ToLocal( 8247 i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false)); 8248 } 8249 8250 #define WELL_KNOWN_SYMBOLS(V) \ 8251 V(AsyncIterator, async_iterator) \ 8252 V(HasInstance, has_instance) \ 8253 V(IsConcatSpreadable, is_concat_spreadable) \ 8254 V(Iterator, iterator) \ 8255 V(Match, match) \ 8256 V(Replace, replace) \ 8257 V(Search, search) \ 8258 V(Split, split) \ 8259 V(ToPrimitive, to_primitive) \ 8260 V(ToStringTag, to_string_tag) \ 8261 V(Unscopables, unscopables) 8262 8263 #define SYMBOL_GETTER(Name, name) \ 8264 Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) { \ 8265 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \ 8266 return Utils::ToLocal(i_isolate->factory()->name##_symbol()); \ 8267 } 8268 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8269 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER) 8270 8271 #undef SYMBOL_GETTER 8272 #undef WELL_KNOWN_SYMBOLS 8273 8274 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) { 8275 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8276 API_RCS_SCOPE(i_isolate, Private, New); 8277 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 8278 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol(); 8279 if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name)); 8280 Local<Symbol> result = Utils::ToLocal(symbol); 8281 return v8::Local<Private>(reinterpret_cast<Private*>(*result)); 8282 } 8283 ForApi(Isolate * isolate,Local<String> name)8284 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) { 8285 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8286 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 8287 Local<Symbol> result = Utils::ToLocal( 8288 i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true)); 8289 return v8::Local<Private>(reinterpret_cast<Private*>(*result)); 8290 } 8291 New(Isolate * isolate,double value)8292 Local<Number> v8::Number::New(Isolate* isolate, double value) { 8293 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 8294 if (std::isnan(value)) { 8295 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. 8296 value = std::numeric_limits<double>::quiet_NaN(); 8297 } 8298 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); 8299 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 8300 return Utils::NumberToLocal(result); 8301 } 8302 New(Isolate * isolate,int32_t value)8303 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) { 8304 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 8305 if (i::Smi::IsValid(value)) { 8306 return Utils::IntegerToLocal( 8307 i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate)); 8308 } 8309 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); 8310 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 8311 return Utils::IntegerToLocal(result); 8312 } 8313 NewFromUnsigned(Isolate * isolate,uint32_t value)8314 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) { 8315 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 8316 bool fits_into_int32_t = (value & (1 << 31)) == 0; 8317 if (fits_into_int32_t) { 8318 return Integer::New(isolate, static_cast<int32_t>(value)); 8319 } 8320 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); 8321 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 8322 return Utils::IntegerToLocal(result); 8323 } 8324 New(Isolate * isolate,int64_t value)8325 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) { 8326 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 8327 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); 8328 i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value); 8329 return Utils::ToLocal(result); 8330 } 8331 NewFromUnsigned(Isolate * isolate,uint64_t value)8332 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) { 8333 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 8334 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); 8335 i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value); 8336 return Utils::ToLocal(result); 8337 } 8338 NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8339 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context, 8340 int sign_bit, int word_count, 8341 const uint64_t* words) { 8342 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 8343 ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords, 8344 MaybeLocal<BigInt>(), InternalEscapableScope); 8345 i::MaybeHandle<i::BigInt> result = 8346 i::BigInt::FromWords64(isolate, sign_bit, word_count, words); 8347 has_pending_exception = result.is_null(); 8348 RETURN_ON_FAILED_EXECUTION(BigInt); 8349 RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked())); 8350 } 8351 Uint64Value(bool * lossless) const8352 uint64_t v8::BigInt::Uint64Value(bool* lossless) const { 8353 i::Handle<i::BigInt> handle = Utils::OpenHandle(this); 8354 return handle->AsUint64(lossless); 8355 } 8356 Int64Value(bool * lossless) const8357 int64_t v8::BigInt::Int64Value(bool* lossless) const { 8358 i::Handle<i::BigInt> handle = Utils::OpenHandle(this); 8359 return handle->AsInt64(lossless); 8360 } 8361 WordCount() const8362 int BigInt::WordCount() const { 8363 i::Handle<i::BigInt> handle = Utils::OpenHandle(this); 8364 return handle->Words64Count(); 8365 } 8366 ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8367 void BigInt::ToWordsArray(int* sign_bit, int* word_count, 8368 uint64_t* words) const { 8369 i::Handle<i::BigInt> handle = Utils::OpenHandle(this); 8370 return handle->ToWordsArray64(sign_bit, word_count, words); 8371 } 8372 ReportExternalAllocationLimitReached()8373 void Isolate::ReportExternalAllocationLimitReached() { 8374 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap(); 8375 if (heap->gc_state() != i::Heap::NOT_IN_GC) return; 8376 heap->ReportExternalMemoryPressure(); 8377 } 8378 GetHeapProfiler()8379 HeapProfiler* Isolate::GetHeapProfiler() { 8380 i::HeapProfiler* heap_profiler = 8381 reinterpret_cast<i::Isolate*>(this)->heap_profiler(); 8382 return reinterpret_cast<HeapProfiler*>(heap_profiler); 8383 } 8384 SetIdle(bool is_idle)8385 void Isolate::SetIdle(bool is_idle) { 8386 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8387 isolate->SetIdle(is_idle); 8388 } 8389 GetArrayBufferAllocator()8390 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() { 8391 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8392 return isolate->array_buffer_allocator(); 8393 } 8394 InContext()8395 bool Isolate::InContext() { 8396 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8397 return !isolate->context().is_null(); 8398 } 8399 ClearKeptObjects()8400 void Isolate::ClearKeptObjects() { 8401 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8402 isolate->ClearKeptObjects(); 8403 } 8404 GetCurrentContext()8405 v8::Local<v8::Context> Isolate::GetCurrentContext() { 8406 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8407 i::Context context = isolate->context(); 8408 if (context.is_null()) return Local<Context>(); 8409 i::Context native_context = context.native_context(); 8410 if (native_context.is_null()) return Local<Context>(); 8411 return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate)); 8412 } 8413 GetEnteredOrMicrotaskContext()8414 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() { 8415 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8416 i::Handle<i::Object> last = 8417 isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext(); 8418 if (last.is_null()) return Local<Context>(); 8419 DCHECK(last->IsNativeContext()); 8420 return Utils::ToLocal(i::Handle<i::Context>::cast(last)); 8421 } 8422 GetIncumbentContext()8423 v8::Local<v8::Context> Isolate::GetIncumbentContext() { 8424 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8425 i::Handle<i::Context> context = isolate->GetIncumbentContext(); 8426 return Utils::ToLocal(context); 8427 } 8428 ThrowError(v8::Local<v8::String> message)8429 v8::Local<Value> Isolate::ThrowError(v8::Local<v8::String> message) { 8430 return ThrowException(v8::Exception::Error(message)); 8431 } 8432 ThrowException(v8::Local<v8::Value> value)8433 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) { 8434 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8435 ENTER_V8_DO_NOT_USE(isolate); 8436 // If we're passed an empty handle, we throw an undefined exception 8437 // to deal more gracefully with out of memory situations. 8438 if (value.IsEmpty()) { 8439 isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value()); 8440 } else { 8441 isolate->ScheduleThrow(*Utils::OpenHandle(*value)); 8442 } 8443 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 8444 } 8445 AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8446 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data, 8447 GCType gc_type) { 8448 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8449 isolate->heap()->AddGCPrologueCallback(callback, gc_type, data); 8450 } 8451 RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8452 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback, 8453 void* data) { 8454 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8455 isolate->heap()->RemoveGCPrologueCallback(callback, data); 8456 } 8457 AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8458 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data, 8459 GCType gc_type) { 8460 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8461 isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data); 8462 } 8463 RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8464 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback, 8465 void* data) { 8466 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8467 isolate->heap()->RemoveGCEpilogueCallback(callback, data); 8468 } 8469 CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8470 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type, 8471 GCCallbackFlags flags, void* data) { 8472 reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags); 8473 } 8474 AddGCPrologueCallback(GCCallback callback,GCType gc_type)8475 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) { 8476 void* data = reinterpret_cast<void*>(callback); 8477 AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type); 8478 } 8479 RemoveGCPrologueCallback(GCCallback callback)8480 void Isolate::RemoveGCPrologueCallback(GCCallback callback) { 8481 void* data = reinterpret_cast<void*>(callback); 8482 RemoveGCPrologueCallback(CallGCCallbackWithoutData, data); 8483 } 8484 AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8485 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) { 8486 void* data = reinterpret_cast<void*>(callback); 8487 AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type); 8488 } 8489 RemoveGCEpilogueCallback(GCCallback callback)8490 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) { 8491 void* data = reinterpret_cast<void*>(callback); 8492 RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data); 8493 } 8494 SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8495 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { 8496 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8497 CHECK_NULL(isolate->heap()->cpp_heap()); 8498 isolate->heap()->SetEmbedderHeapTracer(tracer); 8499 } 8500 GetEmbedderHeapTracer()8501 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() { 8502 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8503 return isolate->heap()->GetEmbedderHeapTracer(); 8504 } 8505 SetEmbedderRootsHandler(EmbedderRootsHandler * handler)8506 void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) { 8507 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8508 isolate->heap()->SetEmbedderRootsHandler(handler); 8509 } 8510 AttachCppHeap(CppHeap * cpp_heap)8511 void Isolate::AttachCppHeap(CppHeap* cpp_heap) { 8512 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8513 CHECK_NULL(GetEmbedderHeapTracer()); 8514 isolate->heap()->AttachCppHeap(cpp_heap); 8515 } 8516 DetachCppHeap()8517 void Isolate::DetachCppHeap() { 8518 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8519 isolate->heap()->DetachCppHeap(); 8520 } 8521 GetCppHeap() const8522 CppHeap* Isolate::GetCppHeap() const { 8523 const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this); 8524 return isolate->heap()->cpp_heap(); 8525 } 8526 SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8527 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback( 8528 GetExternallyAllocatedMemoryInBytesCallback callback) { 8529 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8530 isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback); 8531 } 8532 TerminateExecution()8533 void Isolate::TerminateExecution() { 8534 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8535 isolate->stack_guard()->RequestTerminateExecution(); 8536 } 8537 IsExecutionTerminating()8538 bool Isolate::IsExecutionTerminating() { 8539 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8540 return IsExecutionTerminatingCheck(isolate); 8541 } 8542 CancelTerminateExecution()8543 void Isolate::CancelTerminateExecution() { 8544 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8545 isolate->stack_guard()->ClearTerminateExecution(); 8546 isolate->CancelTerminateExecution(); 8547 } 8548 RequestInterrupt(InterruptCallback callback,void * data)8549 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) { 8550 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8551 isolate->RequestInterrupt(callback, data); 8552 } 8553 HasPendingBackgroundTasks()8554 bool Isolate::HasPendingBackgroundTasks() { 8555 #if V8_ENABLE_WEBASSEMBLY 8556 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8557 return i::wasm::GetWasmEngine()->HasRunningCompileJob(isolate); 8558 #else 8559 return false; 8560 #endif // V8_ENABLE_WEBASSEMBLY 8561 } 8562 RequestGarbageCollectionForTesting(GarbageCollectionType type)8563 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) { 8564 Utils::ApiCheck(i::FLAG_expose_gc, 8565 "v8::Isolate::RequestGarbageCollectionForTesting", 8566 "Must use --expose-gc"); 8567 if (type == kMinorGarbageCollection) { 8568 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage( 8569 i::NEW_SPACE, i::GarbageCollectionReason::kTesting, 8570 kGCCallbackFlagForced); 8571 } else { 8572 DCHECK_EQ(kFullGarbageCollection, type); 8573 reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage( 8574 i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting, 8575 kGCCallbackFlagForced); 8576 } 8577 } 8578 RequestGarbageCollectionForTesting(GarbageCollectionType type,EmbedderHeapTracer::EmbedderStackState stack_state)8579 void Isolate::RequestGarbageCollectionForTesting( 8580 GarbageCollectionType type, 8581 EmbedderHeapTracer::EmbedderStackState stack_state) { 8582 base::Optional<i::EmbedderStackStateScope> stack_scope; 8583 if (type == kFullGarbageCollection) { 8584 stack_scope.emplace(reinterpret_cast<i::Isolate*>(this)->heap(), 8585 i::EmbedderStackStateScope::kExplicitInvocation, 8586 stack_state); 8587 } 8588 RequestGarbageCollectionForTesting(type); 8589 } 8590 GetCurrent()8591 Isolate* Isolate::GetCurrent() { 8592 i::Isolate* isolate = i::Isolate::Current(); 8593 return reinterpret_cast<Isolate*>(isolate); 8594 } 8595 TryGetCurrent()8596 Isolate* Isolate::TryGetCurrent() { 8597 i::Isolate* isolate = i::Isolate::TryGetCurrent(); 8598 return reinterpret_cast<Isolate*>(isolate); 8599 } 8600 IsCurrent() const8601 bool Isolate::IsCurrent() const { 8602 return reinterpret_cast<const i::Isolate*>(this)->IsCurrent(); 8603 } 8604 8605 // static Allocate()8606 Isolate* Isolate::Allocate() { 8607 return reinterpret_cast<Isolate*>(i::Isolate::New()); 8608 } 8609 8610 Isolate::CreateParams::CreateParams() = default; 8611 8612 Isolate::CreateParams::~CreateParams() = default; 8613 8614 // static 8615 // This is separate so that tests can provide a different |isolate|. Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8616 void Isolate::Initialize(Isolate* isolate, 8617 const v8::Isolate::CreateParams& params) { 8618 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8619 TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.IsolateInitialize"); 8620 if (auto allocator = params.array_buffer_allocator_shared) { 8621 CHECK(params.array_buffer_allocator == nullptr || 8622 params.array_buffer_allocator == allocator.get()); 8623 i_isolate->set_array_buffer_allocator(allocator.get()); 8624 i_isolate->set_array_buffer_allocator_shared(std::move(allocator)); 8625 } else { 8626 CHECK_NOT_NULL(params.array_buffer_allocator); 8627 i_isolate->set_array_buffer_allocator(params.array_buffer_allocator); 8628 } 8629 if (params.snapshot_blob != nullptr) { 8630 i_isolate->set_snapshot_blob(params.snapshot_blob); 8631 } else { 8632 i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob()); 8633 } 8634 8635 if (params.fatal_error_callback) { 8636 isolate->SetFatalErrorHandler(params.fatal_error_callback); 8637 } 8638 8639 if (params.oom_error_callback) { 8640 isolate->SetOOMErrorHandler(params.oom_error_callback); 8641 } 8642 8643 if (params.counter_lookup_callback) { 8644 isolate->SetCounterFunction(params.counter_lookup_callback); 8645 } 8646 8647 if (params.create_histogram_callback) { 8648 isolate->SetCreateHistogramFunction(params.create_histogram_callback); 8649 } 8650 8651 if (params.add_histogram_sample_callback) { 8652 isolate->SetAddHistogramSampleFunction( 8653 params.add_histogram_sample_callback); 8654 } 8655 8656 i_isolate->set_api_external_references(params.external_references); 8657 i_isolate->set_allow_atomics_wait(params.allow_atomics_wait); 8658 8659 i_isolate->heap()->ConfigureHeap(params.constraints); 8660 if (params.constraints.stack_limit() != nullptr) { 8661 uintptr_t limit = 8662 reinterpret_cast<uintptr_t>(params.constraints.stack_limit()); 8663 i_isolate->stack_guard()->SetStackLimit(limit); 8664 } 8665 8666 if (params.experimental_attach_to_shared_isolate != nullptr) { 8667 i_isolate->set_shared_isolate(reinterpret_cast<i::Isolate*>( 8668 params.experimental_attach_to_shared_isolate)); 8669 } 8670 8671 // TODO(v8:2487): Once we got rid of Isolate::Current(), we can remove this. 8672 Isolate::Scope isolate_scope(isolate); 8673 if (i_isolate->snapshot_blob() == nullptr) { 8674 FATAL( 8675 "V8 snapshot blob was not set during initialization. This can mean " 8676 "that the snapshot blob file is corrupted or missing."); 8677 } 8678 if (!i::Snapshot::Initialize(i_isolate)) { 8679 // If snapshot data was provided and we failed to deserialize it must 8680 // have been corrupted. 8681 FATAL( 8682 "Failed to deserialize the V8 snapshot blob. This can mean that the " 8683 "snapshot blob file is corrupted or missing."); 8684 } 8685 8686 { 8687 // Set up code event handlers. Needs to be after i::Snapshot::Initialize 8688 // because that is where we add the isolate to WasmEngine. 8689 auto code_event_handler = params.code_event_handler; 8690 if (code_event_handler) { 8691 isolate->SetJitCodeEventHandler(kJitCodeEventEnumExisting, 8692 code_event_handler); 8693 } 8694 } 8695 8696 i_isolate->set_only_terminate_in_safe_scope( 8697 params.only_terminate_in_safe_scope); 8698 i_isolate->set_embedder_wrapper_type_index( 8699 params.embedder_wrapper_type_index); 8700 i_isolate->set_embedder_wrapper_object_index( 8701 params.embedder_wrapper_object_index); 8702 8703 if (!i::V8::GetCurrentPlatform() 8704 ->GetForegroundTaskRunner(isolate) 8705 ->NonNestableTasksEnabled()) { 8706 FATAL( 8707 "The current platform's foreground task runner does not have " 8708 "non-nestable tasks enabled. The embedder must provide one."); 8709 } 8710 } 8711 New(const Isolate::CreateParams & params)8712 Isolate* Isolate::New(const Isolate::CreateParams& params) { 8713 Isolate* isolate = Allocate(); 8714 Initialize(isolate, params); 8715 return isolate; 8716 } 8717 Dispose()8718 void Isolate::Dispose() { 8719 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8720 if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()", 8721 "Disposing the isolate that is entered by a thread.")) { 8722 return; 8723 } 8724 i::Isolate::Delete(isolate); 8725 } 8726 DumpAndResetStats()8727 void Isolate::DumpAndResetStats() { 8728 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8729 isolate->DumpAndResetStats(); 8730 } 8731 DiscardThreadSpecificMetadata()8732 void Isolate::DiscardThreadSpecificMetadata() { 8733 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8734 isolate->DiscardPerThreadDataForThisThread(); 8735 } 8736 Enter()8737 void Isolate::Enter() { 8738 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8739 isolate->Enter(); 8740 } 8741 Exit()8742 void Isolate::Exit() { 8743 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8744 isolate->Exit(); 8745 } 8746 SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8747 void Isolate::SetAbortOnUncaughtExceptionCallback( 8748 AbortOnUncaughtExceptionCallback callback) { 8749 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8750 isolate->SetAbortOnUncaughtExceptionCallback(callback); 8751 } 8752 SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyWithImportAssertionsCallback callback)8753 void Isolate::SetHostImportModuleDynamicallyCallback( 8754 HostImportModuleDynamicallyWithImportAssertionsCallback callback) { 8755 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8756 isolate->SetHostImportModuleDynamicallyCallback(callback); 8757 } 8758 SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8759 void Isolate::SetHostImportModuleDynamicallyCallback( 8760 HostImportModuleDynamicallyCallback callback) { 8761 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8762 isolate->SetHostImportModuleDynamicallyCallback(callback); 8763 } 8764 SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8765 void Isolate::SetHostInitializeImportMetaObjectCallback( 8766 HostInitializeImportMetaObjectCallback callback) { 8767 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8768 isolate->SetHostInitializeImportMetaObjectCallback(callback); 8769 } 8770 SetHostCreateShadowRealmContextCallback(HostCreateShadowRealmContextCallback callback)8771 void Isolate::SetHostCreateShadowRealmContextCallback( 8772 HostCreateShadowRealmContextCallback callback) { 8773 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8774 isolate->SetHostCreateShadowRealmContextCallback(callback); 8775 } 8776 SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8777 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) { 8778 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8779 isolate->SetPrepareStackTraceCallback(callback); 8780 } 8781 DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8782 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( 8783 Isolate* isolate, 8784 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) 8785 : on_failure_(on_failure), isolate_(isolate) { 8786 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8787 switch (on_failure_) { 8788 case CRASH_ON_FAILURE: 8789 i::DisallowJavascriptExecution::Open(i_isolate, 8790 &was_execution_allowed_assert_); 8791 break; 8792 case THROW_ON_FAILURE: 8793 i::ThrowOnJavascriptExecution::Open(i_isolate, 8794 &was_execution_allowed_throws_); 8795 break; 8796 case DUMP_ON_FAILURE: 8797 i::DumpOnJavascriptExecution::Open(i_isolate, 8798 &was_execution_allowed_dump_); 8799 break; 8800 default: 8801 UNREACHABLE(); 8802 } 8803 } 8804 ~DisallowJavascriptExecutionScope()8805 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() { 8806 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_); 8807 switch (on_failure_) { 8808 case CRASH_ON_FAILURE: 8809 i::DisallowJavascriptExecution::Close(i_isolate, 8810 was_execution_allowed_assert_); 8811 break; 8812 case THROW_ON_FAILURE: 8813 i::ThrowOnJavascriptExecution::Close(i_isolate, 8814 was_execution_allowed_throws_); 8815 break; 8816 case DUMP_ON_FAILURE: 8817 i::DumpOnJavascriptExecution::Close(i_isolate, 8818 was_execution_allowed_dump_); 8819 break; 8820 default: 8821 UNREACHABLE(); 8822 } 8823 } 8824 AllowJavascriptExecutionScope(Isolate * isolate)8825 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope( 8826 Isolate* isolate) 8827 : isolate_(isolate) { 8828 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8829 i::AllowJavascriptExecution::Open(i_isolate, &was_execution_allowed_assert_); 8830 i::NoThrowOnJavascriptExecution::Open(i_isolate, 8831 &was_execution_allowed_throws_); 8832 i::NoDumpOnJavascriptExecution::Open(i_isolate, &was_execution_allowed_dump_); 8833 } 8834 ~AllowJavascriptExecutionScope()8835 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() { 8836 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_); 8837 i::AllowJavascriptExecution::Close(i_isolate, was_execution_allowed_assert_); 8838 i::NoThrowOnJavascriptExecution::Close(i_isolate, 8839 was_execution_allowed_throws_); 8840 i::NoDumpOnJavascriptExecution::Close(i_isolate, was_execution_allowed_dump_); 8841 } 8842 SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8843 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope( 8844 Isolate* isolate, MicrotaskQueue* microtask_queue) 8845 : isolate_(reinterpret_cast<i::Isolate*>(isolate)), 8846 microtask_queue_(microtask_queue 8847 ? static_cast<i::MicrotaskQueue*>(microtask_queue) 8848 : isolate_->default_microtask_queue()) { 8849 isolate_->thread_local_top()->IncrementCallDepth(this); 8850 microtask_queue_->IncrementMicrotasksSuppressions(); 8851 } 8852 ~SuppressMicrotaskExecutionScope()8853 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() { 8854 microtask_queue_->DecrementMicrotasksSuppressions(); 8855 isolate_->thread_local_top()->DecrementCallDepth(this); 8856 } 8857 SafeForTerminationScope(v8::Isolate * isolate)8858 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate) 8859 : isolate_(reinterpret_cast<i::Isolate*>(isolate)), 8860 prev_value_(isolate_->next_v8_call_is_safe_for_termination()) { 8861 isolate_->set_next_v8_call_is_safe_for_termination(true); 8862 } 8863 ~SafeForTerminationScope()8864 Isolate::SafeForTerminationScope::~SafeForTerminationScope() { 8865 isolate_->set_next_v8_call_is_safe_for_termination(prev_value_); 8866 } 8867 GetDataFromSnapshotOnce(size_t index)8868 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) { 8869 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this); 8870 i::FixedArray list = i_isolate->heap()->serialized_objects(); 8871 return GetSerializedDataFromFixedArray(i_isolate, list, index); 8872 } 8873 GetHeapStatistics(HeapStatistics * heap_statistics)8874 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { 8875 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8876 i::Heap* heap = isolate->heap(); 8877 8878 // The order of acquiring memory statistics is important here. We query in 8879 // this order because of concurrent allocation: 1) used memory 2) comitted 8880 // physical memory 3) committed memory. Therefore the condition used <= 8881 // committed physical <= committed should hold. 8882 heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize(); 8883 heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize(); 8884 DCHECK_LE(heap_statistics->used_global_handles_size_, 8885 heap_statistics->total_global_handles_size_); 8886 8887 heap_statistics->used_heap_size_ = heap->SizeOfObjects(); 8888 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory(); 8889 heap_statistics->total_heap_size_ = heap->CommittedMemory(); 8890 8891 heap_statistics->total_available_size_ = heap->Available(); 8892 8893 if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) { 8894 i::ReadOnlySpace* ro_space = heap->read_only_space(); 8895 heap_statistics->used_heap_size_ += ro_space->Size(); 8896 heap_statistics->total_physical_size_ += 8897 ro_space->CommittedPhysicalMemory(); 8898 heap_statistics->total_heap_size_ += ro_space->CommittedMemory(); 8899 } 8900 8901 // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix 8902 // this and add DCHECK. 8903 DCHECK_LE(heap_statistics->used_heap_size_, 8904 heap_statistics->total_heap_size_); 8905 8906 heap_statistics->total_heap_size_executable_ = 8907 heap->CommittedMemoryExecutable(); 8908 heap_statistics->heap_size_limit_ = heap->MaxReserved(); 8909 // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an 8910 // API becomes available we should report the malloced memory separately. For 8911 // now we just add the values, thereby over-approximating the peak slightly. 8912 heap_statistics->malloced_memory_ = 8913 isolate->allocator()->GetCurrentMemoryUsage() + 8914 isolate->string_table()->GetCurrentMemoryUsage(); 8915 // On 32-bit systems backing_store_bytes() might overflow size_t temporarily 8916 // due to concurrent array buffer sweeping. 8917 heap_statistics->external_memory_ = 8918 isolate->heap()->backing_store_bytes() < SIZE_MAX 8919 ? static_cast<size_t>(isolate->heap()->backing_store_bytes()) 8920 : SIZE_MAX; 8921 heap_statistics->peak_malloced_memory_ = 8922 isolate->allocator()->GetMaxMemoryUsage(); 8923 heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts(); 8924 heap_statistics->number_of_detached_contexts_ = 8925 heap->NumberOfDetachedContexts(); 8926 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage(); 8927 8928 #if V8_ENABLE_WEBASSEMBLY 8929 heap_statistics->malloced_memory_ += 8930 i::wasm::GetWasmEngine()->allocator()->GetCurrentMemoryUsage(); 8931 heap_statistics->peak_malloced_memory_ += 8932 i::wasm::GetWasmEngine()->allocator()->GetMaxMemoryUsage(); 8933 #endif // V8_ENABLE_WEBASSEMBLY 8934 } 8935 NumberOfHeapSpaces()8936 size_t Isolate::NumberOfHeapSpaces() { 8937 return i::LAST_SPACE - i::FIRST_SPACE + 1; 8938 } 8939 GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8940 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics, 8941 size_t index) { 8942 if (!space_statistics) return false; 8943 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index))) 8944 return false; 8945 8946 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8947 i::Heap* heap = isolate->heap(); 8948 8949 i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index); 8950 space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space); 8951 8952 if (allocation_space == i::RO_SPACE) { 8953 if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) { 8954 // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared. 8955 space_statistics->space_size_ = 0; 8956 space_statistics->space_used_size_ = 0; 8957 space_statistics->space_available_size_ = 0; 8958 space_statistics->physical_space_size_ = 0; 8959 } else { 8960 i::ReadOnlySpace* space = heap->read_only_space(); 8961 space_statistics->space_size_ = space->CommittedMemory(); 8962 space_statistics->space_used_size_ = space->Size(); 8963 space_statistics->space_available_size_ = 0; 8964 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory(); 8965 } 8966 } else { 8967 i::Space* space = heap->space(static_cast<int>(index)); 8968 space_statistics->space_size_ = space ? space->CommittedMemory() : 0; 8969 space_statistics->space_used_size_ = space ? space->SizeOfObjects() : 0; 8970 space_statistics->space_available_size_ = space ? space->Available() : 0; 8971 space_statistics->physical_space_size_ = 8972 space ? space->CommittedPhysicalMemory() : 0; 8973 } 8974 return true; 8975 } 8976 NumberOfTrackedHeapObjectTypes()8977 size_t Isolate::NumberOfTrackedHeapObjectTypes() { 8978 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8979 i::Heap* heap = isolate->heap(); 8980 return heap->NumberOfTrackedHeapObjectTypes(); 8981 } 8982 GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8983 bool Isolate::GetHeapObjectStatisticsAtLastGC( 8984 HeapObjectStatistics* object_statistics, size_t type_index) { 8985 if (!object_statistics) return false; 8986 if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false; 8987 8988 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 8989 i::Heap* heap = isolate->heap(); 8990 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false; 8991 8992 const char* object_type; 8993 const char* object_sub_type; 8994 size_t object_count = heap->ObjectCountAtLastGC(type_index); 8995 size_t object_size = heap->ObjectSizeAtLastGC(type_index); 8996 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) { 8997 // There should be no objects counted when the type is unknown. 8998 DCHECK_EQ(object_count, 0U); 8999 DCHECK_EQ(object_size, 0U); 9000 return false; 9001 } 9002 9003 object_statistics->object_type_ = object_type; 9004 object_statistics->object_sub_type_ = object_sub_type; 9005 object_statistics->object_count_ = object_count; 9006 object_statistics->object_size_ = object_size; 9007 return true; 9008 } 9009 GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)9010 bool Isolate::GetHeapCodeAndMetadataStatistics( 9011 HeapCodeStatistics* code_statistics) { 9012 if (!code_statistics) return false; 9013 9014 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9015 isolate->heap()->CollectCodeStatistics(); 9016 9017 code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size(); 9018 code_statistics->bytecode_and_metadata_size_ = 9019 isolate->bytecode_and_metadata_size(); 9020 code_statistics->external_script_source_size_ = 9021 isolate->external_script_source_size(); 9022 code_statistics->cpu_profiler_metadata_size_ = 9023 i::CpuProfiler::GetAllProfilersMemorySize( 9024 reinterpret_cast<i::Isolate*>(isolate)); 9025 9026 return true; 9027 } 9028 MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)9029 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate, 9030 MeasureMemoryExecution execution) { 9031 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9032 return isolate->heap()->MeasureMemory(std::move(delegate), execution); 9033 } 9034 Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)9035 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default( 9036 Isolate* isolate, Local<Context> context, 9037 Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) { 9038 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 9039 i::Handle<i::NativeContext> native_context = 9040 handle(Utils::OpenHandle(*context)->native_context(), i_isolate); 9041 i::Handle<i::JSPromise> js_promise = 9042 i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver)); 9043 return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise, 9044 mode); 9045 } 9046 GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)9047 void Isolate::GetStackSample(const RegisterState& state, void** frames, 9048 size_t frames_limit, SampleInfo* sample_info) { 9049 RegisterState regs = state; 9050 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9051 if (i::TickSample::GetStackSample(isolate, ®s, 9052 i::TickSample::kSkipCEntryFrame, frames, 9053 frames_limit, sample_info)) { 9054 return; 9055 } 9056 sample_info->frames_count = 0; 9057 sample_info->vm_state = OTHER; 9058 sample_info->external_callback_entry = nullptr; 9059 } 9060 NumberOfPhantomHandleResetsSinceLastCall()9061 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() { 9062 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9063 return isolate->global_handles()->GetAndResetGlobalHandleResetCount(); 9064 } 9065 AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)9066 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( 9067 int64_t change_in_bytes) { 9068 // Try to check for unreasonably large or small values from the embedder. 9069 const int64_t kMaxReasonableBytes = int64_t(1) << 60; 9070 const int64_t kMinReasonableBytes = -kMaxReasonableBytes; 9071 STATIC_ASSERT(kMaxReasonableBytes >= i::JSArrayBuffer::kMaxByteLength); 9072 9073 CHECK(kMinReasonableBytes <= change_in_bytes && 9074 change_in_bytes < kMaxReasonableBytes); 9075 9076 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this); 9077 int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes); 9078 9079 if (change_in_bytes <= 0) return amount; 9080 9081 if (amount > i_isolate->heap()->external_memory_limit()) { 9082 ReportExternalAllocationLimitReached(); 9083 } 9084 return amount; 9085 } 9086 SetEventLogger(LogEventCallback that)9087 void Isolate::SetEventLogger(LogEventCallback that) { 9088 // Do not overwrite the event logger if we want to log explicitly. 9089 if (i::FLAG_log_internal_timer_events) return; 9090 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9091 isolate->set_event_logger(that); 9092 } 9093 AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9094 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) { 9095 if (callback == nullptr) return; 9096 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9097 isolate->AddBeforeCallEnteredCallback(callback); 9098 } 9099 RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)9100 void Isolate::RemoveBeforeCallEnteredCallback( 9101 BeforeCallEnteredCallback callback) { 9102 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9103 isolate->RemoveBeforeCallEnteredCallback(callback); 9104 } 9105 AddCallCompletedCallback(CallCompletedCallback callback)9106 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) { 9107 if (callback == nullptr) return; 9108 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9109 isolate->AddCallCompletedCallback(callback); 9110 } 9111 RemoveCallCompletedCallback(CallCompletedCallback callback)9112 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) { 9113 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9114 isolate->RemoveCallCompletedCallback(callback); 9115 } 9116 Wake()9117 void Isolate::AtomicsWaitWakeHandle::Wake() { 9118 reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake(); 9119 } 9120 SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)9121 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) { 9122 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9123 isolate->SetAtomicsWaitCallback(callback, data); 9124 } 9125 SetPromiseHook(PromiseHook hook)9126 void Isolate::SetPromiseHook(PromiseHook hook) { 9127 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9128 isolate->SetPromiseHook(hook); 9129 } 9130 SetPromiseRejectCallback(PromiseRejectCallback callback)9131 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { 9132 if (callback == nullptr) return; 9133 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9134 isolate->SetPromiseRejectCallback(callback); 9135 } 9136 PerformMicrotaskCheckpoint()9137 void Isolate::PerformMicrotaskCheckpoint() { 9138 DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy()); 9139 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9140 isolate->default_microtask_queue()->PerformCheckpoint(this); 9141 } 9142 EnqueueMicrotask(Local<Function> v8_function)9143 void Isolate::EnqueueMicrotask(Local<Function> v8_function) { 9144 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9145 i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function); 9146 i::Handle<i::NativeContext> handler_context; 9147 if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle( 9148 &handler_context)) 9149 handler_context = isolate->native_context(); 9150 MicrotaskQueue* microtask_queue = handler_context->microtask_queue(); 9151 if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function); 9152 } 9153 EnqueueMicrotask(MicrotaskCallback callback,void * data)9154 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) { 9155 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9156 isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data); 9157 } 9158 SetMicrotasksPolicy(MicrotasksPolicy policy)9159 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) { 9160 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9161 isolate->default_microtask_queue()->set_microtasks_policy(policy); 9162 } 9163 GetMicrotasksPolicy() const9164 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const { 9165 i::Isolate* isolate = 9166 reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this)); 9167 return isolate->default_microtask_queue()->microtasks_policy(); 9168 } 9169 AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9170 void Isolate::AddMicrotasksCompletedCallback( 9171 MicrotasksCompletedCallbackWithData callback, void* data) { 9172 DCHECK(callback); 9173 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9174 isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback, 9175 data); 9176 } 9177 RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)9178 void Isolate::RemoveMicrotasksCompletedCallback( 9179 MicrotasksCompletedCallbackWithData callback, void* data) { 9180 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9181 isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback( 9182 callback, data); 9183 } 9184 SetUseCounterCallback(UseCounterCallback callback)9185 void Isolate::SetUseCounterCallback(UseCounterCallback callback) { 9186 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback); 9187 } 9188 SetCounterFunction(CounterLookupCallback callback)9189 void Isolate::SetCounterFunction(CounterLookupCallback callback) { 9190 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9191 isolate->counters()->ResetCounterFunction(callback); 9192 } 9193 SetCreateHistogramFunction(CreateHistogramCallback callback)9194 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) { 9195 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9196 isolate->counters()->ResetCreateHistogramFunction(callback); 9197 } 9198 SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)9199 void Isolate::SetAddHistogramSampleFunction( 9200 AddHistogramSampleCallback callback) { 9201 reinterpret_cast<i::Isolate*>(this) 9202 ->counters() 9203 ->SetAddHistogramSampleFunction(callback); 9204 } 9205 SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)9206 void Isolate::SetMetricsRecorder( 9207 const std::shared_ptr<metrics::Recorder>& metrics_recorder) { 9208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9209 isolate->metrics_recorder()->SetEmbedderRecorder(isolate, metrics_recorder); 9210 } 9211 SetAddCrashKeyCallback(AddCrashKeyCallback callback)9212 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) { 9213 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9214 isolate->SetAddCrashKeyCallback(callback); 9215 } 9216 IdleNotificationDeadline(double deadline_in_seconds)9217 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) { 9218 // Returning true tells the caller that it need not 9219 // continue to call IdleNotification. 9220 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9221 if (!i::FLAG_use_idle_notification) return true; 9222 return isolate->heap()->IdleNotification(deadline_in_seconds); 9223 } 9224 LowMemoryNotification()9225 void Isolate::LowMemoryNotification() { 9226 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9227 { 9228 i::NestedTimedHistogramScope idle_notification_scope( 9229 isolate->counters()->gc_low_memory_notification()); 9230 TRACE_EVENT0("v8", "V8.GCLowMemoryNotification"); 9231 isolate->heap()->CollectAllAvailableGarbage( 9232 i::GarbageCollectionReason::kLowMemoryNotification); 9233 } 9234 } 9235 ContextDisposedNotification(bool dependant_context)9236 int Isolate::ContextDisposedNotification(bool dependant_context) { 9237 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9238 #if V8_ENABLE_WEBASSEMBLY 9239 if (!dependant_context) { 9240 if (!isolate->context().is_null()) { 9241 // We left the current context, we can abort all WebAssembly compilations 9242 // of that context. 9243 // A handle scope for the native context. 9244 i::HandleScope handle_scope(isolate); 9245 i::wasm::GetWasmEngine()->DeleteCompileJobsOnContext( 9246 isolate->native_context()); 9247 } 9248 } 9249 #endif // V8_ENABLE_WEBASSEMBLY 9250 // TODO(ahaas): move other non-heap activity out of the heap call. 9251 return isolate->heap()->NotifyContextDisposed(dependant_context); 9252 } 9253 IsolateInForegroundNotification()9254 void Isolate::IsolateInForegroundNotification() { 9255 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9256 return isolate->IsolateInForegroundNotification(); 9257 } 9258 IsolateInBackgroundNotification()9259 void Isolate::IsolateInBackgroundNotification() { 9260 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9261 return isolate->IsolateInBackgroundNotification(); 9262 } 9263 MemoryPressureNotification(MemoryPressureLevel level)9264 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) { 9265 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9266 bool on_isolate_thread = 9267 isolate->was_locker_ever_used() 9268 ? isolate->thread_manager()->IsLockedByCurrentThread() 9269 : i::ThreadId::Current() == isolate->thread_id(); 9270 isolate->heap()->MemoryPressureNotification(level, on_isolate_thread); 9271 } 9272 ClearCachesForTesting()9273 void Isolate::ClearCachesForTesting() { 9274 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9275 isolate->AbortConcurrentOptimization(i::BlockingBehavior::kBlock); 9276 isolate->ClearSerializerData(); 9277 } 9278 EnableMemorySavingsMode()9279 void Isolate::EnableMemorySavingsMode() { 9280 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9281 isolate->EnableMemorySavingsMode(); 9282 } 9283 DisableMemorySavingsMode()9284 void Isolate::DisableMemorySavingsMode() { 9285 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9286 isolate->DisableMemorySavingsMode(); 9287 } 9288 SetRAILMode(RAILMode rail_mode)9289 void Isolate::SetRAILMode(RAILMode rail_mode) { 9290 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9291 return isolate->SetRAILMode(rail_mode); 9292 } 9293 UpdateLoadStartTime()9294 void Isolate::UpdateLoadStartTime() { 9295 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9296 isolate->UpdateLoadStartTime(); 9297 } 9298 IncreaseHeapLimitForDebugging()9299 void Isolate::IncreaseHeapLimitForDebugging() { 9300 // No-op. 9301 } 9302 RestoreOriginalHeapLimit()9303 void Isolate::RestoreOriginalHeapLimit() { 9304 // No-op. 9305 } 9306 IsHeapLimitIncreasedForDebugging()9307 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; } 9308 SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)9309 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options, 9310 JitCodeEventHandler event_handler) { 9311 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9312 // Ensure that logging is initialized for our isolate. 9313 isolate->InitializeLoggingAndCounters(); 9314 isolate->logger()->SetCodeEventHandler(options, event_handler); 9315 } 9316 SetStackLimit(uintptr_t stack_limit)9317 void Isolate::SetStackLimit(uintptr_t stack_limit) { 9318 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9319 CHECK(stack_limit); 9320 isolate->stack_guard()->SetStackLimit(stack_limit); 9321 } 9322 GetCodeRange(void ** start,size_t * length_in_bytes)9323 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) { 9324 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9325 const base::AddressRegion& code_region = isolate->heap()->code_region(); 9326 *start = reinterpret_cast<void*>(code_region.begin()); 9327 *length_in_bytes = code_region.size(); 9328 } 9329 GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9330 void Isolate::GetEmbeddedCodeRange(const void** start, 9331 size_t* length_in_bytes) { 9332 // Note, we should return the embedded code rande from the .text section here. 9333 i::EmbeddedData d = i::EmbeddedData::FromBlob(); 9334 *start = reinterpret_cast<const void*>(d.code()); 9335 *length_in_bytes = d.code_size(); 9336 } 9337 GetJSEntryStubs()9338 JSEntryStubs Isolate::GetJSEntryStubs() { 9339 JSEntryStubs entry_stubs; 9340 9341 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9342 std::array<std::pair<i::Builtin, JSEntryStub*>, 3> stubs = { 9343 {{i::Builtin::kJSEntry, &entry_stubs.js_entry_stub}, 9344 {i::Builtin::kJSConstructEntry, &entry_stubs.js_construct_entry_stub}, 9345 {i::Builtin::kJSRunMicrotasksEntry, 9346 &entry_stubs.js_run_microtasks_entry_stub}}}; 9347 for (auto& pair : stubs) { 9348 i::Code js_entry = FromCodeT(isolate->builtins()->code(pair.first)); 9349 pair.second->code.start = 9350 reinterpret_cast<const void*>(js_entry.InstructionStart()); 9351 pair.second->code.length_in_bytes = js_entry.InstructionSize(); 9352 } 9353 9354 return entry_stubs; 9355 } 9356 CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9357 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) { 9358 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM) 9359 // Not implemented on other platforms. 9360 UNREACHABLE(); 9361 #else 9362 9363 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9364 std::vector<MemoryRange>* code_pages = isolate->GetCodePages(); 9365 9366 DCHECK_NOT_NULL(code_pages); 9367 9368 // Copy as many elements into the output vector as we can. If the 9369 // caller-provided buffer is not big enough, we fill it, and the caller can 9370 // provide a bigger one next time. We do it this way because allocation is not 9371 // allowed in signal handlers. 9372 size_t limit = std::min(capacity, code_pages->size()); 9373 for (size_t i = 0; i < limit; i++) { 9374 code_pages_out[i] = code_pages->at(i); 9375 } 9376 return code_pages->size(); 9377 #endif 9378 } 9379 9380 #define CALLBACK_SETTER(ExternalName, Type, InternalName) \ 9381 void Isolate::Set##ExternalName(Type callback) { \ 9382 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \ 9383 isolate->set_##InternalName(callback); \ 9384 } 9385 CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9386 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior) 9387 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior) 9388 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback, 9389 ModifyCodeGenerationFromStringsCallback2, 9390 modify_code_gen_callback2) 9391 CALLBACK_SETTER(AllowWasmCodeGenerationCallback, 9392 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback) 9393 9394 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback) 9395 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback) 9396 9397 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback, 9398 wasm_streaming_callback) 9399 9400 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback, 9401 wasm_load_source_map_callback) 9402 9403 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback, 9404 wasm_simd_enabled_callback) 9405 9406 CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback, 9407 wasm_exceptions_enabled_callback) 9408 9409 CALLBACK_SETTER(WasmDynamicTieringEnabledCallback, 9410 WasmDynamicTieringEnabledCallback, 9411 wasm_dynamic_tiering_enabled_callback) 9412 9413 CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback, 9414 SharedArrayBufferConstructorEnabledCallback, 9415 sharedarraybuffer_constructor_enabled_callback) 9416 9417 void Isolate::InstallConditionalFeatures(Local<Context> context) { 9418 v8::HandleScope handle_scope(this); 9419 v8::Context::Scope context_scope(context); 9420 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9421 isolate->InstallConditionalFeatures(Utils::OpenHandle(*context)); 9422 #if V8_ENABLE_WEBASSEMBLY 9423 if (i::FLAG_expose_wasm) { 9424 i::WasmJs::InstallConditionalFeatures(isolate, Utils::OpenHandle(*context)); 9425 } 9426 #endif // V8_ENABLE_WEBASSEMBLY 9427 } 9428 AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,void * data)9429 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback, 9430 void* data) { 9431 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9432 isolate->heap()->AddNearHeapLimitCallback(callback, data); 9433 } 9434 RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9435 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback, 9436 size_t heap_limit) { 9437 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9438 isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit); 9439 } 9440 AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9441 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) { 9442 DCHECK_GT(threshold_percent, 0.0); 9443 DCHECK_LT(threshold_percent, 1.0); 9444 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9445 isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent); 9446 } 9447 IsDead()9448 bool Isolate::IsDead() { 9449 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9450 return isolate->IsDead(); 9451 } 9452 AddMessageListener(MessageCallback that,Local<Value> data)9453 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) { 9454 return AddMessageListenerWithErrorLevel(that, kMessageError, data); 9455 } 9456 AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9457 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that, 9458 int message_levels, 9459 Local<Value> data) { 9460 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9461 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 9462 i::HandleScope scope(isolate); 9463 i::Handle<i::TemplateList> list = isolate->factory()->message_listeners(); 9464 i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3); 9465 i::Handle<i::Foreign> foreign = 9466 isolate->factory()->NewForeign(FUNCTION_ADDR(that)); 9467 listener->set(0, *foreign); 9468 listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value() 9469 : *Utils::OpenHandle(*data)); 9470 listener->set(2, i::Smi::FromInt(message_levels)); 9471 list = i::TemplateList::Add(isolate, list, listener); 9472 isolate->heap()->SetMessageListeners(*list); 9473 return true; 9474 } 9475 RemoveMessageListeners(MessageCallback that)9476 void Isolate::RemoveMessageListeners(MessageCallback that) { 9477 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9478 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 9479 i::HandleScope scope(isolate); 9480 i::DisallowGarbageCollection no_gc; 9481 i::TemplateList listeners = isolate->heap()->message_listeners(); 9482 for (int i = 0; i < listeners.length(); i++) { 9483 if (listeners.get(i).IsUndefined(isolate)) continue; // skip deleted ones 9484 i::FixedArray listener = i::FixedArray::cast(listeners.get(i)); 9485 i::Foreign callback_obj = i::Foreign::cast(listener.get(0)); 9486 if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) { 9487 listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value()); 9488 } 9489 } 9490 } 9491 SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9492 void Isolate::SetFailedAccessCheckCallbackFunction( 9493 FailedAccessCheckCallback callback) { 9494 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9495 isolate->SetFailedAccessCheckCallback(callback); 9496 } 9497 SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9498 void Isolate::SetCaptureStackTraceForUncaughtExceptions( 9499 bool capture, int frame_limit, StackTrace::StackTraceOptions options) { 9500 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9501 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit, 9502 options); 9503 } 9504 VisitExternalResources(ExternalResourceVisitor * visitor)9505 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) { 9506 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9507 isolate->heap()->VisitExternalResources(visitor); 9508 } 9509 IsInUse()9510 bool Isolate::IsInUse() { 9511 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9512 return isolate->IsInUse(); 9513 } 9514 VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9515 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) { 9516 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9517 i::DisallowGarbageCollection no_gc; 9518 isolate->global_handles()->IterateAllRootsWithClassIds(visitor); 9519 } 9520 VisitWeakHandles(PersistentHandleVisitor * visitor)9521 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { 9522 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9523 i::DisallowGarbageCollection no_gc; 9524 isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor); 9525 } 9526 SetAllowAtomicsWait(bool allow)9527 void Isolate::SetAllowAtomicsWait(bool allow) { 9528 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 9529 isolate->set_allow_atomics_wait(allow); 9530 } 9531 DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9532 void v8::Isolate::DateTimeConfigurationChangeNotification( 9533 TimeZoneDetection time_zone_detection) { 9534 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this); 9535 API_RCS_SCOPE(i_isolate, Isolate, DateTimeConfigurationChangeNotification); 9536 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 9537 i_isolate->date_cache()->ResetDateCache( 9538 static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection)); 9539 #ifdef V8_INTL_SUPPORT 9540 i_isolate->clear_cached_icu_object( 9541 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat); 9542 i_isolate->clear_cached_icu_object( 9543 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime); 9544 i_isolate->clear_cached_icu_object( 9545 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate); 9546 #endif // V8_INTL_SUPPORT 9547 } 9548 LocaleConfigurationChangeNotification()9549 void v8::Isolate::LocaleConfigurationChangeNotification() { 9550 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this); 9551 API_RCS_SCOPE(i_isolate, Isolate, LocaleConfigurationChangeNotification); 9552 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 9553 9554 #ifdef V8_INTL_SUPPORT 9555 i_isolate->ResetDefaultLocale(); 9556 #endif // V8_INTL_SUPPORT 9557 } 9558 IsCodeLike(v8::Isolate * isolate) const9559 bool v8::Object::IsCodeLike(v8::Isolate* isolate) const { 9560 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 9561 API_RCS_SCOPE(i_isolate, Object, IsCodeLike); 9562 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 9563 i::HandleScope scope(i_isolate); 9564 return Utils::OpenHandle(this)->IsCodeLike(i_isolate); 9565 } 9566 9567 // static New(Isolate * isolate,MicrotasksPolicy policy)9568 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate, 9569 MicrotasksPolicy policy) { 9570 auto microtask_queue = 9571 i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate)); 9572 microtask_queue->set_microtasks_policy(policy); 9573 std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue)); 9574 return ret; 9575 } 9576 MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9577 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type) 9578 : MicrotasksScope(isolate, nullptr, type) {} 9579 MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9580 MicrotasksScope::MicrotasksScope(Isolate* isolate, 9581 MicrotaskQueue* microtask_queue, 9582 MicrotasksScope::Type type) 9583 : isolate_(reinterpret_cast<i::Isolate*>(isolate)), 9584 microtask_queue_(microtask_queue 9585 ? static_cast<i::MicrotaskQueue*>(microtask_queue) 9586 : isolate_->default_microtask_queue()), 9587 run_(type == MicrotasksScope::kRunMicrotasks) { 9588 if (run_) microtask_queue_->IncrementMicrotasksScopeDepth(); 9589 #ifdef DEBUG 9590 if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth(); 9591 #endif 9592 } 9593 ~MicrotasksScope()9594 MicrotasksScope::~MicrotasksScope() { 9595 if (run_) { 9596 microtask_queue_->DecrementMicrotasksScopeDepth(); 9597 if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() && 9598 !isolate_->has_scheduled_exception()) { 9599 DCHECK_IMPLIES(isolate_->has_scheduled_exception(), 9600 isolate_->scheduled_exception() == 9601 i::ReadOnlyRoots(isolate_).termination_exception()); 9602 microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_)); 9603 } 9604 } 9605 #ifdef DEBUG 9606 if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth(); 9607 #endif 9608 } 9609 9610 // static PerformCheckpoint(Isolate * v8_isolate)9611 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) { 9612 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 9613 auto* microtask_queue = isolate->default_microtask_queue(); 9614 microtask_queue->PerformCheckpoint(v8_isolate); 9615 } 9616 9617 // static GetCurrentDepth(Isolate * v8_isolate)9618 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) { 9619 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 9620 auto* microtask_queue = isolate->default_microtask_queue(); 9621 return microtask_queue->GetMicrotasksScopeDepth(); 9622 } 9623 9624 // static IsRunningMicrotasks(Isolate * v8_isolate)9625 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) { 9626 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 9627 auto* microtask_queue = isolate->default_microtask_queue(); 9628 return microtask_queue->IsRunningMicrotasks(); 9629 } 9630 Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9631 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj) 9632 : str_(nullptr), length_(0) { 9633 if (obj.IsEmpty()) return; 9634 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 9635 ENTER_V8_DO_NOT_USE(i_isolate); 9636 i::HandleScope scope(i_isolate); 9637 Local<Context> context = isolate->GetCurrentContext(); 9638 TryCatch try_catch(isolate); 9639 Local<String> str; 9640 if (!obj->ToString(context).ToLocal(&str)) return; 9641 length_ = str->Utf8Length(isolate); 9642 str_ = i::NewArray<char>(length_ + 1); 9643 str->WriteUtf8(isolate, str_); 9644 } 9645 ~Utf8Value()9646 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); } 9647 Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9648 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj) 9649 : str_(nullptr), length_(0) { 9650 if (obj.IsEmpty()) return; 9651 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 9652 ENTER_V8_DO_NOT_USE(i_isolate); 9653 i::HandleScope scope(i_isolate); 9654 Local<Context> context = isolate->GetCurrentContext(); 9655 TryCatch try_catch(isolate); 9656 Local<String> str; 9657 if (!obj->ToString(context).ToLocal(&str)) return; 9658 length_ = str->Length(); 9659 str_ = i::NewArray<uint16_t>(length_ + 1); 9660 str->Write(isolate, str_); 9661 } 9662 ~Value()9663 String::Value::~Value() { i::DeleteArray(str_); } 9664 9665 #define DEFINE_ERROR(NAME, name) \ 9666 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \ 9667 i::Isolate* isolate = i::Isolate::Current(); \ 9668 API_RCS_SCOPE(isolate, NAME, New); \ 9669 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \ 9670 i::Object error; \ 9671 { \ 9672 i::HandleScope scope(isolate); \ 9673 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \ 9674 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \ 9675 error = *isolate->factory()->NewError(constructor, message); \ 9676 } \ 9677 i::Handle<i::Object> result(error, isolate); \ 9678 return Utils::ToLocal(result); \ 9679 } 9680 DEFINE_ERROR(RangeError,range_error)9681 DEFINE_ERROR(RangeError, range_error) 9682 DEFINE_ERROR(ReferenceError, reference_error) 9683 DEFINE_ERROR(SyntaxError, syntax_error) 9684 DEFINE_ERROR(TypeError, type_error) 9685 DEFINE_ERROR(WasmCompileError, wasm_compile_error) 9686 DEFINE_ERROR(WasmLinkError, wasm_link_error) 9687 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error) 9688 DEFINE_ERROR(Error, error) 9689 9690 #undef DEFINE_ERROR 9691 9692 Local<Message> Exception::CreateMessage(Isolate* isolate, 9693 Local<Value> exception) { 9694 i::Handle<i::Object> obj = Utils::OpenHandle(*exception); 9695 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 9696 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); 9697 i::HandleScope scope(i_isolate); 9698 return Utils::MessageToLocal( 9699 scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr))); 9700 } 9701 GetStackTrace(Local<Value> exception)9702 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) { 9703 i::Handle<i::Object> obj = Utils::OpenHandle(*exception); 9704 if (!obj->IsJSObject()) return Local<StackTrace>(); 9705 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj); 9706 i::Isolate* isolate = js_obj->GetIsolate(); 9707 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 9708 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj)); 9709 } 9710 PreviewEntries(bool * is_key_value)9711 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) { 9712 if (IsMap()) { 9713 *is_key_value = true; 9714 return Map::Cast(this)->AsArray(); 9715 } 9716 if (IsSet()) { 9717 *is_key_value = false; 9718 return Set::Cast(this)->AsArray(); 9719 } 9720 9721 i::Handle<i::JSReceiver> object = Utils::OpenHandle(this); 9722 i::Isolate* isolate = object->GetIsolate(); 9723 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate); 9724 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); 9725 if (object->IsJSWeakCollection()) { 9726 *is_key_value = object->IsJSWeakMap(); 9727 return Utils::ToLocal(i::JSWeakCollection::GetEntries( 9728 i::Handle<i::JSWeakCollection>::cast(object), 0)); 9729 } 9730 if (object->IsJSMapIterator()) { 9731 i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object); 9732 MapAsArrayKind const kind = 9733 static_cast<MapAsArrayKind>(it->map().instance_type()); 9734 *is_key_value = kind == MapAsArrayKind::kEntries; 9735 if (!it->HasMore()) return v8::Array::New(v8_isolate); 9736 return Utils::ToLocal( 9737 MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind)); 9738 } 9739 if (object->IsJSSetIterator()) { 9740 i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object); 9741 SetAsArrayKind const kind = 9742 static_cast<SetAsArrayKind>(it->map().instance_type()); 9743 *is_key_value = kind == SetAsArrayKind::kEntries; 9744 if (!it->HasMore()) return v8::Array::New(v8_isolate); 9745 return Utils::ToLocal( 9746 SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind)); 9747 } 9748 return v8::MaybeLocal<v8::Array>(); 9749 } 9750 GetFunctionName() const9751 Local<String> CpuProfileNode::GetFunctionName() const { 9752 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9753 i::Isolate* isolate = node->isolate(); 9754 const i::CodeEntry* entry = node->entry(); 9755 i::Handle<i::String> name = 9756 isolate->factory()->InternalizeUtf8String(entry->name()); 9757 return ToApiHandle<String>(name); 9758 } 9759 GetFunctionNameStr() const9760 const char* CpuProfileNode::GetFunctionNameStr() const { 9761 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9762 return node->entry()->name(); 9763 } 9764 GetScriptId() const9765 int CpuProfileNode::GetScriptId() const { 9766 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9767 const i::CodeEntry* entry = node->entry(); 9768 return entry->script_id(); 9769 } 9770 GetScriptResourceName() const9771 Local<String> CpuProfileNode::GetScriptResourceName() const { 9772 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9773 i::Isolate* isolate = node->isolate(); 9774 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String( 9775 node->entry()->resource_name())); 9776 } 9777 GetScriptResourceNameStr() const9778 const char* CpuProfileNode::GetScriptResourceNameStr() const { 9779 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9780 return node->entry()->resource_name(); 9781 } 9782 IsScriptSharedCrossOrigin() const9783 bool CpuProfileNode::IsScriptSharedCrossOrigin() const { 9784 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9785 return node->entry()->is_shared_cross_origin(); 9786 } 9787 GetLineNumber() const9788 int CpuProfileNode::GetLineNumber() const { 9789 return reinterpret_cast<const i::ProfileNode*>(this)->line_number(); 9790 } 9791 GetColumnNumber() const9792 int CpuProfileNode::GetColumnNumber() const { 9793 return reinterpret_cast<const i::ProfileNode*>(this) 9794 ->entry() 9795 ->column_number(); 9796 } 9797 GetHitLineCount() const9798 unsigned int CpuProfileNode::GetHitLineCount() const { 9799 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9800 return node->GetHitLineCount(); 9801 } 9802 GetLineTicks(LineTick * entries,unsigned int length) const9803 bool CpuProfileNode::GetLineTicks(LineTick* entries, 9804 unsigned int length) const { 9805 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9806 return node->GetLineTicks(entries, length); 9807 } 9808 GetBailoutReason() const9809 const char* CpuProfileNode::GetBailoutReason() const { 9810 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9811 return node->entry()->bailout_reason(); 9812 } 9813 GetHitCount() const9814 unsigned CpuProfileNode::GetHitCount() const { 9815 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks(); 9816 } 9817 GetNodeId() const9818 unsigned CpuProfileNode::GetNodeId() const { 9819 return reinterpret_cast<const i::ProfileNode*>(this)->id(); 9820 } 9821 GetSourceType() const9822 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const { 9823 return reinterpret_cast<const i::ProfileNode*>(this)->source_type(); 9824 } 9825 GetChildrenCount() const9826 int CpuProfileNode::GetChildrenCount() const { 9827 return static_cast<int>( 9828 reinterpret_cast<const i::ProfileNode*>(this)->children()->size()); 9829 } 9830 GetChild(int index) const9831 const CpuProfileNode* CpuProfileNode::GetChild(int index) const { 9832 const i::ProfileNode* child = 9833 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index); 9834 return reinterpret_cast<const CpuProfileNode*>(child); 9835 } 9836 GetParent() const9837 const CpuProfileNode* CpuProfileNode::GetParent() const { 9838 const i::ProfileNode* parent = 9839 reinterpret_cast<const i::ProfileNode*>(this)->parent(); 9840 return reinterpret_cast<const CpuProfileNode*>(parent); 9841 } 9842 GetDeoptInfos() const9843 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const { 9844 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 9845 return node->deopt_infos(); 9846 } 9847 Delete()9848 void CpuProfile::Delete() { 9849 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this); 9850 i::CpuProfiler* profiler = profile->cpu_profiler(); 9851 DCHECK_NOT_NULL(profiler); 9852 profiler->DeleteProfile(profile); 9853 } 9854 GetTitle() const9855 Local<String> CpuProfile::GetTitle() const { 9856 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9857 i::Isolate* isolate = profile->top_down()->isolate(); 9858 return ToApiHandle<String>( 9859 isolate->factory()->InternalizeUtf8String(profile->title())); 9860 } 9861 GetTopDownRoot() const9862 const CpuProfileNode* CpuProfile::GetTopDownRoot() const { 9863 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9864 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root()); 9865 } 9866 GetSample(int index) const9867 const CpuProfileNode* CpuProfile::GetSample(int index) const { 9868 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9869 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node); 9870 } 9871 9872 const int CpuProfileNode::kNoLineNumberInfo; 9873 const int CpuProfileNode::kNoColumnNumberInfo; 9874 GetSampleTimestamp(int index) const9875 int64_t CpuProfile::GetSampleTimestamp(int index) const { 9876 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9877 return profile->sample(index).timestamp.since_origin().InMicroseconds(); 9878 } 9879 GetSampleState(int index) const9880 StateTag CpuProfile::GetSampleState(int index) const { 9881 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9882 return profile->sample(index).state_tag; 9883 } 9884 GetSampleEmbedderState(int index) const9885 EmbedderStateTag CpuProfile::GetSampleEmbedderState(int index) const { 9886 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9887 return profile->sample(index).embedder_state_tag; 9888 } 9889 GetStartTime() const9890 int64_t CpuProfile::GetStartTime() const { 9891 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9892 return profile->start_time().since_origin().InMicroseconds(); 9893 } 9894 GetEndTime() const9895 int64_t CpuProfile::GetEndTime() const { 9896 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 9897 return profile->end_time().since_origin().InMicroseconds(); 9898 } 9899 ToInternal(const CpuProfile * profile)9900 static i::CpuProfile* ToInternal(const CpuProfile* profile) { 9901 return const_cast<i::CpuProfile*>( 9902 reinterpret_cast<const i::CpuProfile*>(profile)); 9903 } 9904 Serialize(OutputStream * stream,CpuProfile::SerializationFormat format) const9905 void CpuProfile::Serialize(OutputStream* stream, 9906 CpuProfile::SerializationFormat format) const { 9907 Utils::ApiCheck(format == kJSON, "v8::CpuProfile::Serialize", 9908 "Unknown serialization format"); 9909 Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::CpuProfile::Serialize", 9910 "Invalid stream chunk size"); 9911 i::CpuProfileJSONSerializer serializer(ToInternal(this)); 9912 serializer.Serialize(stream); 9913 } 9914 GetSamplesCount() const9915 int CpuProfile::GetSamplesCount() const { 9916 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count(); 9917 } 9918 New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)9919 CpuProfiler* CpuProfiler::New(Isolate* isolate, 9920 CpuProfilingNamingMode naming_mode, 9921 CpuProfilingLoggingMode logging_mode) { 9922 return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler( 9923 reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode)); 9924 } 9925 CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)9926 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode, 9927 unsigned max_samples, 9928 int sampling_interval_us, 9929 MaybeLocal<Context> filter_context) 9930 : mode_(mode), 9931 max_samples_(max_samples), 9932 sampling_interval_us_(sampling_interval_us) { 9933 if (!filter_context.IsEmpty()) { 9934 Local<Context> local_filter_context = filter_context.ToLocalChecked(); 9935 filter_context_.Reset(local_filter_context->GetIsolate(), 9936 local_filter_context); 9937 filter_context_.SetWeak(); 9938 } 9939 } 9940 raw_filter_context() const9941 void* CpuProfilingOptions::raw_filter_context() const { 9942 return reinterpret_cast<void*>( 9943 i::Context::cast(*Utils::OpenPersistent(filter_context_)) 9944 .native_context() 9945 .address()); 9946 } 9947 Dispose()9948 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); } 9949 9950 // static CollectSample(Isolate * isolate)9951 void CpuProfiler::CollectSample(Isolate* isolate) { 9952 i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate)); 9953 } 9954 SetSamplingInterval(int us)9955 void CpuProfiler::SetSamplingInterval(int us) { 9956 DCHECK_GE(us, 0); 9957 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval( 9958 base::TimeDelta::FromMicroseconds(us)); 9959 } 9960 SetUsePreciseSampling(bool use_precise_sampling)9961 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) { 9962 reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling( 9963 use_precise_sampling); 9964 } 9965 Start(CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9966 CpuProfilingResult CpuProfiler::Start( 9967 CpuProfilingOptions options, 9968 std::unique_ptr<DiscardedSamplesDelegate> delegate) { 9969 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( 9970 options, std::move(delegate)); 9971 } 9972 Start(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9973 CpuProfilingResult CpuProfiler::Start( 9974 Local<String> title, CpuProfilingOptions options, 9975 std::unique_ptr<DiscardedSamplesDelegate> delegate) { 9976 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( 9977 *Utils::OpenHandle(*title), options, std::move(delegate)); 9978 } 9979 Start(Local<String> title,bool record_samples)9980 CpuProfilingResult CpuProfiler::Start(Local<String> title, 9981 bool record_samples) { 9982 CpuProfilingOptions options( 9983 kLeafNodeLineNumbers, 9984 record_samples ? CpuProfilingOptions::kNoSampleLimit : 0); 9985 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( 9986 *Utils::OpenHandle(*title), options); 9987 } 9988 Start(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)9989 CpuProfilingResult CpuProfiler::Start(Local<String> title, 9990 CpuProfilingMode mode, 9991 bool record_samples, 9992 unsigned max_samples) { 9993 CpuProfilingOptions options(mode, record_samples ? max_samples : 0); 9994 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( 9995 *Utils::OpenHandle(*title), options); 9996 } 9997 StartProfiling(Local<String> title,CpuProfilingOptions options,std::unique_ptr<DiscardedSamplesDelegate> delegate)9998 CpuProfilingStatus CpuProfiler::StartProfiling( 9999 Local<String> title, CpuProfilingOptions options, 10000 std::unique_ptr<DiscardedSamplesDelegate> delegate) { 10001 return Start(title, options, std::move(delegate)).status; 10002 } 10003 StartProfiling(Local<String> title,bool record_samples)10004 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title, 10005 bool record_samples) { 10006 return Start(title, record_samples).status; 10007 } 10008 StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)10009 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title, 10010 CpuProfilingMode mode, 10011 bool record_samples, 10012 unsigned max_samples) { 10013 return Start(title, mode, record_samples, max_samples).status; 10014 } 10015 StopProfiling(Local<String> title)10016 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) { 10017 return reinterpret_cast<CpuProfile*>( 10018 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling( 10019 *Utils::OpenHandle(*title))); 10020 } 10021 Stop(ProfilerId id)10022 CpuProfile* CpuProfiler::Stop(ProfilerId id) { 10023 return reinterpret_cast<CpuProfile*>( 10024 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(id)); 10025 } 10026 UseDetailedSourcePositionsForProfiling(Isolate * isolate)10027 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) { 10028 reinterpret_cast<i::Isolate*>(isolate) 10029 ->SetDetailedSourcePositionsForProfiling(true); 10030 } 10031 GetCodeStartAddress()10032 uintptr_t CodeEvent::GetCodeStartAddress() { 10033 return reinterpret_cast<i::CodeEvent*>(this)->code_start_address; 10034 } 10035 GetCodeSize()10036 size_t CodeEvent::GetCodeSize() { 10037 return reinterpret_cast<i::CodeEvent*>(this)->code_size; 10038 } 10039 GetFunctionName()10040 Local<String> CodeEvent::GetFunctionName() { 10041 return ToApiHandle<String>( 10042 reinterpret_cast<i::CodeEvent*>(this)->function_name); 10043 } 10044 GetScriptName()10045 Local<String> CodeEvent::GetScriptName() { 10046 return ToApiHandle<String>( 10047 reinterpret_cast<i::CodeEvent*>(this)->script_name); 10048 } 10049 GetScriptLine()10050 int CodeEvent::GetScriptLine() { 10051 return reinterpret_cast<i::CodeEvent*>(this)->script_line; 10052 } 10053 GetScriptColumn()10054 int CodeEvent::GetScriptColumn() { 10055 return reinterpret_cast<i::CodeEvent*>(this)->script_column; 10056 } 10057 GetCodeType()10058 CodeEventType CodeEvent::GetCodeType() { 10059 return reinterpret_cast<i::CodeEvent*>(this)->code_type; 10060 } 10061 GetComment()10062 const char* CodeEvent::GetComment() { 10063 return reinterpret_cast<i::CodeEvent*>(this)->comment; 10064 } 10065 GetPreviousCodeStartAddress()10066 uintptr_t CodeEvent::GetPreviousCodeStartAddress() { 10067 return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address; 10068 } 10069 GetCodeEventTypeName(CodeEventType code_event_type)10070 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) { 10071 switch (code_event_type) { 10072 case kUnknownType: 10073 return "Unknown"; 10074 #define V(Name) \ 10075 case k##Name##Type: \ 10076 return #Name; 10077 CODE_EVENTS_LIST(V) 10078 #undef V 10079 } 10080 // The execution should never pass here 10081 UNREACHABLE(); 10082 } 10083 CodeEventHandler(Isolate * isolate)10084 CodeEventHandler::CodeEventHandler(Isolate* isolate) { 10085 internal_listener_ = 10086 new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate)); 10087 } 10088 ~CodeEventHandler()10089 CodeEventHandler::~CodeEventHandler() { 10090 delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_); 10091 } 10092 Enable()10093 void CodeEventHandler::Enable() { 10094 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_) 10095 ->StartListening(this); 10096 } 10097 Disable()10098 void CodeEventHandler::Disable() { 10099 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_) 10100 ->StopListening(); 10101 } 10102 ToInternal(const HeapGraphEdge * edge)10103 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) { 10104 return const_cast<i::HeapGraphEdge*>( 10105 reinterpret_cast<const i::HeapGraphEdge*>(edge)); 10106 } 10107 GetType() const10108 HeapGraphEdge::Type HeapGraphEdge::GetType() const { 10109 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type()); 10110 } 10111 GetName() const10112 Local<Value> HeapGraphEdge::GetName() const { 10113 i::HeapGraphEdge* edge = ToInternal(this); 10114 i::Isolate* isolate = edge->isolate(); 10115 switch (edge->type()) { 10116 case i::HeapGraphEdge::kContextVariable: 10117 case i::HeapGraphEdge::kInternal: 10118 case i::HeapGraphEdge::kProperty: 10119 case i::HeapGraphEdge::kShortcut: 10120 case i::HeapGraphEdge::kWeak: 10121 return ToApiHandle<String>( 10122 isolate->factory()->InternalizeUtf8String(edge->name())); 10123 case i::HeapGraphEdge::kElement: 10124 case i::HeapGraphEdge::kHidden: 10125 return ToApiHandle<Number>( 10126 isolate->factory()->NewNumberFromInt(edge->index())); 10127 default: 10128 UNREACHABLE(); 10129 } 10130 } 10131 GetFromNode() const10132 const HeapGraphNode* HeapGraphEdge::GetFromNode() const { 10133 const i::HeapEntry* from = ToInternal(this)->from(); 10134 return reinterpret_cast<const HeapGraphNode*>(from); 10135 } 10136 GetToNode() const10137 const HeapGraphNode* HeapGraphEdge::GetToNode() const { 10138 const i::HeapEntry* to = ToInternal(this)->to(); 10139 return reinterpret_cast<const HeapGraphNode*>(to); 10140 } 10141 ToInternal(const HeapGraphNode * entry)10142 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) { 10143 return const_cast<i::HeapEntry*>( 10144 reinterpret_cast<const i::HeapEntry*>(entry)); 10145 } 10146 GetType() const10147 HeapGraphNode::Type HeapGraphNode::GetType() const { 10148 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type()); 10149 } 10150 GetName() const10151 Local<String> HeapGraphNode::GetName() const { 10152 i::Isolate* isolate = ToInternal(this)->isolate(); 10153 return ToApiHandle<String>( 10154 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name())); 10155 } 10156 GetId() const10157 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); } 10158 GetShallowSize() const10159 size_t HeapGraphNode::GetShallowSize() const { 10160 return ToInternal(this)->self_size(); 10161 } 10162 GetChildrenCount() const10163 int HeapGraphNode::GetChildrenCount() const { 10164 return ToInternal(this)->children_count(); 10165 } 10166 GetChild(int index) const10167 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const { 10168 return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index)); 10169 } 10170 ToInternal(const HeapSnapshot * snapshot)10171 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) { 10172 return const_cast<i::HeapSnapshot*>( 10173 reinterpret_cast<const i::HeapSnapshot*>(snapshot)); 10174 } 10175 Delete()10176 void HeapSnapshot::Delete() { 10177 i::Isolate* isolate = ToInternal(this)->profiler()->isolate(); 10178 if (isolate->heap_profiler()->GetSnapshotsCount() > 1 || 10179 isolate->heap_profiler()->IsTakingSnapshot()) { 10180 ToInternal(this)->Delete(); 10181 } else { 10182 // If this is the last snapshot, clean up all accessory data as well. 10183 isolate->heap_profiler()->DeleteAllSnapshots(); 10184 } 10185 } 10186 GetRoot() const10187 const HeapGraphNode* HeapSnapshot::GetRoot() const { 10188 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root()); 10189 } 10190 GetNodeById(SnapshotObjectId id) const10191 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const { 10192 return reinterpret_cast<const HeapGraphNode*>( 10193 ToInternal(this)->GetEntryById(id)); 10194 } 10195 GetNodesCount() const10196 int HeapSnapshot::GetNodesCount() const { 10197 return static_cast<int>(ToInternal(this)->entries().size()); 10198 } 10199 GetNode(int index) const10200 const HeapGraphNode* HeapSnapshot::GetNode(int index) const { 10201 return reinterpret_cast<const HeapGraphNode*>( 10202 &ToInternal(this)->entries().at(index)); 10203 } 10204 GetMaxSnapshotJSObjectId() const10205 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const { 10206 return ToInternal(this)->max_snapshot_js_object_id(); 10207 } 10208 Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10209 void HeapSnapshot::Serialize(OutputStream* stream, 10210 HeapSnapshot::SerializationFormat format) const { 10211 Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize", 10212 "Unknown serialization format"); 10213 Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize", 10214 "Invalid stream chunk size"); 10215 i::HeapSnapshotJSONSerializer serializer(ToInternal(this)); 10216 serializer.Serialize(stream); 10217 } 10218 10219 // static 10220 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId 10221 HeapProfiler::kUnknownObjectId; 10222 GetSnapshotCount()10223 int HeapProfiler::GetSnapshotCount() { 10224 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount(); 10225 } 10226 GetHeapSnapshot(int index)10227 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) { 10228 return reinterpret_cast<const HeapSnapshot*>( 10229 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index)); 10230 } 10231 GetObjectId(Local<Value> value)10232 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) { 10233 i::Handle<i::Object> obj = Utils::OpenHandle(*value); 10234 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj); 10235 } 10236 GetObjectId(NativeObject value)10237 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) { 10238 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value); 10239 } 10240 FindObjectById(SnapshotObjectId id)10241 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) { 10242 i::Handle<i::Object> obj = 10243 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id); 10244 if (obj.is_null()) return Local<Value>(); 10245 return Utils::ToLocal(obj); 10246 } 10247 ClearObjectIds()10248 void HeapProfiler::ClearObjectIds() { 10249 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap(); 10250 } 10251 TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots,bool capture_numeric_value)10252 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot( 10253 ActivityControl* control, ObjectNameResolver* resolver, 10254 bool treat_global_objects_as_roots, bool capture_numeric_value) { 10255 return reinterpret_cast<const HeapSnapshot*>( 10256 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot( 10257 control, resolver, treat_global_objects_as_roots, 10258 capture_numeric_value)); 10259 } 10260 StartTrackingHeapObjects(bool track_allocations)10261 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) { 10262 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking( 10263 track_allocations); 10264 } 10265 StopTrackingHeapObjects()10266 void HeapProfiler::StopTrackingHeapObjects() { 10267 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking(); 10268 } 10269 GetHeapStats(OutputStream * stream,int64_t * timestamp_us)10270 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream, 10271 int64_t* timestamp_us) { 10272 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this); 10273 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us); 10274 } 10275 StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)10276 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval, 10277 int stack_depth, 10278 SamplingFlags flags) { 10279 return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler( 10280 sample_interval, stack_depth, flags); 10281 } 10282 StopSamplingHeapProfiler()10283 void HeapProfiler::StopSamplingHeapProfiler() { 10284 reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler(); 10285 } 10286 GetAllocationProfile()10287 AllocationProfile* HeapProfiler::GetAllocationProfile() { 10288 return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile(); 10289 } 10290 DeleteAllHeapSnapshots()10291 void HeapProfiler::DeleteAllHeapSnapshots() { 10292 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots(); 10293 } 10294 AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10295 void HeapProfiler::AddBuildEmbedderGraphCallback( 10296 BuildEmbedderGraphCallback callback, void* data) { 10297 reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback( 10298 callback, data); 10299 } 10300 RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)10301 void HeapProfiler::RemoveBuildEmbedderGraphCallback( 10302 BuildEmbedderGraphCallback callback, void* data) { 10303 reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback( 10304 callback, data); 10305 } 10306 SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)10307 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback, 10308 void* data) { 10309 reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback, 10310 data); 10311 } 10312 SetStackStart(void * stack_start)10313 void EmbedderHeapTracer::SetStackStart(void* stack_start) { 10314 CHECK(isolate_); 10315 reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart( 10316 stack_start); 10317 } 10318 FinalizeTracing()10319 void EmbedderHeapTracer::FinalizeTracing() { 10320 if (isolate_) { 10321 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_); 10322 if (isolate->heap()->incremental_marking()->IsMarking()) { 10323 isolate->heap()->FinalizeIncrementalMarkingAtomically( 10324 i::GarbageCollectionReason::kExternalFinalize); 10325 } 10326 } 10327 } 10328 IncreaseAllocatedSize(size_t bytes)10329 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) { 10330 if (isolate_) { 10331 i::LocalEmbedderHeapTracer* const tracer = 10332 reinterpret_cast<i::Isolate*>(isolate_) 10333 ->heap() 10334 ->local_embedder_heap_tracer(); 10335 DCHECK_NOT_NULL(tracer); 10336 tracer->IncreaseAllocatedSize(bytes); 10337 } 10338 } 10339 DecreaseAllocatedSize(size_t bytes)10340 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) { 10341 if (isolate_) { 10342 i::LocalEmbedderHeapTracer* const tracer = 10343 reinterpret_cast<i::Isolate*>(isolate_) 10344 ->heap() 10345 ->local_embedder_heap_tracer(); 10346 DCHECK_NOT_NULL(tracer); 10347 tracer->DecreaseAllocatedSize(bytes); 10348 } 10349 } 10350 RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)10351 void EmbedderHeapTracer::RegisterEmbedderReference( 10352 const BasicTracedReference<v8::Data>& ref) { 10353 if (ref.IsEmpty()) return; 10354 10355 i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap(); 10356 heap->RegisterExternallyReferencedObject( 10357 reinterpret_cast<i::Address*>(ref.val_)); 10358 } 10359 IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)10360 void EmbedderHeapTracer::IterateTracedGlobalHandles( 10361 TracedGlobalHandleVisitor* visitor) { 10362 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_); 10363 i::DisallowGarbageCollection no_gc; 10364 isolate->global_handles()->IterateTracedNodes(visitor); 10365 } 10366 IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)10367 bool EmbedderHeapTracer::IsRootForNonTracingGC( 10368 const v8::TracedReference<v8::Value>& handle) { 10369 return true; 10370 } 10371 ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)10372 void EmbedderHeapTracer::ResetHandleInNonTracingGC( 10373 const v8::TracedReference<v8::Value>& handle) { 10374 UNREACHABLE(); 10375 } 10376 EmbedderStateScope(Isolate * isolate,Local<v8::Context> context,EmbedderStateTag tag)10377 EmbedderStateScope::EmbedderStateScope(Isolate* isolate, 10378 Local<v8::Context> context, 10379 EmbedderStateTag tag) 10380 : embedder_state_(new internal::EmbedderState(isolate, context, tag)) {} 10381 10382 // std::unique_ptr's destructor is not compatible with Forward declared 10383 // EmbedderState class. 10384 // Default destructor must be defined in implementation file. 10385 EmbedderStateScope::~EmbedderStateScope() = default; 10386 CheckValue() const10387 void TracedReferenceBase::CheckValue() const { 10388 #ifdef V8_HOST_ARCH_64_BIT 10389 if (!val_) return; 10390 10391 CHECK_NE(internal::kGlobalHandleZapValue, *reinterpret_cast<uint64_t*>(val_)); 10392 #endif // V8_HOST_ARCH_64_BIT 10393 } 10394 CFunction(const void * address,const CFunctionInfo * type_info)10395 CFunction::CFunction(const void* address, const CFunctionInfo* type_info) 10396 : address_(address), type_info_(type_info) { 10397 CHECK_NOT_NULL(address_); 10398 CHECK_NOT_NULL(type_info_); 10399 } 10400 CFunctionInfo(const CTypeInfo & return_info,unsigned int arg_count,const CTypeInfo * arg_info)10401 CFunctionInfo::CFunctionInfo(const CTypeInfo& return_info, 10402 unsigned int arg_count, const CTypeInfo* arg_info) 10403 : return_info_(return_info), arg_count_(arg_count), arg_info_(arg_info) { 10404 if (arg_count_ > 0) { 10405 for (unsigned int i = 0; i < arg_count_ - 1; ++i) { 10406 DCHECK(arg_info_[i].GetType() != CTypeInfo::kCallbackOptionsType); 10407 } 10408 } 10409 } 10410 ArgumentInfo(unsigned int index) const10411 const CTypeInfo& CFunctionInfo::ArgumentInfo(unsigned int index) const { 10412 DCHECK_LT(index, ArgumentCount()); 10413 return arg_info_[index]; 10414 } 10415 ValidateIndex(size_t index) const10416 void FastApiTypedArrayBase::ValidateIndex(size_t index) const { 10417 DCHECK_LT(index, length_); 10418 } 10419 RegisterState()10420 RegisterState::RegisterState() 10421 : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {} 10422 RegisterState::~RegisterState() = default; 10423 RegisterState(const RegisterState & other)10424 RegisterState::RegisterState(const RegisterState& other) { *this = other; } 10425 operator =(const RegisterState & other)10426 RegisterState& RegisterState::operator=(const RegisterState& other) { 10427 if (&other != this) { 10428 pc = other.pc; 10429 sp = other.sp; 10430 fp = other.fp; 10431 lr = other.lr; 10432 if (other.callee_saved) { 10433 // Make a deep copy if {other.callee_saved} is non-null. 10434 callee_saved = 10435 std::make_unique<CalleeSavedRegisters>(*(other.callee_saved)); 10436 } else { 10437 // Otherwise, set {callee_saved} to null to match {other}. 10438 callee_saved.reset(); 10439 } 10440 } 10441 return *this; 10442 } 10443 10444 #if !V8_ENABLE_WEBASSEMBLY 10445 // If WebAssembly is disabled, we still need to provide an implementation of the 10446 // WasmStreaming API. Since {WasmStreaming::Unpack} will always fail, all 10447 // methods are unreachable. 10448 10449 class WasmStreaming::WasmStreamingImpl {}; 10450 WasmStreaming(std::unique_ptr<WasmStreamingImpl>)10451 WasmStreaming::WasmStreaming(std::unique_ptr<WasmStreamingImpl>) { 10452 UNREACHABLE(); 10453 } 10454 10455 WasmStreaming::~WasmStreaming() = default; 10456 OnBytesReceived(const uint8_t * bytes,size_t size)10457 void WasmStreaming::OnBytesReceived(const uint8_t* bytes, size_t size) { 10458 UNREACHABLE(); 10459 } 10460 Finish(bool can_use_compiled_module)10461 void WasmStreaming::Finish(bool can_use_compiled_module) { UNREACHABLE(); } 10462 Abort(MaybeLocal<Value> exception)10463 void WasmStreaming::Abort(MaybeLocal<Value> exception) { UNREACHABLE(); } 10464 SetCompiledModuleBytes(const uint8_t * bytes,size_t size)10465 bool WasmStreaming::SetCompiledModuleBytes(const uint8_t* bytes, size_t size) { 10466 UNREACHABLE(); 10467 } 10468 SetClient(std::shared_ptr<Client> client)10469 void WasmStreaming::SetClient(std::shared_ptr<Client> client) { UNREACHABLE(); } 10470 SetUrl(const char * url,size_t length)10471 void WasmStreaming::SetUrl(const char* url, size_t length) { UNREACHABLE(); } 10472 10473 // static Unpack(Isolate * isolate,Local<Value> value)10474 std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate, 10475 Local<Value> value) { 10476 FATAL("WebAssembly is disabled"); 10477 } 10478 #endif // !V8_ENABLE_WEBASSEMBLY 10479 10480 namespace internal { 10481 10482 const size_t HandleScopeImplementer::kEnteredContextsOffset = 10483 offsetof(HandleScopeImplementer, entered_contexts_); 10484 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset = 10485 offsetof(HandleScopeImplementer, is_microtask_context_); 10486 FreeThreadResources()10487 void HandleScopeImplementer::FreeThreadResources() { Free(); } 10488 ArchiveThread(char * storage)10489 char* HandleScopeImplementer::ArchiveThread(char* storage) { 10490 HandleScopeData* current = isolate_->handle_scope_data(); 10491 handle_scope_data_ = *current; 10492 MemCopy(storage, this, sizeof(*this)); 10493 10494 ResetAfterArchive(); 10495 current->Initialize(); 10496 10497 return storage + ArchiveSpacePerThread(); 10498 } 10499 ArchiveSpacePerThread()10500 int HandleScopeImplementer::ArchiveSpacePerThread() { 10501 return sizeof(HandleScopeImplementer); 10502 } 10503 RestoreThread(char * storage)10504 char* HandleScopeImplementer::RestoreThread(char* storage) { 10505 MemCopy(this, storage, sizeof(*this)); 10506 *isolate_->handle_scope_data() = handle_scope_data_; 10507 return storage + ArchiveSpacePerThread(); 10508 } 10509 IterateThis(RootVisitor * v)10510 void HandleScopeImplementer::IterateThis(RootVisitor* v) { 10511 #ifdef DEBUG 10512 bool found_block_before_deferred = false; 10513 #endif 10514 // Iterate over all handles in the blocks except for the last. 10515 for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) { 10516 Address* block = blocks()->at(i); 10517 // Cast possibly-unrelated pointers to plain Address before comparing them 10518 // to avoid undefined behavior. 10519 if (last_handle_before_deferred_block_ != nullptr && 10520 (reinterpret_cast<Address>(last_handle_before_deferred_block_) <= 10521 reinterpret_cast<Address>(&block[kHandleBlockSize])) && 10522 (reinterpret_cast<Address>(last_handle_before_deferred_block_) >= 10523 reinterpret_cast<Address>(block))) { 10524 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block), 10525 FullObjectSlot(last_handle_before_deferred_block_)); 10526 DCHECK(!found_block_before_deferred); 10527 #ifdef DEBUG 10528 found_block_before_deferred = true; 10529 #endif 10530 } else { 10531 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block), 10532 FullObjectSlot(&block[kHandleBlockSize])); 10533 } 10534 } 10535 10536 DCHECK(last_handle_before_deferred_block_ == nullptr || 10537 found_block_before_deferred); 10538 10539 // Iterate over live handles in the last block (if any). 10540 if (!blocks()->empty()) { 10541 v->VisitRootPointers(Root::kHandleScope, nullptr, 10542 FullObjectSlot(blocks()->back()), 10543 FullObjectSlot(handle_scope_data_.next)); 10544 } 10545 10546 DetachableVector<Context>* context_lists[2] = {&saved_contexts_, 10547 &entered_contexts_}; 10548 for (unsigned i = 0; i < arraysize(context_lists); i++) { 10549 context_lists[i]->shrink_to_fit(); 10550 if (context_lists[i]->empty()) continue; 10551 FullObjectSlot start(&context_lists[i]->front()); 10552 v->VisitRootPointers(Root::kHandleScope, nullptr, start, 10553 start + static_cast<int>(context_lists[i]->size())); 10554 } 10555 // The shape of |entered_contexts_| and |is_microtask_context_| stacks must 10556 // be in sync. 10557 is_microtask_context_.shrink_to_fit(); 10558 DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity()); 10559 DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size()); 10560 } 10561 Iterate(RootVisitor * v)10562 void HandleScopeImplementer::Iterate(RootVisitor* v) { 10563 HandleScopeData* current = isolate_->handle_scope_data(); 10564 handle_scope_data_ = *current; 10565 IterateThis(v); 10566 } 10567 Iterate(RootVisitor * v,char * storage)10568 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) { 10569 HandleScopeImplementer* scope_implementer = 10570 reinterpret_cast<HandleScopeImplementer*>(storage); 10571 scope_implementer->IterateThis(v); 10572 return storage + ArchiveSpacePerThread(); 10573 } 10574 DetachPersistent(Address * prev_limit)10575 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent( 10576 Address* prev_limit) { 10577 std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate())); 10578 DCHECK_NOT_NULL(prev_limit); 10579 10580 while (!blocks_.empty()) { 10581 Address* block_start = blocks_.back(); 10582 Address* block_limit = &block_start[kHandleBlockSize]; 10583 // We should not need to check for SealHandleScope here. Assert this. 10584 DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit, 10585 prev_limit == block_limit); 10586 if (prev_limit == block_limit) break; 10587 ph->blocks_.push_back(blocks_.back()); 10588 #if DEBUG 10589 ph->ordered_blocks_.insert(blocks_.back()); 10590 #endif 10591 blocks_.pop_back(); 10592 } 10593 10594 // ph->blocks_ now contains the blocks installed on the 10595 // HandleScope stack since BeginDeferredScope was called, but in 10596 // reverse order. 10597 10598 // Switch first and last blocks, such that the last block is the one 10599 // that is potentially half full. 10600 DCHECK(!blocks_.empty() && !ph->blocks_.empty()); 10601 std::swap(ph->blocks_.front(), ph->blocks_.back()); 10602 10603 ph->block_next_ = isolate()->handle_scope_data()->next; 10604 Address* block_start = ph->blocks_.back(); 10605 ph->block_limit_ = block_start + kHandleBlockSize; 10606 10607 DCHECK_NOT_NULL(last_handle_before_deferred_block_); 10608 last_handle_before_deferred_block_ = nullptr; 10609 return ph; 10610 } 10611 BeginDeferredScope()10612 void HandleScopeImplementer::BeginDeferredScope() { 10613 DCHECK_NULL(last_handle_before_deferred_block_); 10614 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next; 10615 } 10616 InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)10617 void InvokeAccessorGetterCallback( 10618 v8::Local<v8::Name> property, 10619 const v8::PropertyCallbackInfo<v8::Value>& info, 10620 v8::AccessorNameGetterCallback getter) { 10621 // Leaving JavaScript. 10622 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); 10623 RCS_SCOPE(isolate, RuntimeCallCounterId::kAccessorGetterCallback); 10624 Address getter_address = reinterpret_cast<Address>(getter); 10625 ExternalCallbackScope call_scope(isolate, getter_address); 10626 getter(property, info); 10627 } 10628 InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)10629 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info, 10630 v8::FunctionCallback callback) { 10631 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); 10632 RCS_SCOPE(isolate, RuntimeCallCounterId::kFunctionCallback); 10633 Address callback_address = reinterpret_cast<Address>(callback); 10634 ExternalCallbackScope call_scope(isolate, callback_address); 10635 callback(info); 10636 } 10637 InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)10638 void InvokeFinalizationRegistryCleanupFromTask( 10639 Handle<Context> context, 10640 Handle<JSFinalizationRegistry> finalization_registry, 10641 Handle<Object> callback) { 10642 Isolate* isolate = finalization_registry->native_context().GetIsolate(); 10643 RCS_SCOPE(isolate, 10644 RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask); 10645 // Do not use ENTER_V8 because this is always called from a running 10646 // FinalizationRegistryCleanupTask within V8 and we should not log it as an 10647 // API call. This method is implemented here to avoid duplication of the 10648 // exception handling and microtask running logic in CallDepthScope. 10649 if (IsExecutionTerminatingCheck(isolate)) return; 10650 Local<v8::Context> api_context = Utils::ToLocal(context); 10651 CallDepthScope<true> call_depth_scope(isolate, api_context); 10652 VMState<OTHER> state(isolate); 10653 Handle<Object> argv[] = {callback}; 10654 if (Execution::CallBuiltin(isolate, 10655 isolate->finalization_registry_cleanup_some(), 10656 finalization_registry, arraysize(argv), argv) 10657 .is_null()) { 10658 call_depth_scope.Escape(); 10659 } 10660 } 10661 10662 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10663 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10664 int32_t ConvertDouble(double d) { 10665 return internal::DoubleToInt32(d); 10666 } 10667 10668 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10669 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10670 uint32_t ConvertDouble(double d) { 10671 return internal::DoubleToUint32(d); 10672 } 10673 10674 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10675 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10676 float ConvertDouble(double d) { 10677 return internal::DoubleToFloat32(d); 10678 } 10679 10680 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10681 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10682 double ConvertDouble(double d) { 10683 return d; 10684 } 10685 10686 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10687 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10688 int64_t ConvertDouble(double d) { 10689 return internal::DoubleToWebIDLInt64(d); 10690 } 10691 10692 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10693 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10694 uint64_t ConvertDouble(double d) { 10695 return internal::DoubleToWebIDLUint64(d); 10696 } 10697 10698 template <> EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)10699 EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) 10700 bool ConvertDouble(double d) { 10701 // Implements https://tc39.es/ecma262/#sec-toboolean. 10702 return !std::isnan(d) && d != 0; 10703 } 10704 10705 // Undefine macros for jumbo build. 10706 #undef SET_FIELD_WRAPPED 10707 #undef NEW_STRING 10708 #undef CALLBACK_SETTER 10709 10710 } // namespace internal 10711 10712 template <> 10713 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,int32_t * dst,uint32_t max_length)10714 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<int32_t>::Build().GetId(), 10715 int32_t>(Local<Array> src, int32_t* dst, 10716 uint32_t max_length) { 10717 return CopyAndConvertArrayToCppBuffer< 10718 CTypeInfo(CTypeInfo::Type::kInt32, CTypeInfo::SequenceType::kIsSequence) 10719 .GetId(), 10720 int32_t>(src, dst, max_length); 10721 } 10722 10723 template <> 10724 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,uint32_t * dst,uint32_t max_length)10725 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<uint32_t>::Build().GetId(), 10726 uint32_t>(Local<Array> src, uint32_t* dst, 10727 uint32_t max_length) { 10728 return CopyAndConvertArrayToCppBuffer< 10729 CTypeInfo(CTypeInfo::Type::kUint32, CTypeInfo::SequenceType::kIsSequence) 10730 .GetId(), 10731 uint32_t>(src, dst, max_length); 10732 } 10733 10734 template <> 10735 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,float * dst,uint32_t max_length)10736 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<float>::Build().GetId(), 10737 float>(Local<Array> src, float* dst, 10738 uint32_t max_length) { 10739 return CopyAndConvertArrayToCppBuffer< 10740 CTypeInfo(CTypeInfo::Type::kFloat32, CTypeInfo::SequenceType::kIsSequence) 10741 .GetId(), 10742 float>(src, dst, max_length); 10743 } 10744 10745 template <> 10746 bool V8_EXPORT V8_WARN_UNUSED_RESULT TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,double * dst,uint32_t max_length)10747 TryToCopyAndConvertArrayToCppBuffer<CTypeInfoBuilder<double>::Build().GetId(), 10748 double>(Local<Array> src, double* dst, 10749 uint32_t max_length) { 10750 return CopyAndConvertArrayToCppBuffer< 10751 CTypeInfo(CTypeInfo::Type::kFloat64, CTypeInfo::SequenceType::kIsSequence) 10752 .GetId(), 10753 double>(src, dst, max_length); 10754 } 10755 10756 } // namespace v8 10757 10758 #undef TRACE_BS 10759 #include "src/api/api-macros-undef.h" 10760