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.h" 6 7 #include <string.h> // For memcpy, strlen. 8 #ifdef V8_USE_ADDRESS_SANITIZER 9 #include <sanitizer/asan_interface.h> 10 #endif // V8_USE_ADDRESS_SANITIZER 11 #include <cmath> // For isnan. 12 #include <limits> 13 #include <vector> 14 #include "include/v8-debug.h" 15 #include "include/v8-experimental.h" 16 #include "include/v8-profiler.h" 17 #include "include/v8-testing.h" 18 #include "src/api-experimental.h" 19 #include "src/api-natives.h" 20 #include "src/assert-scope.h" 21 #include "src/background-parsing-task.h" 22 #include "src/base/functional.h" 23 #include "src/base/platform/platform.h" 24 #include "src/base/platform/time.h" 25 #include "src/base/utils/random-number-generator.h" 26 #include "src/bootstrapper.h" 27 #include "src/char-predicates-inl.h" 28 #include "src/code-stubs.h" 29 #include "src/compiler.h" 30 #include "src/context-measure.h" 31 #include "src/contexts.h" 32 #include "src/conversions-inl.h" 33 #include "src/counters.h" 34 #include "src/debug/debug.h" 35 #include "src/deoptimizer.h" 36 #include "src/execution.h" 37 #include "src/global-handles.h" 38 #include "src/icu_util.h" 39 #include "src/isolate-inl.h" 40 #include "src/messages.h" 41 #include "src/parsing/json-parser.h" 42 #include "src/parsing/parser.h" 43 #include "src/parsing/scanner-character-streams.h" 44 #include "src/pending-compilation-error-handler.h" 45 #include "src/profiler/cpu-profiler.h" 46 #include "src/profiler/heap-profiler.h" 47 #include "src/profiler/heap-snapshot-generator-inl.h" 48 #include "src/profiler/profile-generator-inl.h" 49 #include "src/profiler/sampler.h" 50 #include "src/property.h" 51 #include "src/property-descriptor.h" 52 #include "src/property-details.h" 53 #include "src/prototype.h" 54 #include "src/runtime/runtime.h" 55 #include "src/runtime-profiler.h" 56 #include "src/simulator.h" 57 #include "src/snapshot/natives.h" 58 #include "src/snapshot/snapshot.h" 59 #include "src/startup-data-util.h" 60 #include "src/unicode-inl.h" 61 #include "src/v8.h" 62 #include "src/v8threads.h" 63 #include "src/version.h" 64 #include "src/vm-state-inl.h" 65 66 67 namespace v8 { 68 69 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr)) 70 71 72 #define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate)) 73 74 75 #define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \ 76 bailout_value, HandleScopeClass, \ 77 do_callback) \ 78 if (IsExecutionTerminatingCheck(isolate)) { \ 79 return bailout_value; \ 80 } \ 81 HandleScopeClass handle_scope(isolate); \ 82 CallDepthScope call_depth_scope(isolate, context, do_callback); \ 83 LOG_API(isolate, function_name); \ 84 ENTER_V8(isolate); \ 85 bool has_pending_exception = false 86 87 88 #define PREPARE_FOR_EXECUTION_WITH_CONTEXT( \ 89 context, function_name, bailout_value, HandleScopeClass, do_callback) \ 90 auto isolate = context.IsEmpty() \ 91 ? i::Isolate::Current() \ 92 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \ 93 PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \ 94 bailout_value, HandleScopeClass, do_callback); 95 96 97 #define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, function_name, T) \ 98 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), function_name, \ 99 MaybeLocal<T>(), InternalEscapableScope, \ 100 false); 101 102 103 #define PREPARE_FOR_EXECUTION(context, function_name, T) \ 104 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \ 105 InternalEscapableScope, false) 106 107 108 #define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \ 109 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \ 110 InternalEscapableScope, true) 111 112 113 #define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \ 114 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, Nothing<T>(), \ 115 i::HandleScope, false) 116 117 118 #define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \ 119 do { \ 120 if (has_pending_exception) { \ 121 call_depth_scope.Escape(); \ 122 return value; \ 123 } \ 124 } while (false) 125 126 127 #define RETURN_ON_FAILED_EXECUTION(T) \ 128 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, MaybeLocal<T>()) 129 130 131 #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \ 132 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, Nothing<T>()) 133 134 135 #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \ 136 return maybe_local.FromMaybe(Local<T>()); 137 138 139 #define RETURN_ESCAPED(value) return handle_scope.Escape(value); 140 141 142 namespace { 143 144 Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) { 145 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate()) 146 ->GetCurrentContext(); 147 } 148 149 class InternalEscapableScope : public v8::EscapableHandleScope { 150 public: 151 explicit inline InternalEscapableScope(i::Isolate* isolate) 152 : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {} 153 }; 154 155 156 class CallDepthScope { 157 public: 158 explicit CallDepthScope(i::Isolate* isolate, Local<Context> context, 159 bool do_callback) 160 : isolate_(isolate), 161 context_(context), 162 escaped_(false), 163 do_callback_(do_callback) { 164 // TODO(dcarney): remove this when blink stops crashing. 165 DCHECK(!isolate_->external_caught_exception()); 166 isolate_->IncrementJsCallsFromApiCounter(); 167 isolate_->handle_scope_implementer()->IncrementCallDepth(); 168 if (!context_.IsEmpty()) context_->Enter(); 169 } 170 ~CallDepthScope() { 171 if (!context_.IsEmpty()) context_->Exit(); 172 if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth(); 173 if (do_callback_) isolate_->FireCallCompletedCallback(); 174 } 175 176 void Escape() { 177 DCHECK(!escaped_); 178 escaped_ = true; 179 auto handle_scope_implementer = isolate_->handle_scope_implementer(); 180 handle_scope_implementer->DecrementCallDepth(); 181 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); 182 isolate_->OptionalRescheduleException(call_depth_is_zero); 183 } 184 185 private: 186 i::Isolate* const isolate_; 187 Local<Context> context_; 188 bool escaped_; 189 bool do_callback_; 190 }; 191 192 } // namespace 193 194 195 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate, 196 i::Handle<i::Script> script) { 197 i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script)); 198 i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate); 199 v8::Isolate* v8_isolate = 200 reinterpret_cast<v8::Isolate*>(script->GetIsolate()); 201 ScriptOriginOptions options(script->origin_options()); 202 v8::ScriptOrigin origin( 203 Utils::ToLocal(scriptName), 204 v8::Integer::New(v8_isolate, script->line_offset()), 205 v8::Integer::New(v8_isolate, script->column_offset()), 206 v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()), 207 v8::Integer::New(v8_isolate, script->id()), 208 v8::Boolean::New(v8_isolate, options.IsEmbedderDebugScript()), 209 Utils::ToLocal(source_map_url), 210 v8::Boolean::New(v8_isolate, options.IsOpaque())); 211 return origin; 212 } 213 214 215 // --- E x c e p t i o n B e h a v i o r --- 216 217 218 void i::FatalProcessOutOfMemory(const char* location) { 219 i::V8::FatalProcessOutOfMemory(location, false); 220 } 221 222 223 // When V8 cannot allocated memory FatalProcessOutOfMemory is called. 224 // The default fatal error handler is called and execution is stopped. 225 void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) { 226 i::Isolate* isolate = i::Isolate::Current(); 227 char last_few_messages[Heap::kTraceRingBufferSize + 1]; 228 char js_stacktrace[Heap::kStacktraceBufferSize + 1]; 229 memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1); 230 memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1); 231 232 i::HeapStats heap_stats; 233 int start_marker; 234 heap_stats.start_marker = &start_marker; 235 int new_space_size; 236 heap_stats.new_space_size = &new_space_size; 237 int new_space_capacity; 238 heap_stats.new_space_capacity = &new_space_capacity; 239 intptr_t old_space_size; 240 heap_stats.old_space_size = &old_space_size; 241 intptr_t old_space_capacity; 242 heap_stats.old_space_capacity = &old_space_capacity; 243 intptr_t code_space_size; 244 heap_stats.code_space_size = &code_space_size; 245 intptr_t code_space_capacity; 246 heap_stats.code_space_capacity = &code_space_capacity; 247 intptr_t map_space_size; 248 heap_stats.map_space_size = &map_space_size; 249 intptr_t map_space_capacity; 250 heap_stats.map_space_capacity = &map_space_capacity; 251 intptr_t lo_space_size; 252 heap_stats.lo_space_size = &lo_space_size; 253 int global_handle_count; 254 heap_stats.global_handle_count = &global_handle_count; 255 int weak_global_handle_count; 256 heap_stats.weak_global_handle_count = &weak_global_handle_count; 257 int pending_global_handle_count; 258 heap_stats.pending_global_handle_count = &pending_global_handle_count; 259 int near_death_global_handle_count; 260 heap_stats.near_death_global_handle_count = &near_death_global_handle_count; 261 int free_global_handle_count; 262 heap_stats.free_global_handle_count = &free_global_handle_count; 263 intptr_t memory_allocator_size; 264 heap_stats.memory_allocator_size = &memory_allocator_size; 265 intptr_t memory_allocator_capacity; 266 heap_stats.memory_allocator_capacity = &memory_allocator_capacity; 267 int objects_per_type[LAST_TYPE + 1] = {0}; 268 heap_stats.objects_per_type = objects_per_type; 269 int size_per_type[LAST_TYPE + 1] = {0}; 270 heap_stats.size_per_type = size_per_type; 271 int os_error; 272 heap_stats.os_error = &os_error; 273 heap_stats.last_few_messages = last_few_messages; 274 heap_stats.js_stacktrace = js_stacktrace; 275 int end_marker; 276 heap_stats.end_marker = &end_marker; 277 if (isolate->heap()->HasBeenSetUp()) { 278 // BUG(1718): Don't use the take_snapshot since we don't support 279 // HeapIterator here without doing a special GC. 280 isolate->heap()->RecordStats(&heap_stats, false); 281 char* first_newline = strchr(last_few_messages, '\n'); 282 if (first_newline == NULL || first_newline[1] == '\0') 283 first_newline = last_few_messages; 284 PrintF("\n<--- Last few GCs --->\n%s\n", first_newline); 285 PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace); 286 } 287 Utils::ApiCheck(false, location, "Allocation failed - process out of memory"); 288 // If the fatal error handler returns, we stop execution. 289 FATAL("API fatal error handler returned after process out of memory"); 290 } 291 292 293 void Utils::ReportApiFailure(const char* location, const char* message) { 294 i::Isolate* isolate = i::Isolate::Current(); 295 FatalErrorCallback callback = isolate->exception_behavior(); 296 if (callback == NULL) { 297 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location, 298 message); 299 base::OS::Abort(); 300 } else { 301 callback(location, message); 302 } 303 isolate->SignalFatalError(); 304 } 305 306 307 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { 308 if (isolate->has_scheduled_exception()) { 309 return isolate->scheduled_exception() == 310 isolate->heap()->termination_exception(); 311 } 312 return false; 313 } 314 315 316 void V8::SetNativesDataBlob(StartupData* natives_blob) { 317 i::V8::SetNativesBlob(natives_blob); 318 } 319 320 321 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { 322 i::V8::SetSnapshotBlob(snapshot_blob); 323 } 324 325 326 bool RunExtraCode(Isolate* isolate, Local<Context> context, 327 const char* utf8_source) { 328 // Run custom script if provided. 329 base::ElapsedTimer timer; 330 timer.Start(); 331 TryCatch try_catch(isolate); 332 Local<String> source_string; 333 if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal) 334 .ToLocal(&source_string)) { 335 return false; 336 } 337 Local<String> resource_name = 338 String::NewFromUtf8(isolate, "<embedded script>", NewStringType::kNormal) 339 .ToLocalChecked(); 340 ScriptOrigin origin(resource_name); 341 ScriptCompiler::Source source(source_string, origin); 342 Local<Script> script; 343 if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false; 344 if (script->Run(context).IsEmpty()) return false; 345 if (i::FLAG_profile_deserialization) { 346 i::PrintF("Executing custom snapshot script took %0.3f ms\n", 347 timer.Elapsed().InMillisecondsF()); 348 } 349 timer.Stop(); 350 CHECK(!try_catch.HasCaught()); 351 return true; 352 } 353 354 355 namespace { 356 357 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { 358 public: 359 virtual void* Allocate(size_t length) { 360 void* data = AllocateUninitialized(length); 361 return data == NULL ? data : memset(data, 0, length); 362 } 363 virtual void* AllocateUninitialized(size_t length) { return malloc(length); } 364 virtual void Free(void* data, size_t) { free(data); } 365 }; 366 367 } // namespace 368 369 370 StartupData V8::CreateSnapshotDataBlob(const char* custom_source) { 371 i::Isolate* internal_isolate = new i::Isolate(true); 372 ArrayBufferAllocator allocator; 373 internal_isolate->set_array_buffer_allocator(&allocator); 374 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate); 375 StartupData result = {NULL, 0}; 376 { 377 base::ElapsedTimer timer; 378 timer.Start(); 379 Isolate::Scope isolate_scope(isolate); 380 internal_isolate->Init(NULL); 381 Persistent<Context> context; 382 i::Snapshot::Metadata metadata; 383 { 384 HandleScope handle_scope(isolate); 385 Local<Context> new_context = Context::New(isolate); 386 context.Reset(isolate, new_context); 387 if (custom_source != NULL) { 388 metadata.set_embeds_script(true); 389 Context::Scope context_scope(new_context); 390 if (!RunExtraCode(isolate, new_context, custom_source)) context.Reset(); 391 } 392 } 393 if (!context.IsEmpty()) { 394 // If we don't do this then we end up with a stray root pointing at the 395 // context even after we have disposed of the context. 396 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot"); 397 398 // GC may have cleared weak cells, so compact any WeakFixedArrays 399 // found on the heap. 400 i::HeapIterator iterator(internal_isolate->heap(), 401 i::HeapIterator::kFilterUnreachable); 402 for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) { 403 if (o->IsPrototypeInfo()) { 404 i::Object* prototype_users = 405 i::PrototypeInfo::cast(o)->prototype_users(); 406 if (prototype_users->IsWeakFixedArray()) { 407 i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users); 408 array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>(); 409 } 410 } else if (o->IsScript()) { 411 i::Object* shared_list = i::Script::cast(o)->shared_function_infos(); 412 if (shared_list->IsWeakFixedArray()) { 413 i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list); 414 array->Compact<i::WeakFixedArray::NullCallback>(); 415 } 416 } 417 } 418 419 i::Object* raw_context = *v8::Utils::OpenPersistent(context); 420 context.Reset(); 421 422 i::SnapshotByteSink snapshot_sink; 423 i::StartupSerializer ser(internal_isolate, &snapshot_sink); 424 ser.SerializeStrongReferences(); 425 426 i::SnapshotByteSink context_sink; 427 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink); 428 context_ser.Serialize(&raw_context); 429 ser.SerializeWeakReferencesAndDeferred(); 430 431 result = i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata); 432 } 433 if (i::FLAG_profile_deserialization) { 434 i::PrintF("Creating snapshot took %0.3f ms\n", 435 timer.Elapsed().InMillisecondsF()); 436 } 437 timer.Stop(); 438 } 439 isolate->Dispose(); 440 return result; 441 } 442 443 444 void V8::SetFlagsFromString(const char* str, int length) { 445 i::FlagList::SetFlagsFromString(str, length); 446 } 447 448 449 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { 450 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags); 451 } 452 453 454 RegisteredExtension* RegisteredExtension::first_extension_ = NULL; 455 456 457 RegisteredExtension::RegisteredExtension(Extension* extension) 458 : extension_(extension) { } 459 460 461 void RegisteredExtension::Register(RegisteredExtension* that) { 462 that->next_ = first_extension_; 463 first_extension_ = that; 464 } 465 466 467 void RegisteredExtension::UnregisterAll() { 468 RegisteredExtension* re = first_extension_; 469 while (re != NULL) { 470 RegisteredExtension* next = re->next(); 471 delete re; 472 re = next; 473 } 474 first_extension_ = NULL; 475 } 476 477 478 void RegisterExtension(Extension* that) { 479 RegisteredExtension* extension = new RegisteredExtension(that); 480 RegisteredExtension::Register(extension); 481 } 482 483 484 Extension::Extension(const char* name, 485 const char* source, 486 int dep_count, 487 const char** deps, 488 int source_length) 489 : name_(name), 490 source_length_(source_length >= 0 ? 491 source_length : 492 (source ? static_cast<int>(strlen(source)) : 0)), 493 source_(source, source_length_), 494 dep_count_(dep_count), 495 deps_(deps), 496 auto_enable_(false) { 497 CHECK(source != NULL || source_length_ == 0); 498 } 499 500 501 ResourceConstraints::ResourceConstraints() 502 : max_semi_space_size_(0), 503 max_old_space_size_(0), 504 max_executable_size_(0), 505 stack_limit_(NULL), 506 code_range_size_(0) { } 507 508 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, 509 uint64_t virtual_memory_limit) { 510 #if V8_OS_ANDROID 511 // Android has higher physical memory requirements before raising the maximum 512 // heap size limits since it has no swap space. 513 const uint64_t low_limit = 512ul * i::MB; 514 const uint64_t medium_limit = 1ul * i::GB; 515 const uint64_t high_limit = 2ul * i::GB; 516 #else 517 const uint64_t low_limit = 512ul * i::MB; 518 const uint64_t medium_limit = 768ul * i::MB; 519 const uint64_t high_limit = 1ul * i::GB; 520 #endif 521 522 if (physical_memory <= low_limit) { 523 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice); 524 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice); 525 set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice); 526 } else if (physical_memory <= medium_limit) { 527 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice); 528 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice); 529 set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice); 530 } else if (physical_memory <= high_limit) { 531 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice); 532 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice); 533 set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice); 534 } else { 535 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice); 536 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice); 537 set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice); 538 } 539 540 if (virtual_memory_limit > 0 && i::kRequiresCodeRange) { 541 // Reserve no more than 1/8 of the memory for the code range, but at most 542 // kMaximalCodeRangeSize. 543 set_code_range_size( 544 i::Min(i::kMaximalCodeRangeSize / i::MB, 545 static_cast<size_t>((virtual_memory_limit >> 3) / i::MB))); 546 } 547 } 548 549 550 void SetResourceConstraints(i::Isolate* isolate, 551 const ResourceConstraints& constraints) { 552 int semi_space_size = constraints.max_semi_space_size(); 553 int old_space_size = constraints.max_old_space_size(); 554 int max_executable_size = constraints.max_executable_size(); 555 size_t code_range_size = constraints.code_range_size(); 556 if (semi_space_size != 0 || old_space_size != 0 || 557 max_executable_size != 0 || code_range_size != 0) { 558 isolate->heap()->ConfigureHeap(semi_space_size, old_space_size, 559 max_executable_size, code_range_size); 560 } 561 if (constraints.stack_limit() != NULL) { 562 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit()); 563 isolate->stack_guard()->SetStackLimit(limit); 564 } 565 } 566 567 568 i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) { 569 LOG_API(isolate, "Persistent::New"); 570 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj); 571 #ifdef VERIFY_HEAP 572 if (i::FLAG_verify_heap) { 573 (*obj)->ObjectVerify(); 574 } 575 #endif // VERIFY_HEAP 576 return result.location(); 577 } 578 579 580 i::Object** V8::CopyPersistent(i::Object** obj) { 581 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj); 582 #ifdef VERIFY_HEAP 583 if (i::FLAG_verify_heap) { 584 (*obj)->ObjectVerify(); 585 } 586 #endif // VERIFY_HEAP 587 return result.location(); 588 } 589 590 591 void V8::MakeWeak(i::Object** object, void* parameter, 592 WeakCallback weak_callback) { 593 i::GlobalHandles::MakeWeak(object, parameter, weak_callback); 594 } 595 596 597 void V8::MakeWeak(i::Object** object, void* parameter, 598 int internal_field_index1, int internal_field_index2, 599 WeakCallbackInfo<void>::Callback weak_callback) { 600 WeakCallbackType type = WeakCallbackType::kParameter; 601 if (internal_field_index1 == 0) { 602 if (internal_field_index2 == 1) { 603 type = WeakCallbackType::kInternalFields; 604 } else { 605 DCHECK_EQ(internal_field_index2, -1); 606 type = WeakCallbackType::kInternalFields; 607 } 608 } else { 609 DCHECK_EQ(internal_field_index1, -1); 610 DCHECK_EQ(internal_field_index2, -1); 611 } 612 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type); 613 } 614 615 616 void V8::MakeWeak(i::Object** object, void* parameter, 617 WeakCallbackInfo<void>::Callback weak_callback, 618 WeakCallbackType type) { 619 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type); 620 } 621 622 623 void* V8::ClearWeak(i::Object** obj) { 624 return i::GlobalHandles::ClearWeakness(obj); 625 } 626 627 628 void V8::DisposeGlobal(i::Object** obj) { 629 i::GlobalHandles::Destroy(obj); 630 } 631 632 633 void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) { 634 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 635 i::Object* object = *Utils::OpenHandle(value); 636 isolate->eternal_handles()->Create(isolate, object, index); 637 } 638 639 640 Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) { 641 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 642 return Utils::ToLocal(isolate->eternal_handles()->Get(index)); 643 } 644 645 646 void V8::FromJustIsNothing() { 647 Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing."); 648 } 649 650 651 void V8::ToLocalEmpty() { 652 Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal."); 653 } 654 655 656 void V8::InternalFieldOutOfBounds(int index) { 657 Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback, 658 "WeakCallbackInfo::GetInternalField", 659 "Internal field out of bounds."); 660 } 661 662 663 // --- H a n d l e s --- 664 665 666 HandleScope::HandleScope(Isolate* isolate) { 667 Initialize(isolate); 668 } 669 670 671 void HandleScope::Initialize(Isolate* isolate) { 672 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 673 // We do not want to check the correct usage of the Locker class all over the 674 // place, so we do it only here: Without a HandleScope, an embedder can do 675 // almost nothing, so it is enough to check in this central place. 676 // We make an exception if the serializer is enabled, which means that the 677 // Isolate is exclusively used to create a snapshot. 678 Utils::ApiCheck( 679 !v8::Locker::IsActive() || 680 internal_isolate->thread_manager()->IsLockedByCurrentThread() || 681 internal_isolate->serializer_enabled(), 682 "HandleScope::HandleScope", 683 "Entering the V8 API without proper locking in place"); 684 i::HandleScopeData* current = internal_isolate->handle_scope_data(); 685 isolate_ = internal_isolate; 686 prev_next_ = current->next; 687 prev_limit_ = current->limit; 688 current->level++; 689 } 690 691 692 HandleScope::~HandleScope() { 693 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_); 694 } 695 696 697 int HandleScope::NumberOfHandles(Isolate* isolate) { 698 return i::HandleScope::NumberOfHandles( 699 reinterpret_cast<i::Isolate*>(isolate)); 700 } 701 702 703 i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) { 704 return i::HandleScope::CreateHandle(isolate, value); 705 } 706 707 708 i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object, 709 i::Object* value) { 710 DCHECK(heap_object->IsHeapObject()); 711 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value); 712 } 713 714 715 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) { 716 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 717 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value()); 718 Initialize(v8_isolate); 719 } 720 721 722 i::Object** EscapableHandleScope::Escape(i::Object** escape_value) { 723 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap(); 724 Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(), 725 "EscapeableHandleScope::Escape", 726 "Escape value set twice"); 727 if (escape_value == NULL) { 728 *escape_slot_ = heap->undefined_value(); 729 return NULL; 730 } 731 *escape_slot_ = *escape_value; 732 return escape_slot_; 733 } 734 735 736 SealHandleScope::SealHandleScope(Isolate* isolate) { 737 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 738 739 isolate_ = internal_isolate; 740 i::HandleScopeData* current = internal_isolate->handle_scope_data(); 741 prev_limit_ = current->limit; 742 current->limit = current->next; 743 prev_sealed_level_ = current->sealed_level; 744 current->sealed_level = current->level; 745 } 746 747 748 SealHandleScope::~SealHandleScope() { 749 i::HandleScopeData* current = isolate_->handle_scope_data(); 750 DCHECK_EQ(current->next, current->limit); 751 current->limit = prev_limit_; 752 DCHECK_EQ(current->level, current->sealed_level); 753 current->sealed_level = prev_sealed_level_; 754 } 755 756 757 void Context::Enter() { 758 i::Handle<i::Context> env = Utils::OpenHandle(this); 759 i::Isolate* isolate = env->GetIsolate(); 760 ENTER_V8(isolate); 761 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 762 impl->EnterContext(env); 763 impl->SaveContext(isolate->context()); 764 isolate->set_context(*env); 765 } 766 767 768 void Context::Exit() { 769 i::Handle<i::Context> env = Utils::OpenHandle(this); 770 i::Isolate* isolate = env->GetIsolate(); 771 ENTER_V8(isolate); 772 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 773 if (!Utils::ApiCheck(impl->LastEnteredContextWas(env), 774 "v8::Context::Exit()", 775 "Cannot exit non-entered context")) { 776 return; 777 } 778 impl->LeaveContext(); 779 isolate->set_context(impl->RestoreContext()); 780 } 781 782 783 static void* DecodeSmiToAligned(i::Object* value, const char* location) { 784 Utils::ApiCheck(value->IsSmi(), location, "Not a Smi"); 785 return reinterpret_cast<void*>(value); 786 } 787 788 789 static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { 790 i::Smi* smi = reinterpret_cast<i::Smi*>(value); 791 Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned"); 792 return smi; 793 } 794 795 796 static i::Handle<i::FixedArray> EmbedderDataFor(Context* context, 797 int index, 798 bool can_grow, 799 const char* location) { 800 i::Handle<i::Context> env = Utils::OpenHandle(context); 801 i::Isolate* isolate = env->GetIsolate(); 802 bool ok = 803 Utils::ApiCheck(env->IsNativeContext(), 804 location, 805 "Not a native context") && 806 Utils::ApiCheck(index >= 0, location, "Negative index"); 807 if (!ok) return i::Handle<i::FixedArray>(); 808 i::Handle<i::FixedArray> data(env->embedder_data()); 809 if (index < data->length()) return data; 810 if (!Utils::ApiCheck(can_grow, location, "Index too large")) { 811 return i::Handle<i::FixedArray>(); 812 } 813 int new_size = i::Max(index, data->length() << 1) + 1; 814 int grow_by = new_size - data->length(); 815 data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by); 816 env->set_embedder_data(*data); 817 return data; 818 } 819 820 821 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) { 822 const char* location = "v8::Context::GetEmbedderData()"; 823 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); 824 if (data.is_null()) return Local<Value>(); 825 i::Handle<i::Object> result(data->get(index), data->GetIsolate()); 826 return Utils::ToLocal(result); 827 } 828 829 830 void Context::SetEmbedderData(int index, v8::Local<Value> value) { 831 const char* location = "v8::Context::SetEmbedderData()"; 832 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); 833 if (data.is_null()) return; 834 i::Handle<i::Object> val = Utils::OpenHandle(*value); 835 data->set(index, *val); 836 DCHECK_EQ(*Utils::OpenHandle(*value), 837 *Utils::OpenHandle(*GetEmbedderData(index))); 838 } 839 840 841 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { 842 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; 843 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location); 844 if (data.is_null()) return NULL; 845 return DecodeSmiToAligned(data->get(index), location); 846 } 847 848 849 void Context::SetAlignedPointerInEmbedderData(int index, void* value) { 850 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; 851 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location); 852 data->set(index, EncodeAlignedAsSmi(value, location)); 853 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index)); 854 } 855 856 857 // --- N e a n d e r --- 858 859 860 // A constructor cannot easily return an error value, therefore it is necessary 861 // to check for a dead VM with ON_BAILOUT before constructing any Neander 862 // objects. To remind you about this there is no HandleScope in the 863 // NeanderObject constructor. When you add one to the site calling the 864 // constructor you should check that you ensured the VM was not dead first. 865 NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) { 866 ENTER_V8(isolate); 867 value_ = isolate->factory()->NewNeanderObject(); 868 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size); 869 value_->set_elements(*elements); 870 } 871 872 873 int NeanderObject::size() { 874 return i::FixedArray::cast(value_->elements())->length(); 875 } 876 877 878 NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) { 879 obj_.set(0, i::Smi::FromInt(0)); 880 } 881 882 883 int NeanderArray::length() { 884 return i::Smi::cast(obj_.get(0))->value(); 885 } 886 887 888 i::Object* NeanderArray::get(int offset) { 889 DCHECK_LE(0, offset); 890 DCHECK_LT(offset, length()); 891 return obj_.get(offset + 1); 892 } 893 894 895 // This method cannot easily return an error value, therefore it is necessary 896 // to check for a dead VM with ON_BAILOUT before calling it. To remind you 897 // about this there is no HandleScope in this method. When you add one to the 898 // site calling this method you should check that you ensured the VM was not 899 // dead first. 900 void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) { 901 int length = this->length(); 902 int size = obj_.size(); 903 if (length == size - 1) { 904 i::Factory* factory = isolate->factory(); 905 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size); 906 for (int i = 0; i < length; i++) 907 new_elms->set(i + 1, get(i)); 908 obj_.value()->set_elements(*new_elms); 909 } 910 obj_.set(length + 1, *value); 911 obj_.set(0, i::Smi::FromInt(length + 1)); 912 } 913 914 915 void NeanderArray::set(int index, i::Object* value) { 916 if (index < 0 || index >= this->length()) return; 917 obj_.set(index + 1, value); 918 } 919 920 921 // --- T e m p l a t e --- 922 923 924 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) { 925 that->set_number_of_properties(0); 926 that->set_tag(i::Smi::FromInt(type)); 927 } 928 929 930 void Template::Set(v8::Local<Name> name, v8::Local<Data> value, 931 v8::PropertyAttribute attribute) { 932 auto templ = Utils::OpenHandle(this); 933 i::Isolate* isolate = templ->GetIsolate(); 934 ENTER_V8(isolate); 935 i::HandleScope scope(isolate); 936 // TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo. 937 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name), 938 Utils::OpenHandle(*value), 939 static_cast<i::PropertyAttributes>(attribute)); 940 } 941 942 943 void Template::SetAccessorProperty( 944 v8::Local<v8::Name> name, 945 v8::Local<FunctionTemplate> getter, 946 v8::Local<FunctionTemplate> setter, 947 v8::PropertyAttribute attribute, 948 v8::AccessControl access_control) { 949 // TODO(verwaest): Remove |access_control|. 950 DCHECK_EQ(v8::DEFAULT, access_control); 951 auto templ = Utils::OpenHandle(this); 952 auto isolate = templ->GetIsolate(); 953 ENTER_V8(isolate); 954 DCHECK(!name.IsEmpty()); 955 DCHECK(!getter.IsEmpty() || !setter.IsEmpty()); 956 i::HandleScope scope(isolate); 957 i::ApiNatives::AddAccessorProperty( 958 isolate, templ, Utils::OpenHandle(*name), 959 Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true), 960 static_cast<i::PropertyAttributes>(attribute)); 961 } 962 963 964 // --- F u n c t i o n T e m p l a t e --- 965 static void InitializeFunctionTemplate( 966 i::Handle<i::FunctionTemplateInfo> info) { 967 InitializeTemplate(info, Consts::FUNCTION_TEMPLATE); 968 info->set_flag(0); 969 } 970 971 972 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() { 973 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate(); 974 ENTER_V8(i_isolate); 975 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(), 976 i_isolate); 977 if (result->IsUndefined()) { 978 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(i_isolate); 979 result = Utils::OpenHandle(*ObjectTemplate::New(isolate)); 980 Utils::OpenHandle(this)->set_prototype_template(*result); 981 } 982 return ToApiHandle<ObjectTemplate>(result); 983 } 984 985 986 static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info, 987 const char* func) { 988 Utils::ApiCheck(!info->instantiated(), func, 989 "FunctionTemplate already instantiated"); 990 } 991 992 993 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) { 994 auto info = Utils::OpenHandle(this); 995 EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit"); 996 i::Isolate* isolate = info->GetIsolate(); 997 ENTER_V8(isolate); 998 info->set_parent_template(*Utils::OpenHandle(*value)); 999 } 1000 1001 1002 static Local<FunctionTemplate> FunctionTemplateNew( 1003 i::Isolate* isolate, FunctionCallback callback, 1004 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data, 1005 v8::Local<Signature> signature, int length, bool do_not_cache) { 1006 i::Handle<i::Struct> struct_obj = 1007 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE); 1008 i::Handle<i::FunctionTemplateInfo> obj = 1009 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj); 1010 InitializeFunctionTemplate(obj); 1011 obj->set_do_not_cache(do_not_cache); 1012 int next_serial_number = 0; 1013 if (!do_not_cache) { 1014 next_serial_number = isolate->next_serial_number() + 1; 1015 isolate->set_next_serial_number(next_serial_number); 1016 } 1017 obj->set_serial_number(i::Smi::FromInt(next_serial_number)); 1018 if (callback != 0) { 1019 if (data.IsEmpty()) { 1020 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1021 } 1022 Utils::ToLocal(obj)->SetCallHandler(callback, data, fast_handler); 1023 } 1024 obj->set_length(length); 1025 obj->set_undetectable(false); 1026 obj->set_needs_access_check(false); 1027 obj->set_accept_any_receiver(true); 1028 if (!signature.IsEmpty()) 1029 obj->set_signature(*Utils::OpenHandle(*signature)); 1030 return Utils::ToLocal(obj); 1031 } 1032 1033 1034 Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate, 1035 FunctionCallback callback, 1036 v8::Local<Value> data, 1037 v8::Local<Signature> signature, 1038 int length) { 1039 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 1040 // Changes to the environment cannot be captured in the snapshot. Expect no 1041 // function templates when the isolate is created for serialization. 1042 DCHECK(!i_isolate->serializer_enabled()); 1043 LOG_API(i_isolate, "FunctionTemplate::New"); 1044 ENTER_V8(i_isolate); 1045 return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature, 1046 length, false); 1047 } 1048 1049 1050 Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler( 1051 Isolate* isolate, FunctionCallback callback, 1052 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data, 1053 v8::Local<Signature> signature, int length) { 1054 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 1055 DCHECK(!i_isolate->serializer_enabled()); 1056 LOG_API(i_isolate, "FunctionTemplate::NewWithFastHandler"); 1057 ENTER_V8(i_isolate); 1058 return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature, 1059 length, false); 1060 } 1061 1062 1063 Local<Signature> Signature::New(Isolate* isolate, 1064 Local<FunctionTemplate> receiver) { 1065 return Utils::SignatureToLocal(Utils::OpenHandle(*receiver)); 1066 } 1067 1068 1069 Local<AccessorSignature> AccessorSignature::New( 1070 Isolate* isolate, Local<FunctionTemplate> receiver) { 1071 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver)); 1072 } 1073 1074 1075 #define SET_FIELD_WRAPPED(obj, setter, cdata) do { \ 1076 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \ 1077 (obj)->setter(*foreign); \ 1078 } while (false) 1079 1080 1081 void FunctionTemplate::SetCallHandler( 1082 FunctionCallback callback, v8::Local<Value> data, 1083 experimental::FastAccessorBuilder* fast_handler) { 1084 auto info = Utils::OpenHandle(this); 1085 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler"); 1086 i::Isolate* isolate = info->GetIsolate(); 1087 ENTER_V8(isolate); 1088 i::HandleScope scope(isolate); 1089 i::Handle<i::Struct> struct_obj = 1090 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE); 1091 i::Handle<i::CallHandlerInfo> obj = 1092 i::Handle<i::CallHandlerInfo>::cast(struct_obj); 1093 SET_FIELD_WRAPPED(obj, set_callback, callback); 1094 i::MaybeHandle<i::Code> code = 1095 i::experimental::BuildCodeFromFastAccessorBuilder(fast_handler); 1096 if (!code.is_null()) { 1097 obj->set_fast_handler(*code.ToHandleChecked()); 1098 } 1099 if (data.IsEmpty()) { 1100 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1101 } 1102 obj->set_data(*Utils::OpenHandle(*data)); 1103 info->set_call_code(*obj); 1104 } 1105 1106 1107 static i::Handle<i::AccessorInfo> SetAccessorInfoProperties( 1108 i::Handle<i::AccessorInfo> obj, v8::Local<Name> name, 1109 v8::AccessControl settings, v8::PropertyAttribute attributes, 1110 v8::Local<AccessorSignature> signature) { 1111 obj->set_name(*Utils::OpenHandle(*name)); 1112 if (settings & ALL_CAN_READ) obj->set_all_can_read(true); 1113 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true); 1114 obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes)); 1115 if (!signature.IsEmpty()) { 1116 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature)); 1117 } 1118 return obj; 1119 } 1120 1121 1122 template <typename Getter, typename Setter> 1123 static i::Handle<i::AccessorInfo> MakeAccessorInfo( 1124 v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data, 1125 v8::AccessControl settings, v8::PropertyAttribute attributes, 1126 v8::Local<AccessorSignature> signature) { 1127 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate(); 1128 i::Handle<i::ExecutableAccessorInfo> obj = 1129 isolate->factory()->NewExecutableAccessorInfo(); 1130 SET_FIELD_WRAPPED(obj, set_getter, getter); 1131 SET_FIELD_WRAPPED(obj, set_setter, setter); 1132 if (data.IsEmpty()) { 1133 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1134 } 1135 obj->set_data(*Utils::OpenHandle(*data)); 1136 return SetAccessorInfoProperties(obj, name, settings, attributes, signature); 1137 } 1138 1139 1140 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() { 1141 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true); 1142 if (!Utils::ApiCheck(!handle.is_null(), 1143 "v8::FunctionTemplate::InstanceTemplate()", 1144 "Reading from empty handle")) { 1145 return Local<ObjectTemplate>(); 1146 } 1147 i::Isolate* isolate = handle->GetIsolate(); 1148 ENTER_V8(isolate); 1149 if (handle->instance_template()->IsUndefined()) { 1150 Local<ObjectTemplate> templ = 1151 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle)); 1152 handle->set_instance_template(*Utils::OpenHandle(*templ)); 1153 } 1154 i::Handle<i::ObjectTemplateInfo> result( 1155 i::ObjectTemplateInfo::cast(handle->instance_template())); 1156 return Utils::ToLocal(result); 1157 } 1158 1159 1160 void FunctionTemplate::SetLength(int length) { 1161 auto info = Utils::OpenHandle(this); 1162 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength"); 1163 auto isolate = info->GetIsolate(); 1164 ENTER_V8(isolate); 1165 info->set_length(length); 1166 } 1167 1168 1169 void FunctionTemplate::SetClassName(Local<String> name) { 1170 auto info = Utils::OpenHandle(this); 1171 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName"); 1172 auto isolate = info->GetIsolate(); 1173 ENTER_V8(isolate); 1174 info->set_class_name(*Utils::OpenHandle(*name)); 1175 } 1176 1177 1178 void FunctionTemplate::SetAcceptAnyReceiver(bool value) { 1179 auto info = Utils::OpenHandle(this); 1180 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver"); 1181 auto isolate = info->GetIsolate(); 1182 ENTER_V8(isolate); 1183 info->set_accept_any_receiver(value); 1184 } 1185 1186 1187 void FunctionTemplate::SetHiddenPrototype(bool value) { 1188 auto info = Utils::OpenHandle(this); 1189 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype"); 1190 auto isolate = info->GetIsolate(); 1191 ENTER_V8(isolate); 1192 info->set_hidden_prototype(value); 1193 } 1194 1195 1196 void FunctionTemplate::ReadOnlyPrototype() { 1197 auto info = Utils::OpenHandle(this); 1198 EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype"); 1199 auto isolate = info->GetIsolate(); 1200 ENTER_V8(isolate); 1201 info->set_read_only_prototype(true); 1202 } 1203 1204 1205 void FunctionTemplate::RemovePrototype() { 1206 auto info = Utils::OpenHandle(this); 1207 EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype"); 1208 auto isolate = info->GetIsolate(); 1209 ENTER_V8(isolate); 1210 info->set_remove_prototype(true); 1211 } 1212 1213 1214 // --- O b j e c t T e m p l a t e --- 1215 1216 1217 Local<ObjectTemplate> ObjectTemplate::New( 1218 Isolate* isolate, v8::Local<FunctionTemplate> constructor) { 1219 return New(reinterpret_cast<i::Isolate*>(isolate), constructor); 1220 } 1221 1222 1223 Local<ObjectTemplate> ObjectTemplate::New() { 1224 return New(i::Isolate::Current(), Local<FunctionTemplate>()); 1225 } 1226 1227 1228 Local<ObjectTemplate> ObjectTemplate::New( 1229 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) { 1230 // Changes to the environment cannot be captured in the snapshot. Expect no 1231 // object templates when the isolate is created for serialization. 1232 DCHECK(!isolate->serializer_enabled()); 1233 LOG_API(isolate, "ObjectTemplate::New"); 1234 ENTER_V8(isolate); 1235 i::Handle<i::Struct> struct_obj = 1236 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE); 1237 i::Handle<i::ObjectTemplateInfo> obj = 1238 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj); 1239 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE); 1240 if (!constructor.IsEmpty()) 1241 obj->set_constructor(*Utils::OpenHandle(*constructor)); 1242 obj->set_internal_field_count(i::Smi::FromInt(0)); 1243 return Utils::ToLocal(obj); 1244 } 1245 1246 1247 // Ensure that the object template has a constructor. If no 1248 // constructor is available we create one. 1249 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor( 1250 i::Isolate* isolate, 1251 ObjectTemplate* object_template) { 1252 i::Object* obj = Utils::OpenHandle(object_template)->constructor(); 1253 if (!obj ->IsUndefined()) { 1254 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj); 1255 return i::Handle<i::FunctionTemplateInfo>(info, isolate); 1256 } 1257 Local<FunctionTemplate> templ = 1258 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate)); 1259 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ); 1260 constructor->set_instance_template(*Utils::OpenHandle(object_template)); 1261 Utils::OpenHandle(object_template)->set_constructor(*constructor); 1262 return constructor; 1263 } 1264 1265 1266 static inline i::Handle<i::TemplateInfo> GetTemplateInfo( 1267 i::Isolate* isolate, 1268 Template* template_obj) { 1269 return Utils::OpenHandle(template_obj); 1270 } 1271 1272 1273 // TODO(dcarney): remove this with ObjectTemplate::SetAccessor 1274 static inline i::Handle<i::TemplateInfo> GetTemplateInfo( 1275 i::Isolate* isolate, 1276 ObjectTemplate* object_template) { 1277 EnsureConstructor(isolate, object_template); 1278 return Utils::OpenHandle(object_template); 1279 } 1280 1281 1282 template<typename Getter, typename Setter, typename Data, typename Template> 1283 static bool TemplateSetAccessor( 1284 Template* template_obj, 1285 v8::Local<Name> name, 1286 Getter getter, 1287 Setter setter, 1288 Data data, 1289 AccessControl settings, 1290 PropertyAttribute attribute, 1291 v8::Local<AccessorSignature> signature) { 1292 auto isolate = Utils::OpenHandle(template_obj)->GetIsolate(); 1293 ENTER_V8(isolate); 1294 i::HandleScope scope(isolate); 1295 auto obj = MakeAccessorInfo(name, getter, setter, data, settings, attribute, 1296 signature); 1297 if (obj.is_null()) return false; 1298 auto info = GetTemplateInfo(isolate, template_obj); 1299 i::ApiNatives::AddNativeDataProperty(isolate, info, obj); 1300 return true; 1301 } 1302 1303 1304 void Template::SetNativeDataProperty(v8::Local<String> name, 1305 AccessorGetterCallback getter, 1306 AccessorSetterCallback setter, 1307 v8::Local<Value> data, 1308 PropertyAttribute attribute, 1309 v8::Local<AccessorSignature> signature, 1310 AccessControl settings) { 1311 TemplateSetAccessor( 1312 this, name, getter, setter, data, settings, attribute, signature); 1313 } 1314 1315 1316 void Template::SetNativeDataProperty(v8::Local<Name> name, 1317 AccessorNameGetterCallback getter, 1318 AccessorNameSetterCallback setter, 1319 v8::Local<Value> data, 1320 PropertyAttribute attribute, 1321 v8::Local<AccessorSignature> signature, 1322 AccessControl settings) { 1323 TemplateSetAccessor( 1324 this, name, getter, setter, data, settings, attribute, signature); 1325 } 1326 1327 1328 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic, 1329 PropertyAttribute attribute) { 1330 auto templ = Utils::OpenHandle(this); 1331 i::Isolate* isolate = templ->GetIsolate(); 1332 ENTER_V8(isolate); 1333 i::HandleScope scope(isolate); 1334 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name), 1335 intrinsic, 1336 static_cast<i::PropertyAttributes>(attribute)); 1337 } 1338 1339 1340 void ObjectTemplate::SetAccessor(v8::Local<String> name, 1341 AccessorGetterCallback getter, 1342 AccessorSetterCallback setter, 1343 v8::Local<Value> data, AccessControl settings, 1344 PropertyAttribute attribute, 1345 v8::Local<AccessorSignature> signature) { 1346 TemplateSetAccessor( 1347 this, name, getter, setter, data, settings, attribute, signature); 1348 } 1349 1350 1351 void ObjectTemplate::SetAccessor(v8::Local<Name> name, 1352 AccessorNameGetterCallback getter, 1353 AccessorNameSetterCallback setter, 1354 v8::Local<Value> data, AccessControl settings, 1355 PropertyAttribute attribute, 1356 v8::Local<AccessorSignature> signature) { 1357 TemplateSetAccessor( 1358 this, name, getter, setter, data, settings, attribute, signature); 1359 } 1360 1361 1362 template <typename Getter, typename Setter, typename Query, typename Deleter, 1363 typename Enumerator> 1364 static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ, 1365 Getter getter, Setter setter, 1366 Query query, Deleter remover, 1367 Enumerator enumerator, 1368 Local<Value> data, 1369 PropertyHandlerFlags flags) { 1370 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate(); 1371 ENTER_V8(isolate); 1372 i::HandleScope scope(isolate); 1373 auto cons = EnsureConstructor(isolate, templ); 1374 EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler"); 1375 auto obj = i::Handle<i::InterceptorInfo>::cast( 1376 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE)); 1377 obj->set_flags(0); 1378 1379 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter); 1380 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter); 1381 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query); 1382 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover); 1383 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator); 1384 obj->set_can_intercept_symbols( 1385 !(static_cast<int>(flags) & 1386 static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings))); 1387 obj->set_all_can_read(static_cast<int>(flags) & 1388 static_cast<int>(PropertyHandlerFlags::kAllCanRead)); 1389 obj->set_non_masking(static_cast<int>(flags) & 1390 static_cast<int>(PropertyHandlerFlags::kNonMasking)); 1391 1392 if (data.IsEmpty()) { 1393 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1394 } 1395 obj->set_data(*Utils::OpenHandle(*data)); 1396 cons->set_named_property_handler(*obj); 1397 } 1398 1399 1400 void ObjectTemplate::SetNamedPropertyHandler( 1401 NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter, 1402 NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover, 1403 NamedPropertyEnumeratorCallback enumerator, Local<Value> data) { 1404 ObjectTemplateSetNamedPropertyHandler( 1405 this, getter, setter, query, remover, enumerator, data, 1406 PropertyHandlerFlags::kOnlyInterceptStrings); 1407 } 1408 1409 1410 void ObjectTemplate::SetHandler( 1411 const NamedPropertyHandlerConfiguration& config) { 1412 ObjectTemplateSetNamedPropertyHandler( 1413 this, config.getter, config.setter, config.query, config.deleter, 1414 config.enumerator, config.data, config.flags); 1415 } 1416 1417 1418 void ObjectTemplate::MarkAsUndetectable() { 1419 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1420 ENTER_V8(isolate); 1421 i::HandleScope scope(isolate); 1422 auto cons = EnsureConstructor(isolate, this); 1423 EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable"); 1424 cons->set_undetectable(true); 1425 } 1426 1427 1428 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback, 1429 Local<Value> data) { 1430 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1431 ENTER_V8(isolate); 1432 i::HandleScope scope(isolate); 1433 auto cons = EnsureConstructor(isolate, this); 1434 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback"); 1435 1436 i::Handle<i::Struct> struct_info = 1437 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE); 1438 i::Handle<i::AccessCheckInfo> info = 1439 i::Handle<i::AccessCheckInfo>::cast(struct_info); 1440 1441 SET_FIELD_WRAPPED(info, set_callback, callback); 1442 SET_FIELD_WRAPPED(info, set_named_callback, nullptr); 1443 SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr); 1444 1445 if (data.IsEmpty()) { 1446 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1447 } 1448 info->set_data(*Utils::OpenHandle(*data)); 1449 1450 cons->set_access_check_info(*info); 1451 cons->set_needs_access_check(true); 1452 } 1453 1454 1455 void ObjectTemplate::SetAccessCheckCallbacks( 1456 NamedSecurityCallback named_callback, 1457 IndexedSecurityCallback indexed_callback, Local<Value> data) { 1458 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1459 ENTER_V8(isolate); 1460 i::HandleScope scope(isolate); 1461 auto cons = EnsureConstructor(isolate, this); 1462 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallbacks"); 1463 1464 i::Handle<i::Struct> struct_info = 1465 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE); 1466 i::Handle<i::AccessCheckInfo> info = 1467 i::Handle<i::AccessCheckInfo>::cast(struct_info); 1468 1469 SET_FIELD_WRAPPED(info, set_callback, nullptr); 1470 SET_FIELD_WRAPPED(info, set_named_callback, named_callback); 1471 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback); 1472 1473 if (data.IsEmpty()) { 1474 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1475 } 1476 info->set_data(*Utils::OpenHandle(*data)); 1477 1478 cons->set_access_check_info(*info); 1479 cons->set_needs_access_check(true); 1480 } 1481 1482 1483 void ObjectTemplate::SetHandler( 1484 const IndexedPropertyHandlerConfiguration& config) { 1485 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1486 ENTER_V8(isolate); 1487 i::HandleScope scope(isolate); 1488 auto cons = EnsureConstructor(isolate, this); 1489 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler"); 1490 auto obj = i::Handle<i::InterceptorInfo>::cast( 1491 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE)); 1492 obj->set_flags(0); 1493 1494 if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter); 1495 if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter); 1496 if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query); 1497 if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter); 1498 if (config.enumerator != 0) { 1499 SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator); 1500 } 1501 obj->set_all_can_read(static_cast<int>(config.flags) & 1502 static_cast<int>(PropertyHandlerFlags::kAllCanRead)); 1503 1504 v8::Local<v8::Value> data = config.data; 1505 if (data.IsEmpty()) { 1506 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1507 } 1508 obj->set_data(*Utils::OpenHandle(*data)); 1509 cons->set_indexed_property_handler(*obj); 1510 } 1511 1512 1513 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback, 1514 Local<Value> data) { 1515 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1516 ENTER_V8(isolate); 1517 i::HandleScope scope(isolate); 1518 auto cons = EnsureConstructor(isolate, this); 1519 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler"); 1520 i::Handle<i::Struct> struct_obj = 1521 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE); 1522 i::Handle<i::CallHandlerInfo> obj = 1523 i::Handle<i::CallHandlerInfo>::cast(struct_obj); 1524 SET_FIELD_WRAPPED(obj, set_callback, callback); 1525 if (data.IsEmpty()) { 1526 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 1527 } 1528 obj->set_data(*Utils::OpenHandle(*data)); 1529 cons->set_instance_call_handler(*obj); 1530 } 1531 1532 1533 int ObjectTemplate::InternalFieldCount() { 1534 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value(); 1535 } 1536 1537 1538 void ObjectTemplate::SetInternalFieldCount(int value) { 1539 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 1540 if (!Utils::ApiCheck(i::Smi::IsValid(value), 1541 "v8::ObjectTemplate::SetInternalFieldCount()", 1542 "Invalid internal field count")) { 1543 return; 1544 } 1545 ENTER_V8(isolate); 1546 if (value > 0) { 1547 // The internal field count is set by the constructor function's 1548 // construct code, so we ensure that there is a constructor 1549 // function to do the setting. 1550 EnsureConstructor(isolate, this); 1551 } 1552 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value)); 1553 } 1554 1555 1556 // --- S c r i p t s --- 1557 1558 1559 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a 1560 // JSFunction. 1561 1562 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_, 1563 BufferPolicy buffer_policy_) 1564 : data(data_), 1565 length(length_), 1566 rejected(false), 1567 buffer_policy(buffer_policy_) {} 1568 1569 1570 ScriptCompiler::CachedData::~CachedData() { 1571 if (buffer_policy == BufferOwned) { 1572 delete[] data; 1573 } 1574 } 1575 1576 1577 bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; } 1578 1579 1580 void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); } 1581 1582 1583 ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream, 1584 Encoding encoding) 1585 : impl_(new i::StreamedSource(stream, encoding)) {} 1586 1587 1588 ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; } 1589 1590 1591 const ScriptCompiler::CachedData* 1592 ScriptCompiler::StreamedSource::GetCachedData() const { 1593 return impl_->cached_data.get(); 1594 } 1595 1596 1597 Local<Script> UnboundScript::BindToCurrentContext() { 1598 i::Handle<i::HeapObject> obj = 1599 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); 1600 i::Handle<i::SharedFunctionInfo> 1601 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate()); 1602 i::Isolate* isolate = obj->GetIsolate(); 1603 1604 i::ScopeInfo* scope_info = function_info->scope_info(); 1605 i::Handle<i::JSReceiver> global(isolate->native_context()->global_object()); 1606 for (int i = 0; i < scope_info->StrongModeFreeVariableCount(); ++i) { 1607 i::Handle<i::String> name_string(scope_info->StrongModeFreeVariableName(i)); 1608 i::ScriptContextTable::LookupResult result; 1609 i::Handle<i::ScriptContextTable> script_context_table( 1610 isolate->native_context()->script_context_table()); 1611 if (!i::ScriptContextTable::Lookup(script_context_table, name_string, 1612 &result)) { 1613 i::Handle<i::Name> name(scope_info->StrongModeFreeVariableName(i)); 1614 Maybe<bool> has = i::JSReceiver::HasProperty(global, name); 1615 if (has.IsJust() && !has.FromJust()) { 1616 i::PendingCompilationErrorHandler pending_error_handler_; 1617 pending_error_handler_.ReportMessageAt( 1618 scope_info->StrongModeFreeVariableStartPosition(i), 1619 scope_info->StrongModeFreeVariableEndPosition(i), 1620 i::MessageTemplate::kStrongUnboundGlobal, name_string, 1621 i::kReferenceError); 1622 i::Handle<i::Script> script(i::Script::cast(function_info->script())); 1623 pending_error_handler_.ThrowPendingError(isolate, script); 1624 isolate->ReportPendingMessages(); 1625 isolate->OptionalRescheduleException(true); 1626 return Local<Script>(); 1627 } 1628 } 1629 } 1630 i::Handle<i::JSFunction> function = 1631 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo( 1632 function_info, isolate->native_context()); 1633 return ToApiHandle<Script>(function); 1634 } 1635 1636 1637 int UnboundScript::GetId() { 1638 i::Handle<i::HeapObject> obj = 1639 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this)); 1640 i::Isolate* isolate = obj->GetIsolate(); 1641 LOG_API(isolate, "v8::UnboundScript::GetId"); 1642 i::HandleScope scope(isolate); 1643 i::Handle<i::SharedFunctionInfo> function_info( 1644 i::SharedFunctionInfo::cast(*obj)); 1645 i::Handle<i::Script> script(i::Script::cast(function_info->script())); 1646 return script->id(); 1647 } 1648 1649 1650 int UnboundScript::GetLineNumber(int code_pos) { 1651 i::Handle<i::SharedFunctionInfo> obj = 1652 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); 1653 i::Isolate* isolate = obj->GetIsolate(); 1654 LOG_API(isolate, "UnboundScript::GetLineNumber"); 1655 if (obj->script()->IsScript()) { 1656 i::Handle<i::Script> script(i::Script::cast(obj->script())); 1657 return i::Script::GetLineNumber(script, code_pos); 1658 } else { 1659 return -1; 1660 } 1661 } 1662 1663 1664 Local<Value> UnboundScript::GetScriptName() { 1665 i::Handle<i::SharedFunctionInfo> obj = 1666 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); 1667 i::Isolate* isolate = obj->GetIsolate(); 1668 LOG_API(isolate, "UnboundScript::GetName"); 1669 if (obj->script()->IsScript()) { 1670 i::Object* name = i::Script::cast(obj->script())->name(); 1671 return Utils::ToLocal(i::Handle<i::Object>(name, isolate)); 1672 } else { 1673 return Local<String>(); 1674 } 1675 } 1676 1677 1678 Local<Value> UnboundScript::GetSourceURL() { 1679 i::Handle<i::SharedFunctionInfo> obj = 1680 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); 1681 i::Isolate* isolate = obj->GetIsolate(); 1682 LOG_API(isolate, "UnboundScript::GetSourceURL"); 1683 if (obj->script()->IsScript()) { 1684 i::Object* url = i::Script::cast(obj->script())->source_url(); 1685 return Utils::ToLocal(i::Handle<i::Object>(url, isolate)); 1686 } else { 1687 return Local<String>(); 1688 } 1689 } 1690 1691 1692 Local<Value> UnboundScript::GetSourceMappingURL() { 1693 i::Handle<i::SharedFunctionInfo> obj = 1694 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this)); 1695 i::Isolate* isolate = obj->GetIsolate(); 1696 LOG_API(isolate, "UnboundScript::GetSourceMappingURL"); 1697 if (obj->script()->IsScript()) { 1698 i::Object* url = i::Script::cast(obj->script())->source_mapping_url(); 1699 return Utils::ToLocal(i::Handle<i::Object>(url, isolate)); 1700 } else { 1701 return Local<String>(); 1702 } 1703 } 1704 1705 1706 MaybeLocal<Value> Script::Run(Local<Context> context) { 1707 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Script::Run()", Value) 1708 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy()); 1709 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); 1710 auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this)); 1711 i::Handle<i::Object> receiver(isolate->global_proxy(), isolate); 1712 Local<Value> result; 1713 has_pending_exception = 1714 !ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL), 1715 &result); 1716 RETURN_ON_FAILED_EXECUTION(Value); 1717 RETURN_ESCAPED(result); 1718 } 1719 1720 1721 Local<Value> Script::Run() { 1722 auto self = Utils::OpenHandle(this, true); 1723 // If execution is terminating, Compile(..)->Run() requires this 1724 // check. 1725 if (self.is_null()) return Local<Value>(); 1726 auto context = ContextFromHeapObject(self); 1727 RETURN_TO_LOCAL_UNCHECKED(Run(context), Value); 1728 } 1729 1730 1731 Local<UnboundScript> Script::GetUnboundScript() { 1732 i::Handle<i::Object> obj = Utils::OpenHandle(this); 1733 return ToApiHandle<UnboundScript>( 1734 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared())); 1735 } 1736 1737 1738 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal( 1739 Isolate* v8_isolate, Source* source, CompileOptions options, 1740 bool is_module) { 1741 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 1742 PREPARE_FOR_EXECUTION_WITH_ISOLATE( 1743 isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript); 1744 1745 // Don't try to produce any kind of cache when the debugger is loaded. 1746 if (isolate->debug()->is_loaded() && 1747 (options == kProduceParserCache || options == kProduceCodeCache)) { 1748 options = kNoCompileOptions; 1749 } 1750 1751 i::ScriptData* script_data = NULL; 1752 if (options == kConsumeParserCache || options == kConsumeCodeCache) { 1753 DCHECK(source->cached_data); 1754 // ScriptData takes care of pointer-aligning the data. 1755 script_data = new i::ScriptData(source->cached_data->data, 1756 source->cached_data->length); 1757 } 1758 1759 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string)); 1760 i::Handle<i::SharedFunctionInfo> result; 1761 { 1762 i::HistogramTimerScope total(isolate->counters()->compile_script(), true); 1763 i::Handle<i::Object> name_obj; 1764 i::Handle<i::Object> source_map_url; 1765 int line_offset = 0; 1766 int column_offset = 0; 1767 if (!source->resource_name.IsEmpty()) { 1768 name_obj = Utils::OpenHandle(*(source->resource_name)); 1769 } 1770 if (!source->resource_line_offset.IsEmpty()) { 1771 line_offset = static_cast<int>(source->resource_line_offset->Value()); 1772 } 1773 if (!source->resource_column_offset.IsEmpty()) { 1774 column_offset = 1775 static_cast<int>(source->resource_column_offset->Value()); 1776 } 1777 if (!source->source_map_url.IsEmpty()) { 1778 source_map_url = Utils::OpenHandle(*(source->source_map_url)); 1779 } 1780 result = i::Compiler::CompileScript( 1781 str, name_obj, line_offset, column_offset, source->resource_options, 1782 source_map_url, isolate->native_context(), NULL, &script_data, options, 1783 i::NOT_NATIVES_CODE, is_module); 1784 has_pending_exception = result.is_null(); 1785 if (has_pending_exception && script_data != NULL) { 1786 // This case won't happen during normal operation; we have compiled 1787 // successfully and produced cached data, and but the second compilation 1788 // of the same source code fails. 1789 delete script_data; 1790 script_data = NULL; 1791 } 1792 RETURN_ON_FAILED_EXECUTION(UnboundScript); 1793 1794 if ((options == kProduceParserCache || options == kProduceCodeCache) && 1795 script_data != NULL) { 1796 // script_data now contains the data that was generated. source will 1797 // take the ownership. 1798 source->cached_data = new CachedData( 1799 script_data->data(), script_data->length(), CachedData::BufferOwned); 1800 script_data->ReleaseDataOwnership(); 1801 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) { 1802 source->cached_data->rejected = script_data->rejected(); 1803 } 1804 delete script_data; 1805 } 1806 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result)); 1807 } 1808 1809 1810 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript( 1811 Isolate* v8_isolate, Source* source, CompileOptions options) { 1812 return CompileUnboundInternal(v8_isolate, source, options, false); 1813 } 1814 1815 1816 Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate, 1817 Source* source, 1818 CompileOptions options) { 1819 RETURN_TO_LOCAL_UNCHECKED( 1820 CompileUnboundInternal(v8_isolate, source, options, false), 1821 UnboundScript); 1822 } 1823 1824 1825 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, 1826 Source* source, 1827 CompileOptions options) { 1828 auto isolate = context->GetIsolate(); 1829 auto maybe = CompileUnboundInternal(isolate, source, options, false); 1830 Local<UnboundScript> result; 1831 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>(); 1832 v8::Context::Scope scope(context); 1833 return result->BindToCurrentContext(); 1834 } 1835 1836 1837 Local<Script> ScriptCompiler::Compile( 1838 Isolate* v8_isolate, 1839 Source* source, 1840 CompileOptions options) { 1841 auto context = v8_isolate->GetCurrentContext(); 1842 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script); 1843 } 1844 1845 1846 MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context, 1847 Source* source, 1848 CompileOptions options) { 1849 CHECK(i::FLAG_harmony_modules); 1850 auto isolate = context->GetIsolate(); 1851 auto maybe = CompileUnboundInternal(isolate, source, options, true); 1852 Local<UnboundScript> generic; 1853 if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>(); 1854 v8::Context::Scope scope(context); 1855 return generic->BindToCurrentContext(); 1856 } 1857 1858 1859 class IsIdentifierHelper { 1860 public: 1861 IsIdentifierHelper() : is_identifier_(false), first_char_(true) {} 1862 1863 bool Check(i::String* string) { 1864 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); 1865 if (cons_string == NULL) return is_identifier_; 1866 // We don't support cons strings here. 1867 return false; 1868 } 1869 void VisitOneByteString(const uint8_t* chars, int length) { 1870 for (int i = 0; i < length; ++i) { 1871 if (first_char_) { 1872 first_char_ = false; 1873 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]); 1874 } else { 1875 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]); 1876 } 1877 } 1878 } 1879 void VisitTwoByteString(const uint16_t* chars, int length) { 1880 for (int i = 0; i < length; ++i) { 1881 if (first_char_) { 1882 first_char_ = false; 1883 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]); 1884 } else { 1885 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]); 1886 } 1887 } 1888 } 1889 1890 private: 1891 bool is_identifier_; 1892 bool first_char_; 1893 i::UnicodeCache unicode_cache_; 1894 DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper); 1895 }; 1896 1897 1898 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext( 1899 Local<Context> v8_context, Source* source, size_t arguments_count, 1900 Local<String> arguments[], size_t context_extension_count, 1901 Local<Object> context_extensions[]) { 1902 PREPARE_FOR_EXECUTION( 1903 v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function); 1904 i::Handle<i::String> source_string; 1905 auto factory = isolate->factory(); 1906 if (arguments_count) { 1907 source_string = factory->NewStringFromStaticChars("(function("); 1908 for (size_t i = 0; i < arguments_count; ++i) { 1909 IsIdentifierHelper helper; 1910 if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) { 1911 return Local<Function>(); 1912 } 1913 has_pending_exception = 1914 !factory->NewConsString(source_string, 1915 Utils::OpenHandle(*arguments[i])) 1916 .ToHandle(&source_string); 1917 RETURN_ON_FAILED_EXECUTION(Function); 1918 if (i + 1 == arguments_count) continue; 1919 has_pending_exception = 1920 !factory->NewConsString(source_string, 1921 factory->LookupSingleCharacterStringFromCode( 1922 ',')).ToHandle(&source_string); 1923 RETURN_ON_FAILED_EXECUTION(Function); 1924 } 1925 auto brackets = factory->NewStringFromStaticChars("){"); 1926 has_pending_exception = !factory->NewConsString(source_string, brackets) 1927 .ToHandle(&source_string); 1928 RETURN_ON_FAILED_EXECUTION(Function); 1929 } else { 1930 source_string = factory->NewStringFromStaticChars("(function(){"); 1931 } 1932 1933 int scope_position = source_string->length(); 1934 has_pending_exception = 1935 !factory->NewConsString(source_string, 1936 Utils::OpenHandle(*source->source_string)) 1937 .ToHandle(&source_string); 1938 RETURN_ON_FAILED_EXECUTION(Function); 1939 // Include \n in case the source contains a line end comment. 1940 auto brackets = factory->NewStringFromStaticChars("\n})"); 1941 has_pending_exception = 1942 !factory->NewConsString(source_string, brackets).ToHandle(&source_string); 1943 RETURN_ON_FAILED_EXECUTION(Function); 1944 1945 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context); 1946 i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(), 1947 isolate); 1948 for (size_t i = 0; i < context_extension_count; ++i) { 1949 i::Handle<i::JSReceiver> extension = 1950 Utils::OpenHandle(*context_extensions[i]); 1951 if (!extension->IsJSObject()) return Local<Function>(); 1952 i::Handle<i::JSFunction> closure(context->closure(), isolate); 1953 context = factory->NewWithContext(closure, context, extension); 1954 } 1955 1956 i::Handle<i::Object> name_obj; 1957 int line_offset = 0; 1958 int column_offset = 0; 1959 if (!source->resource_name.IsEmpty()) { 1960 name_obj = Utils::OpenHandle(*(source->resource_name)); 1961 } 1962 if (!source->resource_line_offset.IsEmpty()) { 1963 line_offset = static_cast<int>(source->resource_line_offset->Value()); 1964 } 1965 if (!source->resource_column_offset.IsEmpty()) { 1966 column_offset = static_cast<int>(source->resource_column_offset->Value()); 1967 } 1968 i::Handle<i::JSFunction> fun; 1969 has_pending_exception = !i::Compiler::GetFunctionFromEval( 1970 source_string, outer_info, context, i::SLOPPY, 1971 i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset, 1972 column_offset - scope_position, name_obj, 1973 source->resource_options).ToHandle(&fun); 1974 if (has_pending_exception) { 1975 isolate->ReportPendingMessages(); 1976 } 1977 RETURN_ON_FAILED_EXECUTION(Function); 1978 1979 i::Handle<i::Object> result; 1980 has_pending_exception = 1981 !i::Execution::Call(isolate, fun, 1982 Utils::OpenHandle(*v8_context->Global()), 0, 1983 nullptr).ToHandle(&result); 1984 RETURN_ON_FAILED_EXECUTION(Function); 1985 RETURN_ESCAPED( 1986 Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result))); 1987 } 1988 1989 1990 Local<Function> ScriptCompiler::CompileFunctionInContext( 1991 Isolate* v8_isolate, Source* source, Local<Context> v8_context, 1992 size_t arguments_count, Local<String> arguments[], 1993 size_t context_extension_count, Local<Object> context_extensions[]) { 1994 RETURN_TO_LOCAL_UNCHECKED( 1995 CompileFunctionInContext(v8_context, source, arguments_count, arguments, 1996 context_extension_count, context_extensions), 1997 Function); 1998 } 1999 2000 2001 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( 2002 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) { 2003 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 2004 return new i::BackgroundParsingTask(source->impl(), options, 2005 i::FLAG_stack_size, isolate); 2006 } 2007 2008 2009 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context, 2010 StreamedSource* v8_source, 2011 Local<String> full_source_string, 2012 const ScriptOrigin& origin) { 2013 PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script); 2014 i::StreamedSource* source = v8_source->impl(); 2015 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string)); 2016 i::Handle<i::Script> script = isolate->factory()->NewScript(str); 2017 if (!origin.ResourceName().IsEmpty()) { 2018 script->set_name(*Utils::OpenHandle(*(origin.ResourceName()))); 2019 } 2020 if (!origin.ResourceLineOffset().IsEmpty()) { 2021 script->set_line_offset( 2022 static_cast<int>(origin.ResourceLineOffset()->Value())); 2023 } 2024 if (!origin.ResourceColumnOffset().IsEmpty()) { 2025 script->set_column_offset( 2026 static_cast<int>(origin.ResourceColumnOffset()->Value())); 2027 } 2028 script->set_origin_options(origin.Options()); 2029 if (!origin.SourceMapUrl().IsEmpty()) { 2030 script->set_source_mapping_url( 2031 *Utils::OpenHandle(*(origin.SourceMapUrl()))); 2032 } 2033 2034 source->info->set_script(script); 2035 source->info->set_context(isolate->native_context()); 2036 2037 // Do the parsing tasks which need to be done on the main thread. This will 2038 // also handle parse errors. 2039 source->parser->Internalize(isolate, script, 2040 source->info->literal() == nullptr); 2041 source->parser->HandleSourceURLComments(isolate, script); 2042 2043 i::Handle<i::SharedFunctionInfo> result; 2044 if (source->info->literal() != nullptr) { 2045 // Parsing has succeeded. 2046 result = i::Compiler::CompileStreamedScript(script, source->info.get(), 2047 str->length()); 2048 } 2049 has_pending_exception = result.is_null(); 2050 if (has_pending_exception) isolate->ReportPendingMessages(); 2051 RETURN_ON_FAILED_EXECUTION(Script); 2052 2053 source->info->clear_script(); // because script goes out of scope. 2054 2055 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result); 2056 if (generic.IsEmpty()) return Local<Script>(); 2057 Local<Script> bound = generic->BindToCurrentContext(); 2058 if (bound.IsEmpty()) return Local<Script>(); 2059 RETURN_ESCAPED(bound); 2060 } 2061 2062 2063 Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate, 2064 StreamedSource* v8_source, 2065 Local<String> full_source_string, 2066 const ScriptOrigin& origin) { 2067 auto context = v8_isolate->GetCurrentContext(); 2068 RETURN_TO_LOCAL_UNCHECKED( 2069 Compile(context, v8_source, full_source_string, origin), Script); 2070 } 2071 2072 2073 uint32_t ScriptCompiler::CachedDataVersionTag() { 2074 return static_cast<uint32_t>(base::hash_combine( 2075 internal::Version::Hash(), internal::FlagList::Hash(), 2076 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures()))); 2077 } 2078 2079 2080 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source, 2081 ScriptOrigin* origin) { 2082 if (origin) { 2083 ScriptCompiler::Source script_source(source, *origin); 2084 return ScriptCompiler::Compile(context, &script_source); 2085 } 2086 ScriptCompiler::Source script_source(source); 2087 return ScriptCompiler::Compile(context, &script_source); 2088 } 2089 2090 2091 Local<Script> Script::Compile(v8::Local<String> source, 2092 v8::ScriptOrigin* origin) { 2093 auto str = Utils::OpenHandle(*source); 2094 auto context = ContextFromHeapObject(str); 2095 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script); 2096 } 2097 2098 2099 Local<Script> Script::Compile(v8::Local<String> source, 2100 v8::Local<String> file_name) { 2101 auto str = Utils::OpenHandle(*source); 2102 auto context = ContextFromHeapObject(str); 2103 ScriptOrigin origin(file_name); 2104 return Compile(context, source, &origin).FromMaybe(Local<Script>()); 2105 } 2106 2107 2108 // --- E x c e p t i o n s --- 2109 2110 2111 v8::TryCatch::TryCatch() 2112 : isolate_(i::Isolate::Current()), 2113 next_(isolate_->try_catch_handler()), 2114 is_verbose_(false), 2115 can_continue_(true), 2116 capture_message_(true), 2117 rethrow_(false), 2118 has_terminated_(false) { 2119 ResetInternal(); 2120 // Special handling for simulators which have a separate JS stack. 2121 js_stack_comparable_address_ = 2122 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch( 2123 isolate_, v8::internal::GetCurrentStackPosition())); 2124 isolate_->RegisterTryCatchHandler(this); 2125 } 2126 2127 2128 v8::TryCatch::TryCatch(v8::Isolate* isolate) 2129 : isolate_(reinterpret_cast<i::Isolate*>(isolate)), 2130 next_(isolate_->try_catch_handler()), 2131 is_verbose_(false), 2132 can_continue_(true), 2133 capture_message_(true), 2134 rethrow_(false), 2135 has_terminated_(false) { 2136 ResetInternal(); 2137 // Special handling for simulators which have a separate JS stack. 2138 js_stack_comparable_address_ = 2139 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch( 2140 isolate_, v8::internal::GetCurrentStackPosition())); 2141 isolate_->RegisterTryCatchHandler(this); 2142 } 2143 2144 2145 v8::TryCatch::~TryCatch() { 2146 if (rethrow_) { 2147 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_); 2148 v8::HandleScope scope(isolate); 2149 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception()); 2150 if (HasCaught() && capture_message_) { 2151 // If an exception was caught and rethrow_ is indicated, the saved 2152 // message, script, and location need to be restored to Isolate TLS 2153 // for reuse. capture_message_ needs to be disabled so that Throw() 2154 // does not create a new message. 2155 isolate_->thread_local_top()->rethrowing_message_ = true; 2156 isolate_->RestorePendingMessageFromTryCatch(this); 2157 } 2158 isolate_->UnregisterTryCatchHandler(this); 2159 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_); 2160 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc); 2161 DCHECK(!isolate_->thread_local_top()->rethrowing_message_); 2162 } else { 2163 if (HasCaught() && isolate_->has_scheduled_exception()) { 2164 // If an exception was caught but is still scheduled because no API call 2165 // promoted it, then it is canceled to prevent it from being propagated. 2166 // Note that this will not cancel termination exceptions. 2167 isolate_->CancelScheduledExceptionFromTryCatch(this); 2168 } 2169 isolate_->UnregisterTryCatchHandler(this); 2170 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_); 2171 } 2172 } 2173 2174 2175 bool v8::TryCatch::HasCaught() const { 2176 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole(); 2177 } 2178 2179 2180 bool v8::TryCatch::CanContinue() const { 2181 return can_continue_; 2182 } 2183 2184 2185 bool v8::TryCatch::HasTerminated() const { 2186 return has_terminated_; 2187 } 2188 2189 2190 v8::Local<v8::Value> v8::TryCatch::ReThrow() { 2191 if (!HasCaught()) return v8::Local<v8::Value>(); 2192 rethrow_ = true; 2193 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_)); 2194 } 2195 2196 2197 v8::Local<Value> v8::TryCatch::Exception() const { 2198 if (HasCaught()) { 2199 // Check for out of memory exception. 2200 i::Object* exception = reinterpret_cast<i::Object*>(exception_); 2201 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_)); 2202 } else { 2203 return v8::Local<Value>(); 2204 } 2205 } 2206 2207 2208 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const { 2209 if (!HasCaught()) return v8::Local<Value>(); 2210 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_); 2211 if (!raw_obj->IsJSObject()) return v8::Local<Value>(); 2212 PREPARE_FOR_EXECUTION(context, "v8::TryCatch::StackTrace", Value); 2213 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_); 2214 i::Handle<i::String> name = isolate->factory()->stack_string(); 2215 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name); 2216 has_pending_exception = !maybe.IsJust(); 2217 RETURN_ON_FAILED_EXECUTION(Value); 2218 if (!maybe.FromJust()) return v8::Local<Value>(); 2219 Local<Value> result; 2220 has_pending_exception = 2221 !ToLocal<Value>(i::Object::GetProperty(obj, name), &result); 2222 RETURN_ON_FAILED_EXECUTION(Value); 2223 RETURN_ESCAPED(result); 2224 } 2225 2226 2227 v8::Local<Value> v8::TryCatch::StackTrace() const { 2228 auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext(); 2229 RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value); 2230 } 2231 2232 2233 v8::Local<v8::Message> v8::TryCatch::Message() const { 2234 i::Object* message = reinterpret_cast<i::Object*>(message_obj_); 2235 DCHECK(message->IsJSMessageObject() || message->IsTheHole()); 2236 if (HasCaught() && !message->IsTheHole()) { 2237 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_)); 2238 } else { 2239 return v8::Local<v8::Message>(); 2240 } 2241 } 2242 2243 2244 void v8::TryCatch::Reset() { 2245 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) { 2246 // If an exception was caught but is still scheduled because no API call 2247 // promoted it, then it is canceled to prevent it from being propagated. 2248 // Note that this will not cancel termination exceptions. 2249 isolate_->CancelScheduledExceptionFromTryCatch(this); 2250 } 2251 ResetInternal(); 2252 } 2253 2254 2255 void v8::TryCatch::ResetInternal() { 2256 i::Object* the_hole = isolate_->heap()->the_hole_value(); 2257 exception_ = the_hole; 2258 message_obj_ = the_hole; 2259 } 2260 2261 2262 void v8::TryCatch::SetVerbose(bool value) { 2263 is_verbose_ = value; 2264 } 2265 2266 2267 void v8::TryCatch::SetCaptureMessage(bool value) { 2268 capture_message_ = value; 2269 } 2270 2271 2272 // --- M e s s a g e --- 2273 2274 2275 Local<String> Message::Get() const { 2276 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2277 ENTER_V8(isolate); 2278 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); 2279 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2280 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj); 2281 Local<String> result = Utils::ToLocal(raw_result); 2282 return scope.Escape(result); 2283 } 2284 2285 2286 ScriptOrigin Message::GetScriptOrigin() const { 2287 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2288 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this)); 2289 auto script_wraper = i::Handle<i::Object>(message->script(), isolate); 2290 auto script_value = i::Handle<i::JSValue>::cast(script_wraper); 2291 i::Handle<i::Script> script(i::Script::cast(script_value->value())); 2292 return GetScriptOriginForScript(isolate, script); 2293 } 2294 2295 2296 v8::Local<Value> Message::GetScriptResourceName() const { 2297 return GetScriptOrigin().ResourceName(); 2298 } 2299 2300 2301 v8::Local<v8::StackTrace> Message::GetStackTrace() const { 2302 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2303 ENTER_V8(isolate); 2304 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); 2305 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this)); 2306 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate); 2307 if (!stackFramesObj->IsJSArray()) return v8::Local<v8::StackTrace>(); 2308 auto stackTrace = i::Handle<i::JSArray>::cast(stackFramesObj); 2309 return scope.Escape(Utils::StackTraceToLocal(stackTrace)); 2310 } 2311 2312 2313 Maybe<int> Message::GetLineNumber(Local<Context> context) const { 2314 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int); 2315 i::Handle<i::JSFunction> fun = isolate->message_get_line_number(); 2316 i::Handle<i::Object> undefined = isolate->factory()->undefined_value(); 2317 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)}; 2318 i::Handle<i::Object> result; 2319 has_pending_exception = 2320 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args) 2321 .ToHandle(&result); 2322 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); 2323 return Just(static_cast<int>(result->Number())); 2324 } 2325 2326 2327 int Message::GetLineNumber() const { 2328 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 2329 return GetLineNumber(context).FromMaybe(0); 2330 } 2331 2332 2333 int Message::GetStartPosition() const { 2334 auto self = Utils::OpenHandle(this); 2335 return self->start_position(); 2336 } 2337 2338 2339 int Message::GetEndPosition() const { 2340 auto self = Utils::OpenHandle(this); 2341 return self->end_position(); 2342 } 2343 2344 2345 Maybe<int> Message::GetStartColumn(Local<Context> context) const { 2346 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetStartColumn()", 2347 int); 2348 i::Handle<i::JSFunction> fun = isolate->message_get_column_number(); 2349 i::Handle<i::Object> undefined = isolate->factory()->undefined_value(); 2350 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)}; 2351 i::Handle<i::Object> result; 2352 has_pending_exception = 2353 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args) 2354 .ToHandle(&result); 2355 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); 2356 return Just(static_cast<int>(result->Number())); 2357 } 2358 2359 2360 int Message::GetStartColumn() const { 2361 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 2362 const int default_value = kNoColumnInfo; 2363 return GetStartColumn(context).FromMaybe(default_value); 2364 } 2365 2366 2367 Maybe<int> Message::GetEndColumn(Local<Context> context) const { 2368 auto self = Utils::OpenHandle(this); 2369 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int); 2370 i::Handle<i::JSFunction> fun = isolate->message_get_column_number(); 2371 i::Handle<i::Object> undefined = isolate->factory()->undefined_value(); 2372 i::Handle<i::Object> args[] = {self}; 2373 i::Handle<i::Object> result; 2374 has_pending_exception = 2375 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args) 2376 .ToHandle(&result); 2377 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); 2378 int start = self->start_position(); 2379 int end = self->end_position(); 2380 return Just(static_cast<int>(result->Number()) + (end - start)); 2381 } 2382 2383 2384 int Message::GetEndColumn() const { 2385 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 2386 const int default_value = kNoColumnInfo; 2387 return GetEndColumn(context).FromMaybe(default_value); 2388 } 2389 2390 2391 bool Message::IsSharedCrossOrigin() const { 2392 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2393 ENTER_V8(isolate); 2394 auto self = Utils::OpenHandle(this); 2395 auto script = i::Handle<i::JSValue>::cast( 2396 i::Handle<i::Object>(self->script(), isolate)); 2397 return i::Script::cast(script->value()) 2398 ->origin_options() 2399 .IsSharedCrossOrigin(); 2400 } 2401 2402 bool Message::IsOpaque() const { 2403 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2404 ENTER_V8(isolate); 2405 auto self = Utils::OpenHandle(this); 2406 auto script = i::Handle<i::JSValue>::cast( 2407 i::Handle<i::Object>(self->script(), isolate)); 2408 return i::Script::cast(script->value())->origin_options().IsOpaque(); 2409 } 2410 2411 2412 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const { 2413 PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String); 2414 i::Handle<i::JSFunction> fun = isolate->message_get_source_line(); 2415 i::Handle<i::Object> undefined = isolate->factory()->undefined_value(); 2416 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)}; 2417 i::Handle<i::Object> result; 2418 has_pending_exception = 2419 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args) 2420 .ToHandle(&result); 2421 RETURN_ON_FAILED_EXECUTION(String); 2422 Local<String> str; 2423 if (result->IsString()) { 2424 str = Utils::ToLocal(i::Handle<i::String>::cast(result)); 2425 } 2426 RETURN_ESCAPED(str); 2427 } 2428 2429 2430 Local<String> Message::GetSourceLine() const { 2431 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 2432 RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String) 2433 } 2434 2435 2436 void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { 2437 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 2438 ENTER_V8(i_isolate); 2439 i_isolate->PrintCurrentStackTrace(out); 2440 } 2441 2442 2443 // --- S t a c k T r a c e --- 2444 2445 Local<StackFrame> StackTrace::GetFrame(uint32_t index) const { 2446 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 2447 ENTER_V8(isolate); 2448 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); 2449 auto self = Utils::OpenHandle(this); 2450 auto obj = i::Object::GetElement(isolate, self, index).ToHandleChecked(); 2451 auto jsobj = i::Handle<i::JSObject>::cast(obj); 2452 return scope.Escape(Utils::StackFrameToLocal(jsobj)); 2453 } 2454 2455 2456 int StackTrace::GetFrameCount() const { 2457 return i::Smi::cast(Utils::OpenHandle(this)->length())->value(); 2458 } 2459 2460 2461 Local<Array> StackTrace::AsArray() { 2462 return Utils::ToLocal(Utils::OpenHandle(this)); 2463 } 2464 2465 2466 Local<StackTrace> StackTrace::CurrentStackTrace( 2467 Isolate* isolate, 2468 int frame_limit, 2469 StackTraceOptions options) { 2470 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 2471 ENTER_V8(i_isolate); 2472 // TODO(dcarney): remove when ScriptDebugServer is fixed. 2473 options = static_cast<StackTraceOptions>( 2474 static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins); 2475 i::Handle<i::JSArray> stackTrace = 2476 i_isolate->CaptureCurrentStackTrace(frame_limit, options); 2477 return Utils::StackTraceToLocal(stackTrace); 2478 } 2479 2480 2481 // --- S t a c k F r a m e --- 2482 2483 static int getIntProperty(const StackFrame* f, const char* propertyName, 2484 int defaultValue) { 2485 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate(); 2486 ENTER_V8(isolate); 2487 i::HandleScope scope(isolate); 2488 i::Handle<i::JSObject> self = Utils::OpenHandle(f); 2489 i::Handle<i::Object> obj = 2490 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked(); 2491 return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue; 2492 } 2493 2494 2495 int StackFrame::GetLineNumber() const { 2496 return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo); 2497 } 2498 2499 2500 int StackFrame::GetColumn() const { 2501 return getIntProperty(this, "column", Message::kNoColumnInfo); 2502 } 2503 2504 2505 int StackFrame::GetScriptId() const { 2506 return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo); 2507 } 2508 2509 2510 static Local<String> getStringProperty(const StackFrame* f, 2511 const char* propertyName) { 2512 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate(); 2513 ENTER_V8(isolate); 2514 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate)); 2515 i::Handle<i::JSObject> self = Utils::OpenHandle(f); 2516 i::Handle<i::Object> obj = 2517 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked(); 2518 return obj->IsString() 2519 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj))) 2520 : Local<String>(); 2521 } 2522 2523 2524 Local<String> StackFrame::GetScriptName() const { 2525 return getStringProperty(this, "scriptName"); 2526 } 2527 2528 2529 Local<String> StackFrame::GetScriptNameOrSourceURL() const { 2530 return getStringProperty(this, "scriptNameOrSourceURL"); 2531 } 2532 2533 2534 Local<String> StackFrame::GetFunctionName() const { 2535 return getStringProperty(this, "functionName"); 2536 } 2537 2538 2539 static bool getBoolProperty(const StackFrame* f, const char* propertyName) { 2540 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate(); 2541 ENTER_V8(isolate); 2542 i::HandleScope scope(isolate); 2543 i::Handle<i::JSObject> self = Utils::OpenHandle(f); 2544 i::Handle<i::Object> obj = 2545 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked(); 2546 return obj->IsTrue(); 2547 } 2548 2549 bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); } 2550 2551 2552 bool StackFrame::IsConstructor() const { 2553 return getBoolProperty(this, "isConstructor"); 2554 } 2555 2556 2557 // --- N a t i v e W e a k M a p --- 2558 2559 Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) { 2560 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 2561 ENTER_V8(isolate); 2562 i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap(); 2563 i::JSWeakCollection::Initialize(weakmap, isolate); 2564 return Utils::NativeWeakMapToLocal(weakmap); 2565 } 2566 2567 2568 void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) { 2569 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this); 2570 i::Isolate* isolate = weak_collection->GetIsolate(); 2571 ENTER_V8(isolate); 2572 i::HandleScope scope(isolate); 2573 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key); 2574 i::Handle<i::Object> value = Utils::OpenHandle(*v8_value); 2575 if (!key->IsJSReceiver() && !key->IsSymbol()) { 2576 DCHECK(false); 2577 return; 2578 } 2579 i::Handle<i::ObjectHashTable> table( 2580 i::ObjectHashTable::cast(weak_collection->table())); 2581 if (!table->IsKey(*key)) { 2582 DCHECK(false); 2583 return; 2584 } 2585 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value(); 2586 i::JSWeakCollection::Set(weak_collection, key, value, hash); 2587 } 2588 2589 2590 Local<Value> NativeWeakMap::Get(Local<Value> v8_key) { 2591 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this); 2592 i::Isolate* isolate = weak_collection->GetIsolate(); 2593 ENTER_V8(isolate); 2594 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key); 2595 if (!key->IsJSReceiver() && !key->IsSymbol()) { 2596 DCHECK(false); 2597 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 2598 } 2599 i::Handle<i::ObjectHashTable> table( 2600 i::ObjectHashTable::cast(weak_collection->table())); 2601 if (!table->IsKey(*key)) { 2602 DCHECK(false); 2603 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 2604 } 2605 i::Handle<i::Object> lookup(table->Lookup(key), isolate); 2606 if (lookup->IsTheHole()) 2607 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 2608 return Utils::ToLocal(lookup); 2609 } 2610 2611 2612 bool NativeWeakMap::Has(Local<Value> v8_key) { 2613 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this); 2614 i::Isolate* isolate = weak_collection->GetIsolate(); 2615 ENTER_V8(isolate); 2616 i::HandleScope scope(isolate); 2617 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key); 2618 if (!key->IsJSReceiver() && !key->IsSymbol()) { 2619 DCHECK(false); 2620 return false; 2621 } 2622 i::Handle<i::ObjectHashTable> table( 2623 i::ObjectHashTable::cast(weak_collection->table())); 2624 if (!table->IsKey(*key)) { 2625 DCHECK(false); 2626 return false; 2627 } 2628 i::Handle<i::Object> lookup(table->Lookup(key), isolate); 2629 return !lookup->IsTheHole(); 2630 } 2631 2632 2633 bool NativeWeakMap::Delete(Local<Value> v8_key) { 2634 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this); 2635 i::Isolate* isolate = weak_collection->GetIsolate(); 2636 ENTER_V8(isolate); 2637 i::HandleScope scope(isolate); 2638 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key); 2639 if (!key->IsJSReceiver() && !key->IsSymbol()) { 2640 DCHECK(false); 2641 return false; 2642 } 2643 i::Handle<i::ObjectHashTable> table( 2644 i::ObjectHashTable::cast(weak_collection->table())); 2645 if (!table->IsKey(*key)) { 2646 DCHECK(false); 2647 return false; 2648 } 2649 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value(); 2650 return i::JSWeakCollection::Delete(weak_collection, key, hash); 2651 } 2652 2653 2654 // --- J S O N --- 2655 2656 MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) { 2657 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 2658 PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, "JSON::Parse", Value); 2659 i::Handle<i::String> string = Utils::OpenHandle(*json_string); 2660 i::Handle<i::String> source = i::String::Flatten(string); 2661 auto maybe = source->IsSeqOneByteString() 2662 ? i::JsonParser<true>::Parse(source) 2663 : i::JsonParser<false>::Parse(source); 2664 Local<Value> result; 2665 has_pending_exception = !ToLocal<Value>(maybe, &result); 2666 RETURN_ON_FAILED_EXECUTION(Value); 2667 RETURN_ESCAPED(result); 2668 } 2669 2670 2671 Local<Value> JSON::Parse(Local<String> json_string) { 2672 auto isolate = reinterpret_cast<v8::Isolate*>( 2673 Utils::OpenHandle(*json_string)->GetIsolate()); 2674 RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value); 2675 } 2676 2677 2678 // --- D a t a --- 2679 2680 bool Value::FullIsUndefined() const { 2681 bool result = Utils::OpenHandle(this)->IsUndefined(); 2682 DCHECK_EQ(result, QuickIsUndefined()); 2683 return result; 2684 } 2685 2686 2687 bool Value::FullIsNull() const { 2688 bool result = Utils::OpenHandle(this)->IsNull(); 2689 DCHECK_EQ(result, QuickIsNull()); 2690 return result; 2691 } 2692 2693 2694 bool Value::IsTrue() const { 2695 return Utils::OpenHandle(this)->IsTrue(); 2696 } 2697 2698 2699 bool Value::IsFalse() const { 2700 return Utils::OpenHandle(this)->IsFalse(); 2701 } 2702 2703 2704 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); } 2705 2706 2707 bool Value::IsName() const { 2708 return Utils::OpenHandle(this)->IsName(); 2709 } 2710 2711 2712 bool Value::FullIsString() const { 2713 bool result = Utils::OpenHandle(this)->IsString(); 2714 DCHECK_EQ(result, QuickIsString()); 2715 return result; 2716 } 2717 2718 2719 bool Value::IsSymbol() const { 2720 return Utils::OpenHandle(this)->IsSymbol(); 2721 } 2722 2723 2724 bool Value::IsArray() const { 2725 return Utils::OpenHandle(this)->IsJSArray(); 2726 } 2727 2728 2729 bool Value::IsArrayBuffer() const { 2730 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2731 return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(); 2732 } 2733 2734 2735 bool Value::IsArrayBufferView() const { 2736 return Utils::OpenHandle(this)->IsJSArrayBufferView(); 2737 } 2738 2739 2740 bool Value::IsTypedArray() const { 2741 return Utils::OpenHandle(this)->IsJSTypedArray(); 2742 } 2743 2744 2745 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \ 2746 bool Value::Is##Type##Array() const { \ 2747 i::Handle<i::Object> obj = Utils::OpenHandle(this); \ 2748 return obj->IsJSTypedArray() && \ 2749 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \ 2750 } 2751 2752 2753 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY) 2754 2755 #undef VALUE_IS_TYPED_ARRAY 2756 2757 2758 bool Value::IsDataView() const { 2759 return Utils::OpenHandle(this)->IsJSDataView(); 2760 } 2761 2762 2763 bool Value::IsSharedArrayBuffer() const { 2764 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2765 return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(); 2766 } 2767 2768 2769 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); } 2770 2771 2772 bool Value::IsNumber() const { 2773 return Utils::OpenHandle(this)->IsNumber(); 2774 } 2775 2776 2777 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); } 2778 2779 2780 #define VALUE_IS_SPECIFIC_TYPE(Type, Class) \ 2781 bool Value::Is##Type() const { \ 2782 i::Handle<i::Object> obj = Utils::OpenHandle(this); \ 2783 if (!obj->IsHeapObject()) return false; \ 2784 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \ 2785 return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \ 2786 } 2787 2788 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments) 2789 VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean) 2790 VALUE_IS_SPECIFIC_TYPE(NumberObject, Number) 2791 VALUE_IS_SPECIFIC_TYPE(StringObject, String) 2792 VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol) 2793 VALUE_IS_SPECIFIC_TYPE(Date, Date) 2794 VALUE_IS_SPECIFIC_TYPE(Map, Map) 2795 VALUE_IS_SPECIFIC_TYPE(Set, Set) 2796 VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap) 2797 VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet) 2798 2799 #undef VALUE_IS_SPECIFIC_TYPE 2800 2801 2802 bool Value::IsBoolean() const { 2803 return Utils::OpenHandle(this)->IsBoolean(); 2804 } 2805 2806 2807 bool Value::IsExternal() const { 2808 return Utils::OpenHandle(this)->IsExternal(); 2809 } 2810 2811 2812 bool Value::IsInt32() const { 2813 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2814 if (obj->IsSmi()) return true; 2815 if (obj->IsNumber()) { 2816 return i::IsInt32Double(obj->Number()); 2817 } 2818 return false; 2819 } 2820 2821 2822 bool Value::IsUint32() const { 2823 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2824 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0; 2825 if (obj->IsNumber()) { 2826 double value = obj->Number(); 2827 return !i::IsMinusZero(value) && 2828 value >= 0 && 2829 value <= i::kMaxUInt32 && 2830 value == i::FastUI2D(i::FastD2UI(value)); 2831 } 2832 return false; 2833 } 2834 2835 2836 bool Value::IsNativeError() const { 2837 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2838 if (!obj->IsJSObject()) return false; 2839 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj); 2840 i::Isolate* isolate = js_obj->GetIsolate(); 2841 i::Handle<i::Object> constructor(js_obj->map()->GetConstructor(), isolate); 2842 if (!constructor->IsJSFunction()) return false; 2843 i::Handle<i::JSFunction> function = 2844 i::Handle<i::JSFunction>::cast(constructor); 2845 if (!function->shared()->native()) return false; 2846 return function.is_identical_to(isolate->error_function()) || 2847 function.is_identical_to(isolate->eval_error_function()) || 2848 function.is_identical_to(isolate->range_error_function()) || 2849 function.is_identical_to(isolate->reference_error_function()) || 2850 function.is_identical_to(isolate->syntax_error_function()) || 2851 function.is_identical_to(isolate->type_error_function()) || 2852 function.is_identical_to(isolate->uri_error_function()); 2853 } 2854 2855 2856 bool Value::IsRegExp() const { 2857 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2858 return obj->IsJSRegExp(); 2859 } 2860 2861 2862 bool Value::IsGeneratorFunction() const { 2863 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2864 if (!obj->IsJSFunction()) return false; 2865 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj); 2866 return func->shared()->is_generator(); 2867 } 2868 2869 2870 bool Value::IsGeneratorObject() const { 2871 return Utils::OpenHandle(this)->IsJSGeneratorObject(); 2872 } 2873 2874 2875 bool Value::IsMapIterator() const { 2876 return Utils::OpenHandle(this)->IsJSMapIterator(); 2877 } 2878 2879 2880 bool Value::IsSetIterator() const { 2881 return Utils::OpenHandle(this)->IsJSSetIterator(); 2882 } 2883 2884 2885 bool Value::IsPromise() const { 2886 auto self = Utils::OpenHandle(this); 2887 return i::Object::IsPromise(self); 2888 } 2889 2890 2891 MaybeLocal<String> Value::ToString(Local<Context> context) const { 2892 auto obj = Utils::OpenHandle(this); 2893 if (obj->IsString()) return ToApiHandle<String>(obj); 2894 PREPARE_FOR_EXECUTION(context, "ToString", String); 2895 Local<String> result; 2896 has_pending_exception = 2897 !ToLocal<String>(i::Object::ToString(isolate, obj), &result); 2898 RETURN_ON_FAILED_EXECUTION(String); 2899 RETURN_ESCAPED(result); 2900 } 2901 2902 2903 Local<String> Value::ToString(Isolate* isolate) const { 2904 RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String); 2905 } 2906 2907 2908 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const { 2909 i::Handle<i::Object> obj = Utils::OpenHandle(this); 2910 if (obj->IsString()) return ToApiHandle<String>(obj); 2911 PREPARE_FOR_EXECUTION(context, "ToDetailString", String); 2912 Local<String> result; 2913 i::Handle<i::Object> args[] = {obj}; 2914 has_pending_exception = !ToLocal<String>( 2915 i::Execution::TryCall(isolate, isolate->no_side_effects_to_string_fun(), 2916 isolate->factory()->undefined_value(), 2917 arraysize(args), args), 2918 &result); 2919 RETURN_ON_FAILED_EXECUTION(String); 2920 RETURN_ESCAPED(result); 2921 } 2922 2923 2924 Local<String> Value::ToDetailString(Isolate* isolate) const { 2925 RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()), 2926 String); 2927 } 2928 2929 2930 MaybeLocal<Object> Value::ToObject(Local<Context> context) const { 2931 auto obj = Utils::OpenHandle(this); 2932 if (obj->IsJSObject()) return ToApiHandle<Object>(obj); 2933 PREPARE_FOR_EXECUTION(context, "ToObject", Object); 2934 Local<Object> result; 2935 has_pending_exception = 2936 !ToLocal<Object>(i::Execution::ToObject(isolate, obj), &result); 2937 RETURN_ON_FAILED_EXECUTION(Object); 2938 RETURN_ESCAPED(result); 2939 } 2940 2941 2942 Local<v8::Object> Value::ToObject(Isolate* isolate) const { 2943 RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object); 2944 } 2945 2946 2947 MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const { 2948 auto obj = Utils::OpenHandle(this); 2949 if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj); 2950 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); 2951 auto val = isolate->factory()->ToBoolean(obj->BooleanValue()); 2952 return ToApiHandle<Boolean>(val); 2953 } 2954 2955 2956 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const { 2957 return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked(); 2958 } 2959 2960 2961 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const { 2962 auto obj = Utils::OpenHandle(this); 2963 if (obj->IsNumber()) return ToApiHandle<Number>(obj); 2964 PREPARE_FOR_EXECUTION(context, "ToNumber", Number); 2965 Local<Number> result; 2966 has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result); 2967 RETURN_ON_FAILED_EXECUTION(Number); 2968 RETURN_ESCAPED(result); 2969 } 2970 2971 2972 Local<Number> Value::ToNumber(Isolate* isolate) const { 2973 RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number); 2974 } 2975 2976 2977 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const { 2978 auto obj = Utils::OpenHandle(this); 2979 if (obj->IsSmi()) return ToApiHandle<Integer>(obj); 2980 PREPARE_FOR_EXECUTION(context, "ToInteger", Integer); 2981 Local<Integer> result; 2982 has_pending_exception = 2983 !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result); 2984 RETURN_ON_FAILED_EXECUTION(Integer); 2985 RETURN_ESCAPED(result); 2986 } 2987 2988 2989 Local<Integer> Value::ToInteger(Isolate* isolate) const { 2990 RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer); 2991 } 2992 2993 2994 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const { 2995 auto obj = Utils::OpenHandle(this); 2996 if (obj->IsSmi()) return ToApiHandle<Int32>(obj); 2997 Local<Int32> result; 2998 PREPARE_FOR_EXECUTION(context, "ToInt32", Int32); 2999 has_pending_exception = 3000 !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result); 3001 RETURN_ON_FAILED_EXECUTION(Int32); 3002 RETURN_ESCAPED(result); 3003 } 3004 3005 3006 Local<Int32> Value::ToInt32(Isolate* isolate) const { 3007 RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32); 3008 } 3009 3010 3011 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const { 3012 auto obj = Utils::OpenHandle(this); 3013 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj); 3014 Local<Uint32> result; 3015 PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32); 3016 has_pending_exception = 3017 !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result); 3018 RETURN_ON_FAILED_EXECUTION(Uint32); 3019 RETURN_ESCAPED(result); 3020 } 3021 3022 3023 Local<Uint32> Value::ToUint32(Isolate* isolate) const { 3024 RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32); 3025 } 3026 3027 3028 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) { 3029 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); 3030 Utils::ApiCheck(isolate != NULL && 3031 !isolate->IsDead(), 3032 "v8::internal::Internals::CheckInitialized()", 3033 "Isolate is not initialized or V8 has died"); 3034 } 3035 3036 3037 void External::CheckCast(v8::Value* that) { 3038 Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(), 3039 "v8::External::Cast()", 3040 "Could not convert to external"); 3041 } 3042 3043 3044 void v8::Object::CheckCast(Value* that) { 3045 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3046 Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast()", 3047 "Could not convert to object"); 3048 } 3049 3050 3051 void v8::Function::CheckCast(Value* that) { 3052 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3053 Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()", 3054 "Could not convert to function"); 3055 } 3056 3057 3058 void v8::Boolean::CheckCast(v8::Value* that) { 3059 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3060 Utils::ApiCheck(obj->IsBoolean(), 3061 "v8::Boolean::Cast()", 3062 "Could not convert to boolean"); 3063 } 3064 3065 3066 void v8::Name::CheckCast(v8::Value* that) { 3067 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3068 Utils::ApiCheck(obj->IsName(), 3069 "v8::Name::Cast()", 3070 "Could not convert to name"); 3071 } 3072 3073 3074 void v8::String::CheckCast(v8::Value* that) { 3075 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3076 Utils::ApiCheck(obj->IsString(), 3077 "v8::String::Cast()", 3078 "Could not convert to string"); 3079 } 3080 3081 3082 void v8::Symbol::CheckCast(v8::Value* that) { 3083 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3084 Utils::ApiCheck(obj->IsSymbol(), 3085 "v8::Symbol::Cast()", 3086 "Could not convert to symbol"); 3087 } 3088 3089 3090 void v8::Number::CheckCast(v8::Value* that) { 3091 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3092 Utils::ApiCheck(obj->IsNumber(), 3093 "v8::Number::Cast()", 3094 "Could not convert to number"); 3095 } 3096 3097 3098 void v8::Integer::CheckCast(v8::Value* that) { 3099 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3100 Utils::ApiCheck(obj->IsNumber(), 3101 "v8::Integer::Cast()", 3102 "Could not convert to number"); 3103 } 3104 3105 3106 void v8::Int32::CheckCast(v8::Value* that) { 3107 Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast()", 3108 "Could not convert to 32-bit signed integer"); 3109 } 3110 3111 3112 void v8::Uint32::CheckCast(v8::Value* that) { 3113 Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast()", 3114 "Could not convert to 32-bit unsigned integer"); 3115 } 3116 3117 3118 void v8::Array::CheckCast(Value* that) { 3119 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3120 Utils::ApiCheck(obj->IsJSArray(), 3121 "v8::Array::Cast()", 3122 "Could not convert to array"); 3123 } 3124 3125 3126 void v8::Map::CheckCast(Value* that) { 3127 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3128 Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast()", 3129 "Could not convert to Map"); 3130 } 3131 3132 3133 void v8::Set::CheckCast(Value* that) { 3134 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3135 Utils::ApiCheck(obj->IsJSSet(), "v8::Set::Cast()", 3136 "Could not convert to Set"); 3137 } 3138 3139 3140 void v8::Promise::CheckCast(Value* that) { 3141 Utils::ApiCheck(that->IsPromise(), 3142 "v8::Promise::Cast()", 3143 "Could not convert to promise"); 3144 } 3145 3146 3147 void v8::Promise::Resolver::CheckCast(Value* that) { 3148 Utils::ApiCheck(that->IsPromise(), 3149 "v8::Promise::Resolver::Cast()", 3150 "Could not convert to promise resolver"); 3151 } 3152 3153 3154 void v8::Proxy::CheckCast(Value* that) { 3155 Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast()", 3156 "Could not convert to proxy"); 3157 } 3158 3159 3160 void v8::ArrayBuffer::CheckCast(Value* that) { 3161 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3162 Utils::ApiCheck( 3163 obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(), 3164 "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer"); 3165 } 3166 3167 3168 void v8::ArrayBufferView::CheckCast(Value* that) { 3169 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3170 Utils::ApiCheck(obj->IsJSArrayBufferView(), 3171 "v8::ArrayBufferView::Cast()", 3172 "Could not convert to ArrayBufferView"); 3173 } 3174 3175 3176 void v8::TypedArray::CheckCast(Value* that) { 3177 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3178 Utils::ApiCheck(obj->IsJSTypedArray(), 3179 "v8::TypedArray::Cast()", 3180 "Could not convert to TypedArray"); 3181 } 3182 3183 3184 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \ 3185 void v8::Type##Array::CheckCast(Value* that) { \ 3186 i::Handle<i::Object> obj = Utils::OpenHandle(that); \ 3187 Utils::ApiCheck( \ 3188 obj->IsJSTypedArray() && \ 3189 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \ 3190 "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \ 3191 } 3192 3193 3194 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST) 3195 3196 #undef CHECK_TYPED_ARRAY_CAST 3197 3198 3199 void v8::DataView::CheckCast(Value* that) { 3200 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3201 Utils::ApiCheck(obj->IsJSDataView(), 3202 "v8::DataView::Cast()", 3203 "Could not convert to DataView"); 3204 } 3205 3206 3207 void v8::SharedArrayBuffer::CheckCast(Value* that) { 3208 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3209 Utils::ApiCheck( 3210 obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(), 3211 "v8::SharedArrayBuffer::Cast()", 3212 "Could not convert to SharedArrayBuffer"); 3213 } 3214 3215 3216 void v8::Date::CheckCast(v8::Value* that) { 3217 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3218 i::Isolate* isolate = NULL; 3219 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate(); 3220 Utils::ApiCheck(isolate != NULL && 3221 obj->HasSpecificClassOf(isolate->heap()->Date_string()), 3222 "v8::Date::Cast()", 3223 "Could not convert to date"); 3224 } 3225 3226 3227 void v8::StringObject::CheckCast(v8::Value* that) { 3228 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3229 i::Isolate* isolate = NULL; 3230 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate(); 3231 Utils::ApiCheck(isolate != NULL && 3232 obj->HasSpecificClassOf(isolate->heap()->String_string()), 3233 "v8::StringObject::Cast()", 3234 "Could not convert to StringObject"); 3235 } 3236 3237 3238 void v8::SymbolObject::CheckCast(v8::Value* that) { 3239 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3240 i::Isolate* isolate = NULL; 3241 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate(); 3242 Utils::ApiCheck(isolate != NULL && 3243 obj->HasSpecificClassOf(isolate->heap()->Symbol_string()), 3244 "v8::SymbolObject::Cast()", 3245 "Could not convert to SymbolObject"); 3246 } 3247 3248 3249 void v8::NumberObject::CheckCast(v8::Value* that) { 3250 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3251 i::Isolate* isolate = NULL; 3252 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate(); 3253 Utils::ApiCheck(isolate != NULL && 3254 obj->HasSpecificClassOf(isolate->heap()->Number_string()), 3255 "v8::NumberObject::Cast()", 3256 "Could not convert to NumberObject"); 3257 } 3258 3259 3260 void v8::BooleanObject::CheckCast(v8::Value* that) { 3261 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3262 i::Isolate* isolate = NULL; 3263 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate(); 3264 Utils::ApiCheck(isolate != NULL && 3265 obj->HasSpecificClassOf(isolate->heap()->Boolean_string()), 3266 "v8::BooleanObject::Cast()", 3267 "Could not convert to BooleanObject"); 3268 } 3269 3270 3271 void v8::RegExp::CheckCast(v8::Value* that) { 3272 i::Handle<i::Object> obj = Utils::OpenHandle(that); 3273 Utils::ApiCheck(obj->IsJSRegExp(), 3274 "v8::RegExp::Cast()", 3275 "Could not convert to regular expression"); 3276 } 3277 3278 3279 Maybe<bool> Value::BooleanValue(Local<Context> context) const { 3280 return Just(Utils::OpenHandle(this)->BooleanValue()); 3281 } 3282 3283 3284 bool Value::BooleanValue() const { 3285 return Utils::OpenHandle(this)->BooleanValue(); 3286 } 3287 3288 3289 Maybe<double> Value::NumberValue(Local<Context> context) const { 3290 auto obj = Utils::OpenHandle(this); 3291 if (obj->IsNumber()) return Just(obj->Number()); 3292 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double); 3293 i::Handle<i::Object> num; 3294 has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num); 3295 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double); 3296 return Just(num->Number()); 3297 } 3298 3299 3300 double Value::NumberValue() const { 3301 auto obj = Utils::OpenHandle(this); 3302 if (obj->IsNumber()) return obj->Number(); 3303 return NumberValue(ContextFromHeapObject(obj)) 3304 .FromMaybe(std::numeric_limits<double>::quiet_NaN()); 3305 } 3306 3307 3308 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const { 3309 auto obj = Utils::OpenHandle(this); 3310 i::Handle<i::Object> num; 3311 if (obj->IsNumber()) { 3312 num = obj; 3313 } else { 3314 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t); 3315 has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num); 3316 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t); 3317 } 3318 return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value()) 3319 : static_cast<int64_t>(num->Number())); 3320 } 3321 3322 3323 int64_t Value::IntegerValue() const { 3324 auto obj = Utils::OpenHandle(this); 3325 if (obj->IsNumber()) { 3326 if (obj->IsSmi()) { 3327 return i::Smi::cast(*obj)->value(); 3328 } else { 3329 return static_cast<int64_t>(obj->Number()); 3330 } 3331 } 3332 return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0); 3333 } 3334 3335 3336 Maybe<int32_t> Value::Int32Value(Local<Context> context) const { 3337 auto obj = Utils::OpenHandle(this); 3338 if (obj->IsNumber()) return Just(NumberToInt32(*obj)); 3339 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t); 3340 i::Handle<i::Object> num; 3341 has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num); 3342 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t); 3343 return Just(num->IsSmi() ? i::Smi::cast(*num)->value() 3344 : static_cast<int32_t>(num->Number())); 3345 } 3346 3347 3348 int32_t Value::Int32Value() const { 3349 auto obj = Utils::OpenHandle(this); 3350 if (obj->IsNumber()) return NumberToInt32(*obj); 3351 return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0); 3352 } 3353 3354 3355 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const { 3356 auto obj = Utils::OpenHandle(this); 3357 if (obj->IsNumber()) return Just(NumberToUint32(*obj)); 3358 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t); 3359 i::Handle<i::Object> num; 3360 has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num); 3361 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t); 3362 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value()) 3363 : static_cast<uint32_t>(num->Number())); 3364 } 3365 3366 3367 uint32_t Value::Uint32Value() const { 3368 auto obj = Utils::OpenHandle(this); 3369 if (obj->IsNumber()) return NumberToUint32(*obj); 3370 return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0); 3371 } 3372 3373 3374 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const { 3375 auto self = Utils::OpenHandle(this); 3376 if (self->IsSmi()) { 3377 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self); 3378 return Local<Uint32>(); 3379 } 3380 PREPARE_FOR_EXECUTION(context, "ToArrayIndex", Uint32); 3381 i::Handle<i::Object> string_obj; 3382 has_pending_exception = 3383 !i::Object::ToString(isolate, self).ToHandle(&string_obj); 3384 RETURN_ON_FAILED_EXECUTION(Uint32); 3385 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj); 3386 uint32_t index; 3387 if (str->AsArrayIndex(&index)) { 3388 i::Handle<i::Object> value; 3389 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) { 3390 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate); 3391 } else { 3392 value = isolate->factory()->NewNumber(index); 3393 } 3394 RETURN_ESCAPED(Utils::Uint32ToLocal(value)); 3395 } 3396 return Local<Uint32>(); 3397 } 3398 3399 3400 Local<Uint32> Value::ToArrayIndex() const { 3401 auto self = Utils::OpenHandle(this); 3402 if (self->IsSmi()) { 3403 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self); 3404 return Local<Uint32>(); 3405 } 3406 auto context = ContextFromHeapObject(self); 3407 RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32); 3408 } 3409 3410 3411 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const { 3412 auto self = Utils::OpenHandle(this); 3413 auto other = Utils::OpenHandle(*that); 3414 return i::Object::Equals(self, other); 3415 } 3416 3417 3418 bool Value::Equals(Local<Value> that) const { 3419 auto self = Utils::OpenHandle(this); 3420 auto other = Utils::OpenHandle(*that); 3421 if (self->IsSmi() && other->IsSmi()) { 3422 return self->Number() == other->Number(); 3423 } 3424 if (self->IsJSObject() && other->IsJSObject()) { 3425 return *self == *other; 3426 } 3427 auto heap_object = self->IsSmi() ? other : self; 3428 auto context = ContextFromHeapObject(heap_object); 3429 return Equals(context, that).FromMaybe(false); 3430 } 3431 3432 3433 bool Value::StrictEquals(Local<Value> that) const { 3434 auto self = Utils::OpenHandle(this); 3435 auto other = Utils::OpenHandle(*that); 3436 return self->StrictEquals(*other); 3437 } 3438 3439 3440 bool Value::SameValue(Local<Value> that) const { 3441 auto self = Utils::OpenHandle(this); 3442 auto other = Utils::OpenHandle(*that); 3443 return self->SameValue(*other); 3444 } 3445 3446 3447 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, 3448 v8::Local<Value> key, v8::Local<Value> value) { 3449 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool); 3450 auto self = Utils::OpenHandle(this); 3451 auto key_obj = Utils::OpenHandle(*key); 3452 auto value_obj = Utils::OpenHandle(*value); 3453 has_pending_exception = 3454 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj, 3455 i::SLOPPY).is_null(); 3456 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3457 return Just(true); 3458 } 3459 3460 3461 bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) { 3462 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3463 return Set(context, key, value).FromMaybe(false); 3464 } 3465 3466 3467 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index, 3468 v8::Local<Value> value) { 3469 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool); 3470 auto self = Utils::OpenHandle(this); 3471 auto value_obj = Utils::OpenHandle(*value); 3472 has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj, 3473 i::SLOPPY).is_null(); 3474 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3475 return Just(true); 3476 } 3477 3478 3479 bool v8::Object::Set(uint32_t index, v8::Local<Value> value) { 3480 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3481 return Set(context, index, value).FromMaybe(false); 3482 } 3483 3484 3485 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context, 3486 v8::Local<Name> key, 3487 v8::Local<Value> value) { 3488 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()", 3489 bool); 3490 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 3491 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key); 3492 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); 3493 3494 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 3495 isolate, self, key_obj, i::LookupIterator::OWN); 3496 Maybe<bool> result = 3497 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW); 3498 has_pending_exception = result.IsNothing(); 3499 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3500 return result; 3501 } 3502 3503 3504 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context, 3505 uint32_t index, 3506 v8::Local<Value> value) { 3507 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()", 3508 bool); 3509 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 3510 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); 3511 3512 i::LookupIterator it(isolate, self, index, i::LookupIterator::OWN); 3513 Maybe<bool> result = 3514 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW); 3515 has_pending_exception = result.IsNothing(); 3516 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3517 return result; 3518 } 3519 3520 3521 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context, 3522 v8::Local<Name> key, 3523 v8::Local<Value> value, 3524 v8::PropertyAttribute attributes) { 3525 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()", 3526 bool); 3527 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 3528 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key); 3529 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); 3530 3531 if (self->IsAccessCheckNeeded() && 3532 !isolate->MayAccess(handle(isolate->context()), 3533 i::Handle<i::JSObject>::cast(self))) { 3534 isolate->ReportFailedAccessCheck(i::Handle<i::JSObject>::cast(self)); 3535 return Nothing<bool>(); 3536 } 3537 3538 i::PropertyDescriptor desc; 3539 desc.set_writable(!(attributes & v8::ReadOnly)); 3540 desc.set_enumerable(!(attributes & v8::DontEnum)); 3541 desc.set_configurable(!(attributes & v8::DontDelete)); 3542 desc.set_value(value_obj); 3543 Maybe<bool> success = i::JSReceiver::DefineOwnProperty( 3544 isolate, self, key_obj, &desc, i::Object::DONT_THROW); 3545 // Even though we said DONT_THROW, there might be accessors that do throw. 3546 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3547 return success; 3548 } 3549 3550 3551 MUST_USE_RESULT 3552 static i::MaybeHandle<i::Object> DefineObjectProperty( 3553 i::Handle<i::JSObject> js_object, i::Handle<i::Object> key, 3554 i::Handle<i::Object> value, i::PropertyAttributes attrs) { 3555 i::Isolate* isolate = js_object->GetIsolate(); 3556 bool success = false; 3557 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 3558 isolate, js_object, key, &success, i::LookupIterator::OWN); 3559 if (!success) return i::MaybeHandle<i::Object>(); 3560 3561 return i::JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs); 3562 } 3563 3564 3565 Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context, 3566 v8::Local<Value> key, v8::Local<Value> value, 3567 v8::PropertyAttribute attribs) { 3568 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::ForceSet()", bool); 3569 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this)); 3570 auto key_obj = Utils::OpenHandle(*key); 3571 auto value_obj = Utils::OpenHandle(*value); 3572 has_pending_exception = 3573 DefineObjectProperty(self, key_obj, value_obj, 3574 static_cast<i::PropertyAttributes>(attribs)) 3575 .is_null(); 3576 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3577 return Just(true); 3578 } 3579 3580 3581 bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value, 3582 v8::PropertyAttribute attribs) { 3583 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 3584 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), 3585 "v8::Object::ForceSet", false, i::HandleScope, 3586 false); 3587 i::Handle<i::JSObject> self = 3588 i::Handle<i::JSObject>::cast(Utils::OpenHandle(this)); 3589 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key); 3590 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); 3591 has_pending_exception = 3592 DefineObjectProperty(self, key_obj, value_obj, 3593 static_cast<i::PropertyAttributes>(attribs)) 3594 .is_null(); 3595 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false); 3596 return true; 3597 } 3598 3599 3600 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key, 3601 Local<Value> value) { 3602 return DefineOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)), 3603 value, DontEnum); 3604 } 3605 3606 3607 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context, 3608 Local<Value> key) { 3609 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value); 3610 auto self = Utils::OpenHandle(this); 3611 auto key_obj = Utils::OpenHandle(*key); 3612 i::Handle<i::Object> result; 3613 has_pending_exception = 3614 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result); 3615 RETURN_ON_FAILED_EXECUTION(Value); 3616 RETURN_ESCAPED(Utils::ToLocal(result)); 3617 } 3618 3619 3620 Local<Value> v8::Object::Get(v8::Local<Value> key) { 3621 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3622 RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value); 3623 } 3624 3625 3626 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) { 3627 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value); 3628 auto self = Utils::OpenHandle(this); 3629 i::Handle<i::Object> result; 3630 has_pending_exception = 3631 !i::Object::GetElement(isolate, self, index).ToHandle(&result); 3632 RETURN_ON_FAILED_EXECUTION(Value); 3633 RETURN_ESCAPED(Utils::ToLocal(result)); 3634 } 3635 3636 3637 Local<Value> v8::Object::Get(uint32_t index) { 3638 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3639 RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value); 3640 } 3641 3642 3643 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context, 3644 Local<Private> key) { 3645 return Get(context, Local<Value>(reinterpret_cast<Value*>(*key))); 3646 } 3647 3648 3649 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes( 3650 Local<Context> context, Local<Value> key) { 3651 PREPARE_FOR_EXECUTION_PRIMITIVE( 3652 context, "v8::Object::GetPropertyAttributes()", PropertyAttribute); 3653 auto self = Utils::OpenHandle(this); 3654 auto key_obj = Utils::OpenHandle(*key); 3655 if (!key_obj->IsName()) { 3656 has_pending_exception = 3657 !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj); 3658 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); 3659 } 3660 auto key_name = i::Handle<i::Name>::cast(key_obj); 3661 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name); 3662 has_pending_exception = result.IsNothing(); 3663 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); 3664 if (result.FromJust() == i::ABSENT) { 3665 return Just(static_cast<PropertyAttribute>(i::NONE)); 3666 } 3667 return Just(static_cast<PropertyAttribute>(result.FromJust())); 3668 } 3669 3670 3671 PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) { 3672 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3673 return GetPropertyAttributes(context, key) 3674 .FromMaybe(static_cast<PropertyAttribute>(i::NONE)); 3675 } 3676 3677 3678 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context, 3679 Local<String> key) { 3680 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()", 3681 Value); 3682 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 3683 i::Handle<i::String> key_name = Utils::OpenHandle(*key); 3684 3685 i::PropertyDescriptor desc; 3686 Maybe<bool> found = 3687 i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc); 3688 has_pending_exception = found.IsNothing(); 3689 RETURN_ON_FAILED_EXECUTION(Value); 3690 if (!found.FromJust()) { 3691 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 3692 } 3693 RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate))); 3694 } 3695 3696 3697 Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) { 3698 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3699 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value); 3700 } 3701 3702 3703 Local<Value> v8::Object::GetPrototype() { 3704 auto isolate = Utils::OpenHandle(this)->GetIsolate(); 3705 auto self = Utils::OpenHandle(this); 3706 i::PrototypeIterator iter(isolate, self); 3707 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter)); 3708 } 3709 3710 3711 Maybe<bool> v8::Object::SetPrototype(Local<Context> context, 3712 Local<Value> value) { 3713 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrototype()", bool); 3714 auto self = Utils::OpenHandle(this); 3715 auto value_obj = Utils::OpenHandle(*value); 3716 // We do not allow exceptions thrown while setting the prototype 3717 // to propagate outside. 3718 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); 3719 auto result = i::JSReceiver::SetPrototype(self, value_obj, false, 3720 i::Object::THROW_ON_ERROR); 3721 has_pending_exception = result.IsNothing(); 3722 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3723 return Just(true); 3724 } 3725 3726 3727 bool v8::Object::SetPrototype(Local<Value> value) { 3728 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3729 return SetPrototype(context, value).FromMaybe(false); 3730 } 3731 3732 3733 Local<Object> v8::Object::FindInstanceInPrototypeChain( 3734 v8::Local<FunctionTemplate> tmpl) { 3735 auto isolate = Utils::OpenHandle(this)->GetIsolate(); 3736 i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this), 3737 i::PrototypeIterator::START_AT_RECEIVER); 3738 auto tmpl_info = *Utils::OpenHandle(*tmpl); 3739 while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) { 3740 iter.Advance(); 3741 if (iter.IsAtEnd()) { 3742 return Local<Object>(); 3743 } 3744 } 3745 // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here. 3746 return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate)); 3747 } 3748 3749 3750 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) { 3751 PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array); 3752 auto self = Utils::OpenHandle(this); 3753 i::Handle<i::FixedArray> value; 3754 has_pending_exception = 3755 !i::JSReceiver::GetKeys(self, i::JSReceiver::INCLUDE_PROTOS, 3756 i::ENUMERABLE_STRINGS) 3757 .ToHandle(&value); 3758 RETURN_ON_FAILED_EXECUTION(Array); 3759 // Because we use caching to speed up enumeration it is important 3760 // to never change the result of the basic enumeration function so 3761 // we clone the result. 3762 auto elms = isolate->factory()->CopyFixedArray(value); 3763 auto result = isolate->factory()->NewJSArrayWithElements(elms); 3764 RETURN_ESCAPED(Utils::ToLocal(result)); 3765 } 3766 3767 3768 Local<Array> v8::Object::GetPropertyNames() { 3769 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3770 RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array); 3771 } 3772 3773 3774 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) { 3775 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array); 3776 auto self = Utils::OpenHandle(this); 3777 i::Handle<i::FixedArray> value; 3778 has_pending_exception = !i::JSReceiver::GetKeys(self, i::JSReceiver::OWN_ONLY, 3779 i::ENUMERABLE_STRINGS) 3780 .ToHandle(&value); 3781 RETURN_ON_FAILED_EXECUTION(Array); 3782 // Because we use caching to speed up enumeration it is important 3783 // to never change the result of the basic enumeration function so 3784 // we clone the result. 3785 auto elms = isolate->factory()->CopyFixedArray(value); 3786 auto result = isolate->factory()->NewJSArrayWithElements(elms); 3787 RETURN_ESCAPED(Utils::ToLocal(result)); 3788 } 3789 3790 3791 Local<Array> v8::Object::GetOwnPropertyNames() { 3792 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3793 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array); 3794 } 3795 3796 3797 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) { 3798 PREPARE_FOR_EXECUTION(context, "v8::Object::ObjectProtoToString", String); 3799 auto obj = Utils::OpenHandle(this); 3800 Local<String> result; 3801 has_pending_exception = 3802 !ToLocal<String>(i::JSObject::ObjectProtoToString(isolate, obj), &result); 3803 RETURN_ON_FAILED_EXECUTION(String); 3804 RETURN_ESCAPED(result); 3805 } 3806 3807 3808 Local<String> v8::Object::ObjectProtoToString() { 3809 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3810 RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String); 3811 } 3812 3813 3814 Local<String> v8::Object::GetConstructorName() { 3815 auto self = Utils::OpenHandle(this); 3816 i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self); 3817 return Utils::ToLocal(name); 3818 } 3819 3820 3821 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) { 3822 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool); 3823 auto self = Utils::OpenHandle(this); 3824 auto key_obj = Utils::OpenHandle(*key); 3825 Maybe<bool> result = 3826 i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY); 3827 has_pending_exception = result.IsNothing(); 3828 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3829 return result; 3830 } 3831 3832 3833 bool v8::Object::Delete(v8::Local<Value> key) { 3834 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3835 return Delete(context, key).FromMaybe(false); 3836 } 3837 3838 3839 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context, 3840 Local<Private> key) { 3841 return Delete(context, Local<Value>(reinterpret_cast<Value*>(*key))); 3842 } 3843 3844 3845 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) { 3846 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool); 3847 auto self = Utils::OpenHandle(this); 3848 auto key_obj = Utils::OpenHandle(*key); 3849 Maybe<bool> maybe = Nothing<bool>(); 3850 // Check if the given key is an array index. 3851 uint32_t index = 0; 3852 if (key_obj->ToArrayIndex(&index)) { 3853 maybe = i::JSReceiver::HasElement(self, index); 3854 } else { 3855 // Convert the key to a name - possibly by calling back into JavaScript. 3856 i::Handle<i::Name> name; 3857 if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) { 3858 maybe = i::JSReceiver::HasProperty(self, name); 3859 } 3860 } 3861 has_pending_exception = maybe.IsNothing(); 3862 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3863 return maybe; 3864 } 3865 3866 3867 bool v8::Object::Has(v8::Local<Value> key) { 3868 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3869 return Has(context, key).FromMaybe(false); 3870 } 3871 3872 3873 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) { 3874 return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key))); 3875 } 3876 3877 3878 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) { 3879 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()", 3880 bool); 3881 auto self = Utils::OpenHandle(this); 3882 Maybe<bool> result = i::JSReceiver::DeleteElement(self, index); 3883 has_pending_exception = result.IsNothing(); 3884 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3885 return result; 3886 } 3887 3888 3889 bool v8::Object::Delete(uint32_t index) { 3890 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3891 return Delete(context, index).FromMaybe(false); 3892 } 3893 3894 3895 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) { 3896 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool); 3897 auto self = Utils::OpenHandle(this); 3898 auto maybe = i::JSReceiver::HasElement(self, index); 3899 has_pending_exception = maybe.IsNothing(); 3900 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3901 return maybe; 3902 } 3903 3904 3905 bool v8::Object::Has(uint32_t index) { 3906 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3907 return Has(context, index).FromMaybe(false); 3908 } 3909 3910 3911 template <typename Getter, typename Setter, typename Data> 3912 static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self, 3913 Local<Name> name, Getter getter, 3914 Setter setter, Data data, 3915 AccessControl settings, 3916 PropertyAttribute attributes) { 3917 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool); 3918 if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false); 3919 i::Handle<i::JSObject> obj = 3920 i::Handle<i::JSObject>::cast(Utils::OpenHandle(self)); 3921 v8::Local<AccessorSignature> signature; 3922 auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes, 3923 signature); 3924 if (info.is_null()) return Nothing<bool>(); 3925 bool fast = obj->HasFastProperties(); 3926 i::Handle<i::Object> result; 3927 has_pending_exception = 3928 !i::JSObject::SetAccessor(obj, info).ToHandle(&result); 3929 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3930 if (result->IsUndefined()) return Nothing<bool>(); 3931 if (fast) { 3932 i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor"); 3933 } 3934 return Just(true); 3935 } 3936 3937 3938 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name, 3939 AccessorNameGetterCallback getter, 3940 AccessorNameSetterCallback setter, 3941 MaybeLocal<Value> data, AccessControl settings, 3942 PropertyAttribute attribute) { 3943 return ObjectSetAccessor(context, this, name, getter, setter, 3944 data.FromMaybe(Local<Value>()), settings, attribute); 3945 } 3946 3947 3948 bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter, 3949 AccessorSetterCallback setter, v8::Local<Value> data, 3950 AccessControl settings, PropertyAttribute attributes) { 3951 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3952 return ObjectSetAccessor(context, this, name, getter, setter, data, settings, 3953 attributes).FromMaybe(false); 3954 } 3955 3956 3957 bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter, 3958 AccessorNameSetterCallback setter, 3959 v8::Local<Value> data, AccessControl settings, 3960 PropertyAttribute attributes) { 3961 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 3962 return ObjectSetAccessor(context, this, name, getter, setter, data, settings, 3963 attributes).FromMaybe(false); 3964 } 3965 3966 3967 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter, 3968 Local<Function> setter, 3969 PropertyAttribute attribute, 3970 AccessControl settings) { 3971 // TODO(verwaest): Remove |settings|. 3972 DCHECK_EQ(v8::DEFAULT, settings); 3973 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 3974 ENTER_V8(isolate); 3975 i::HandleScope scope(isolate); 3976 auto self = Utils::OpenHandle(this); 3977 if (!self->IsJSObject()) return; 3978 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter); 3979 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true); 3980 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); 3981 i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self), 3982 v8::Utils::OpenHandle(*name), getter_i, setter_i, 3983 static_cast<i::PropertyAttributes>(attribute)); 3984 } 3985 3986 3987 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, 3988 Local<Name> key) { 3989 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()", 3990 bool); 3991 auto self = Utils::OpenHandle(this); 3992 auto key_val = Utils::OpenHandle(*key); 3993 auto result = i::JSReceiver::HasOwnProperty(self, key_val); 3994 has_pending_exception = result.IsNothing(); 3995 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 3996 return result; 3997 } 3998 3999 4000 bool v8::Object::HasOwnProperty(Local<String> key) { 4001 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4002 return HasOwnProperty(context, key).FromMaybe(false); 4003 } 4004 4005 4006 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context, 4007 Local<Name> key) { 4008 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasRealNamedProperty()", 4009 bool); 4010 auto self = Utils::OpenHandle(this); 4011 if (!self->IsJSObject()) return Just(false); 4012 auto key_val = Utils::OpenHandle(*key); 4013 auto result = i::JSObject::HasRealNamedProperty( 4014 i::Handle<i::JSObject>::cast(self), key_val); 4015 has_pending_exception = result.IsNothing(); 4016 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 4017 return result; 4018 } 4019 4020 4021 bool v8::Object::HasRealNamedProperty(Local<String> key) { 4022 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4023 return HasRealNamedProperty(context, key).FromMaybe(false); 4024 } 4025 4026 4027 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context, 4028 uint32_t index) { 4029 PREPARE_FOR_EXECUTION_PRIMITIVE(context, 4030 "v8::Object::HasRealIndexedProperty()", bool); 4031 auto self = Utils::OpenHandle(this); 4032 if (!self->IsJSObject()) return Just(false); 4033 auto result = i::JSObject::HasRealElementProperty( 4034 i::Handle<i::JSObject>::cast(self), index); 4035 has_pending_exception = result.IsNothing(); 4036 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 4037 return result; 4038 } 4039 4040 4041 bool v8::Object::HasRealIndexedProperty(uint32_t index) { 4042 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4043 return HasRealIndexedProperty(context, index).FromMaybe(false); 4044 } 4045 4046 4047 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context, 4048 Local<Name> key) { 4049 PREPARE_FOR_EXECUTION_PRIMITIVE( 4050 context, "v8::Object::HasRealNamedCallbackProperty()", bool); 4051 auto self = Utils::OpenHandle(this); 4052 if (!self->IsJSObject()) return Just(false); 4053 auto key_val = Utils::OpenHandle(*key); 4054 auto result = i::JSObject::HasRealNamedCallbackProperty( 4055 i::Handle<i::JSObject>::cast(self), key_val); 4056 has_pending_exception = result.IsNothing(); 4057 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 4058 return result; 4059 } 4060 4061 4062 bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) { 4063 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4064 return HasRealNamedCallbackProperty(context, key).FromMaybe(false); 4065 } 4066 4067 4068 bool v8::Object::HasNamedLookupInterceptor() { 4069 auto self = Utils::OpenHandle(this); 4070 return self->IsJSObject() && 4071 i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor(); 4072 } 4073 4074 4075 bool v8::Object::HasIndexedLookupInterceptor() { 4076 auto self = Utils::OpenHandle(this); 4077 return self->IsJSObject() && 4078 i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor(); 4079 } 4080 4081 4082 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( 4083 Local<Context> context, Local<Name> key) { 4084 PREPARE_FOR_EXECUTION( 4085 context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value); 4086 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 4087 if (!self->IsJSObject()) return MaybeLocal<Value>(); 4088 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key); 4089 i::PrototypeIterator iter(isolate, self); 4090 if (iter.IsAtEnd()) return MaybeLocal<Value>(); 4091 i::Handle<i::JSReceiver> proto = 4092 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter); 4093 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 4094 isolate, self, key_obj, proto, 4095 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); 4096 Local<Value> result; 4097 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result); 4098 RETURN_ON_FAILED_EXECUTION(Value); 4099 if (!it.IsFound()) return MaybeLocal<Value>(); 4100 RETURN_ESCAPED(result); 4101 } 4102 4103 4104 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( 4105 Local<String> key) { 4106 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4107 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key), 4108 Value); 4109 } 4110 4111 4112 Maybe<PropertyAttribute> 4113 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain( 4114 Local<Context> context, Local<Name> key) { 4115 PREPARE_FOR_EXECUTION_PRIMITIVE( 4116 context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()", 4117 PropertyAttribute); 4118 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 4119 if (!self->IsJSObject()) return Nothing<PropertyAttribute>(); 4120 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key); 4121 i::PrototypeIterator iter(isolate, self); 4122 if (iter.IsAtEnd()) return Nothing<PropertyAttribute>(); 4123 i::Handle<i::JSReceiver> proto = 4124 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter); 4125 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 4126 isolate, self, key_obj, proto, 4127 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); 4128 Maybe<i::PropertyAttributes> result = 4129 i::JSReceiver::GetPropertyAttributes(&it); 4130 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); 4131 if (!it.IsFound()) return Nothing<PropertyAttribute>(); 4132 if (result.FromJust() == i::ABSENT) return Just(None); 4133 return Just(static_cast<PropertyAttribute>(result.FromJust())); 4134 } 4135 4136 4137 Maybe<PropertyAttribute> 4138 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) { 4139 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4140 return GetRealNamedPropertyAttributesInPrototypeChain(context, key); 4141 } 4142 4143 4144 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context, 4145 Local<Name> key) { 4146 PREPARE_FOR_EXECUTION(context, "v8::Object::GetRealNamedProperty()", Value); 4147 auto self = Utils::OpenHandle(this); 4148 auto key_obj = Utils::OpenHandle(*key); 4149 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 4150 isolate, self, key_obj, 4151 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); 4152 Local<Value> result; 4153 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result); 4154 RETURN_ON_FAILED_EXECUTION(Value); 4155 if (!it.IsFound()) return MaybeLocal<Value>(); 4156 RETURN_ESCAPED(result); 4157 } 4158 4159 4160 Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) { 4161 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4162 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value); 4163 } 4164 4165 4166 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes( 4167 Local<Context> context, Local<Name> key) { 4168 PREPARE_FOR_EXECUTION_PRIMITIVE( 4169 context, "v8::Object::GetRealNamedPropertyAttributes()", 4170 PropertyAttribute); 4171 auto self = Utils::OpenHandle(this); 4172 auto key_obj = Utils::OpenHandle(*key); 4173 i::LookupIterator it = i::LookupIterator::PropertyOrElement( 4174 isolate, self, key_obj, 4175 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); 4176 auto result = i::JSReceiver::GetPropertyAttributes(&it); 4177 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute); 4178 if (!it.IsFound()) return Nothing<PropertyAttribute>(); 4179 if (result.FromJust() == i::ABSENT) { 4180 return Just(static_cast<PropertyAttribute>(i::NONE)); 4181 } 4182 return Just<PropertyAttribute>( 4183 static_cast<PropertyAttribute>(result.FromJust())); 4184 } 4185 4186 4187 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes( 4188 Local<String> key) { 4189 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4190 return GetRealNamedPropertyAttributes(context, key); 4191 } 4192 4193 4194 Local<v8::Object> v8::Object::Clone() { 4195 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this)); 4196 auto isolate = self->GetIsolate(); 4197 ENTER_V8(isolate); 4198 auto result = isolate->factory()->CopyJSObject(self); 4199 CHECK(!result.is_null()); 4200 return Utils::ToLocal(result); 4201 } 4202 4203 4204 Local<v8::Context> v8::Object::CreationContext() { 4205 auto self = Utils::OpenHandle(this); 4206 auto context = handle(self->GetCreationContext()); 4207 return Utils::ToLocal(context); 4208 } 4209 4210 4211 int v8::Object::GetIdentityHash() { 4212 auto isolate = Utils::OpenHandle(this)->GetIsolate(); 4213 i::HandleScope scope(isolate); 4214 auto self = Utils::OpenHandle(this); 4215 return i::JSReceiver::GetOrCreateIdentityHash(self)->value(); 4216 } 4217 4218 4219 bool v8::Object::SetHiddenValue(v8::Local<v8::String> key, 4220 v8::Local<v8::Value> value) { 4221 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4222 ENTER_V8(isolate); 4223 i::HandleScope scope(isolate); 4224 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 4225 if (!self->IsJSObject()) return false; 4226 i::Handle<i::String> key_obj = Utils::OpenHandle(*key); 4227 i::Handle<i::String> key_string = 4228 isolate->factory()->InternalizeString(key_obj); 4229 if (value.IsEmpty()) { 4230 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self), 4231 key_string); 4232 return true; 4233 } 4234 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value); 4235 i::Handle<i::Object> result = i::JSObject::SetHiddenProperty( 4236 i::Handle<i::JSObject>::cast(self), key_string, value_obj); 4237 return *result == *self; 4238 } 4239 4240 4241 v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Local<v8::String> key) { 4242 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4243 ENTER_V8(isolate); 4244 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 4245 if (!self->IsJSObject()) return v8::Local<v8::Value>(); 4246 i::Handle<i::String> key_obj = Utils::OpenHandle(*key); 4247 i::Handle<i::String> key_string = 4248 isolate->factory()->InternalizeString(key_obj); 4249 i::Handle<i::Object> result( 4250 i::Handle<i::JSObject>::cast(self)->GetHiddenProperty(key_string), 4251 isolate); 4252 if (result->IsTheHole()) return v8::Local<v8::Value>(); 4253 return Utils::ToLocal(result); 4254 } 4255 4256 4257 bool v8::Object::DeleteHiddenValue(v8::Local<v8::String> key) { 4258 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4259 ENTER_V8(isolate); 4260 i::HandleScope scope(isolate); 4261 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 4262 if (!self->IsJSObject()) return false; 4263 i::Handle<i::String> key_obj = Utils::OpenHandle(*key); 4264 i::Handle<i::String> key_string = 4265 isolate->factory()->InternalizeString(key_obj); 4266 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self), 4267 key_string); 4268 return true; 4269 } 4270 4271 4272 bool v8::Object::IsCallable() { 4273 auto self = Utils::OpenHandle(this); 4274 return self->IsCallable(); 4275 } 4276 4277 4278 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context, 4279 Local<Value> recv, int argc, 4280 Local<Value> argv[]) { 4281 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Object::CallAsFunction()", 4282 Value); 4283 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); 4284 auto self = Utils::OpenHandle(this); 4285 auto recv_obj = Utils::OpenHandle(*recv); 4286 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**)); 4287 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); 4288 Local<Value> result; 4289 has_pending_exception = !ToLocal<Value>( 4290 i::Execution::Call(isolate, self, recv_obj, argc, args), &result); 4291 RETURN_ON_FAILED_EXECUTION(Value); 4292 RETURN_ESCAPED(result); 4293 } 4294 4295 4296 Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc, 4297 v8::Local<v8::Value> argv[]) { 4298 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4299 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv); 4300 RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast), 4301 Value); 4302 } 4303 4304 4305 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc, 4306 Local<Value> argv[]) { 4307 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, 4308 "v8::Object::CallAsConstructor()", Value); 4309 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); 4310 auto self = Utils::OpenHandle(this); 4311 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**)); 4312 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); 4313 Local<Value> result; 4314 has_pending_exception = !ToLocal<Value>( 4315 i::Execution::New(isolate, self, self, argc, args), &result); 4316 RETURN_ON_FAILED_EXECUTION(Value); 4317 RETURN_ESCAPED(result); 4318 } 4319 4320 4321 Local<v8::Value> Object::CallAsConstructor(int argc, 4322 v8::Local<v8::Value> argv[]) { 4323 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4324 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv); 4325 RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value); 4326 } 4327 4328 4329 MaybeLocal<Function> Function::New(Local<Context> context, 4330 FunctionCallback callback, Local<Value> data, 4331 int length) { 4332 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate(); 4333 LOG_API(isolate, "Function::New"); 4334 ENTER_V8(isolate); 4335 return FunctionTemplateNew(isolate, callback, nullptr, data, 4336 Local<Signature>(), length, true) 4337 ->GetFunction(context); 4338 } 4339 4340 4341 Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback, 4342 Local<Value> data, int length) { 4343 return Function::New(v8_isolate->GetCurrentContext(), callback, data, length) 4344 .FromMaybe(Local<Function>()); 4345 } 4346 4347 4348 Local<v8::Object> Function::NewInstance() const { 4349 return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, NULL) 4350 .FromMaybe(Local<Object>()); 4351 } 4352 4353 4354 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc, 4355 v8::Local<v8::Value> argv[]) const { 4356 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::NewInstance()", 4357 Object); 4358 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); 4359 auto self = Utils::OpenHandle(this); 4360 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**)); 4361 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); 4362 Local<Object> result; 4363 has_pending_exception = !ToLocal<Object>( 4364 i::Execution::New(isolate, self, self, argc, args), &result); 4365 RETURN_ON_FAILED_EXECUTION(Object); 4366 RETURN_ESCAPED(result); 4367 } 4368 4369 4370 Local<v8::Object> Function::NewInstance(int argc, 4371 v8::Local<v8::Value> argv[]) const { 4372 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4373 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object); 4374 } 4375 4376 4377 MaybeLocal<v8::Value> Function::Call(Local<Context> context, 4378 v8::Local<v8::Value> recv, int argc, 4379 v8::Local<v8::Value> argv[]) { 4380 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::Call()", Value); 4381 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate); 4382 auto self = Utils::OpenHandle(this); 4383 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv); 4384 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**)); 4385 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv); 4386 Local<Value> result; 4387 has_pending_exception = !ToLocal<Value>( 4388 i::Execution::Call(isolate, self, recv_obj, argc, args), &result); 4389 RETURN_ON_FAILED_EXECUTION(Value); 4390 RETURN_ESCAPED(result); 4391 } 4392 4393 4394 Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc, 4395 v8::Local<v8::Value> argv[]) { 4396 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 4397 RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value); 4398 } 4399 4400 4401 void Function::SetName(v8::Local<v8::String> name) { 4402 auto self = Utils::OpenHandle(this); 4403 if (!self->IsJSFunction()) return; 4404 auto func = i::Handle<i::JSFunction>::cast(self); 4405 func->shared()->set_name(*Utils::OpenHandle(*name)); 4406 } 4407 4408 4409 Local<Value> Function::GetName() const { 4410 auto self = Utils::OpenHandle(this); 4411 if (self->IsJSBoundFunction()) { 4412 auto func = i::Handle<i::JSBoundFunction>::cast(self); 4413 return Utils::ToLocal(handle(func->name(), func->GetIsolate())); 4414 } 4415 if (self->IsJSFunction()) { 4416 auto func = i::Handle<i::JSFunction>::cast(self); 4417 return Utils::ToLocal(handle(func->shared()->name(), func->GetIsolate())); 4418 } 4419 return ToApiHandle<Primitive>( 4420 self->GetIsolate()->factory()->undefined_value()); 4421 } 4422 4423 4424 Local<Value> Function::GetInferredName() const { 4425 auto self = Utils::OpenHandle(this); 4426 if (!self->IsJSFunction()) { 4427 return ToApiHandle<Primitive>( 4428 self->GetIsolate()->factory()->undefined_value()); 4429 } 4430 auto func = i::Handle<i::JSFunction>::cast(self); 4431 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(), 4432 func->GetIsolate())); 4433 } 4434 4435 4436 Local<Value> Function::GetDebugName() const { 4437 auto self = Utils::OpenHandle(this); 4438 if (!self->IsJSFunction()) { 4439 return ToApiHandle<Primitive>( 4440 self->GetIsolate()->factory()->undefined_value()); 4441 } 4442 auto func = i::Handle<i::JSFunction>::cast(self); 4443 i::Handle<i::String> name = i::JSFunction::GetDebugName(func); 4444 return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate())); 4445 } 4446 4447 4448 Local<Value> Function::GetDisplayName() const { 4449 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 4450 ENTER_V8(isolate); 4451 auto self = Utils::OpenHandle(this); 4452 if (!self->IsJSFunction()) { 4453 return ToApiHandle<Primitive>(isolate->factory()->undefined_value()); 4454 } 4455 auto func = i::Handle<i::JSFunction>::cast(self); 4456 i::Handle<i::String> property_name = 4457 isolate->factory()->NewStringFromStaticChars("displayName"); 4458 i::Handle<i::Object> value = 4459 i::JSReceiver::GetDataProperty(func, property_name); 4460 if (value->IsString()) { 4461 i::Handle<i::String> name = i::Handle<i::String>::cast(value); 4462 if (name->length() > 0) return Utils::ToLocal(name); 4463 } 4464 return ToApiHandle<Primitive>(isolate->factory()->undefined_value()); 4465 } 4466 4467 4468 ScriptOrigin Function::GetScriptOrigin() const { 4469 auto self = Utils::OpenHandle(this); 4470 if (!self->IsJSFunction()) { 4471 return v8::ScriptOrigin(Local<Value>()); 4472 } 4473 auto func = i::Handle<i::JSFunction>::cast(self); 4474 if (func->shared()->script()->IsScript()) { 4475 i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); 4476 return GetScriptOriginForScript(func->GetIsolate(), script); 4477 } 4478 return v8::ScriptOrigin(Local<Value>()); 4479 } 4480 4481 4482 const int Function::kLineOffsetNotFound = -1; 4483 4484 4485 int Function::GetScriptLineNumber() const { 4486 auto self = Utils::OpenHandle(this); 4487 if (!self->IsJSFunction()) { 4488 return kLineOffsetNotFound; 4489 } 4490 auto func = i::Handle<i::JSFunction>::cast(self); 4491 if (func->shared()->script()->IsScript()) { 4492 i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); 4493 return i::Script::GetLineNumber(script, func->shared()->start_position()); 4494 } 4495 return kLineOffsetNotFound; 4496 } 4497 4498 4499 int Function::GetScriptColumnNumber() const { 4500 auto self = Utils::OpenHandle(this); 4501 if (!self->IsJSFunction()) { 4502 return kLineOffsetNotFound; 4503 } 4504 auto func = i::Handle<i::JSFunction>::cast(self); 4505 if (func->shared()->script()->IsScript()) { 4506 i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); 4507 return i::Script::GetColumnNumber(script, func->shared()->start_position()); 4508 } 4509 return kLineOffsetNotFound; 4510 } 4511 4512 4513 bool Function::IsBuiltin() const { 4514 auto self = Utils::OpenHandle(this); 4515 if (!self->IsJSFunction()) { 4516 return false; 4517 } 4518 auto func = i::Handle<i::JSFunction>::cast(self); 4519 return func->shared()->IsBuiltin(); 4520 } 4521 4522 4523 int Function::ScriptId() const { 4524 auto self = Utils::OpenHandle(this); 4525 if (!self->IsJSFunction()) { 4526 return v8::UnboundScript::kNoScriptId; 4527 } 4528 auto func = i::Handle<i::JSFunction>::cast(self); 4529 if (!func->shared()->script()->IsScript()) { 4530 return v8::UnboundScript::kNoScriptId; 4531 } 4532 i::Handle<i::Script> script(i::Script::cast(func->shared()->script())); 4533 return script->id(); 4534 } 4535 4536 4537 Local<v8::Value> Function::GetBoundFunction() const { 4538 auto self = Utils::OpenHandle(this); 4539 if (self->IsJSBoundFunction()) { 4540 auto bound_function = i::Handle<i::JSBoundFunction>::cast(self); 4541 auto bound_target_function = i::handle( 4542 bound_function->bound_target_function(), bound_function->GetIsolate()); 4543 return Utils::CallableToLocal(bound_target_function); 4544 } 4545 return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate())); 4546 } 4547 4548 4549 int Name::GetIdentityHash() { 4550 auto self = Utils::OpenHandle(this); 4551 return static_cast<int>(self->Hash()); 4552 } 4553 4554 4555 int String::Length() const { 4556 i::Handle<i::String> str = Utils::OpenHandle(this); 4557 return str->length(); 4558 } 4559 4560 4561 bool String::IsOneByte() const { 4562 i::Handle<i::String> str = Utils::OpenHandle(this); 4563 return str->HasOnlyOneByteChars(); 4564 } 4565 4566 4567 // Helpers for ContainsOnlyOneByteHelper 4568 template<size_t size> struct OneByteMask; 4569 template<> struct OneByteMask<4> { 4570 static const uint32_t value = 0xFF00FF00; 4571 }; 4572 template<> struct OneByteMask<8> { 4573 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00); 4574 }; 4575 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value; 4576 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1; 4577 static inline bool Unaligned(const uint16_t* chars) { 4578 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask; 4579 } 4580 4581 4582 static inline const uint16_t* Align(const uint16_t* chars) { 4583 return reinterpret_cast<uint16_t*>( 4584 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask); 4585 } 4586 4587 class ContainsOnlyOneByteHelper { 4588 public: 4589 ContainsOnlyOneByteHelper() : is_one_byte_(true) {} 4590 bool Check(i::String* string) { 4591 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); 4592 if (cons_string == NULL) return is_one_byte_; 4593 return CheckCons(cons_string); 4594 } 4595 void VisitOneByteString(const uint8_t* chars, int length) { 4596 // Nothing to do. 4597 } 4598 void VisitTwoByteString(const uint16_t* chars, int length) { 4599 // Accumulated bits. 4600 uintptr_t acc = 0; 4601 // Align to uintptr_t. 4602 const uint16_t* end = chars + length; 4603 while (Unaligned(chars) && chars != end) { 4604 acc |= *chars++; 4605 } 4606 // Read word aligned in blocks, 4607 // checking the return value at the end of each block. 4608 const uint16_t* aligned_end = Align(end); 4609 const int increment = sizeof(uintptr_t)/sizeof(uint16_t); 4610 const int inner_loops = 16; 4611 while (chars + inner_loops*increment < aligned_end) { 4612 for (int i = 0; i < inner_loops; i++) { 4613 acc |= *reinterpret_cast<const uintptr_t*>(chars); 4614 chars += increment; 4615 } 4616 // Check for early return. 4617 if ((acc & kOneByteMask) != 0) { 4618 is_one_byte_ = false; 4619 return; 4620 } 4621 } 4622 // Read the rest. 4623 while (chars != end) { 4624 acc |= *chars++; 4625 } 4626 // Check result. 4627 if ((acc & kOneByteMask) != 0) is_one_byte_ = false; 4628 } 4629 4630 private: 4631 bool CheckCons(i::ConsString* cons_string) { 4632 while (true) { 4633 // Check left side if flat. 4634 i::String* left = cons_string->first(); 4635 i::ConsString* left_as_cons = 4636 i::String::VisitFlat(this, left, 0); 4637 if (!is_one_byte_) return false; 4638 // Check right side if flat. 4639 i::String* right = cons_string->second(); 4640 i::ConsString* right_as_cons = 4641 i::String::VisitFlat(this, right, 0); 4642 if (!is_one_byte_) return false; 4643 // Standard recurse/iterate trick. 4644 if (left_as_cons != NULL && right_as_cons != NULL) { 4645 if (left->length() < right->length()) { 4646 CheckCons(left_as_cons); 4647 cons_string = right_as_cons; 4648 } else { 4649 CheckCons(right_as_cons); 4650 cons_string = left_as_cons; 4651 } 4652 // Check fast return. 4653 if (!is_one_byte_) return false; 4654 continue; 4655 } 4656 // Descend left in place. 4657 if (left_as_cons != NULL) { 4658 cons_string = left_as_cons; 4659 continue; 4660 } 4661 // Descend right in place. 4662 if (right_as_cons != NULL) { 4663 cons_string = right_as_cons; 4664 continue; 4665 } 4666 // Terminate. 4667 break; 4668 } 4669 return is_one_byte_; 4670 } 4671 bool is_one_byte_; 4672 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper); 4673 }; 4674 4675 4676 bool String::ContainsOnlyOneByte() const { 4677 i::Handle<i::String> str = Utils::OpenHandle(this); 4678 if (str->HasOnlyOneByteChars()) return true; 4679 ContainsOnlyOneByteHelper helper; 4680 return helper.Check(*str); 4681 } 4682 4683 4684 class Utf8LengthHelper : public i::AllStatic { 4685 public: 4686 enum State { 4687 kEndsWithLeadingSurrogate = 1 << 0, 4688 kStartsWithTrailingSurrogate = 1 << 1, 4689 kLeftmostEdgeIsCalculated = 1 << 2, 4690 kRightmostEdgeIsCalculated = 1 << 3, 4691 kLeftmostEdgeIsSurrogate = 1 << 4, 4692 kRightmostEdgeIsSurrogate = 1 << 5 4693 }; 4694 4695 static const uint8_t kInitialState = 0; 4696 4697 static inline bool EndsWithSurrogate(uint8_t state) { 4698 return state & kEndsWithLeadingSurrogate; 4699 } 4700 4701 static inline bool StartsWithSurrogate(uint8_t state) { 4702 return state & kStartsWithTrailingSurrogate; 4703 } 4704 4705 class Visitor { 4706 public: 4707 Visitor() : utf8_length_(0), state_(kInitialState) {} 4708 4709 void VisitOneByteString(const uint8_t* chars, int length) { 4710 int utf8_length = 0; 4711 // Add in length 1 for each non-Latin1 character. 4712 for (int i = 0; i < length; i++) { 4713 utf8_length += *chars++ >> 7; 4714 } 4715 // Add in length 1 for each character. 4716 utf8_length_ = utf8_length + length; 4717 state_ = kInitialState; 4718 } 4719 4720 void VisitTwoByteString(const uint16_t* chars, int length) { 4721 int utf8_length = 0; 4722 int last_character = unibrow::Utf16::kNoPreviousCharacter; 4723 for (int i = 0; i < length; i++) { 4724 uint16_t c = chars[i]; 4725 utf8_length += unibrow::Utf8::Length(c, last_character); 4726 last_character = c; 4727 } 4728 utf8_length_ = utf8_length; 4729 uint8_t state = 0; 4730 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) { 4731 state |= kStartsWithTrailingSurrogate; 4732 } 4733 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) { 4734 state |= kEndsWithLeadingSurrogate; 4735 } 4736 state_ = state; 4737 } 4738 4739 static i::ConsString* VisitFlat(i::String* string, 4740 int* length, 4741 uint8_t* state) { 4742 Visitor visitor; 4743 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string); 4744 *length = visitor.utf8_length_; 4745 *state = visitor.state_; 4746 return cons_string; 4747 } 4748 4749 private: 4750 int utf8_length_; 4751 uint8_t state_; 4752 DISALLOW_COPY_AND_ASSIGN(Visitor); 4753 }; 4754 4755 static inline void MergeLeafLeft(int* length, 4756 uint8_t* state, 4757 uint8_t leaf_state) { 4758 bool edge_surrogate = StartsWithSurrogate(leaf_state); 4759 if (!(*state & kLeftmostEdgeIsCalculated)) { 4760 DCHECK(!(*state & kLeftmostEdgeIsSurrogate)); 4761 *state |= kLeftmostEdgeIsCalculated 4762 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0); 4763 } else if (EndsWithSurrogate(*state) && edge_surrogate) { 4764 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates; 4765 } 4766 if (EndsWithSurrogate(leaf_state)) { 4767 *state |= kEndsWithLeadingSurrogate; 4768 } else { 4769 *state &= ~kEndsWithLeadingSurrogate; 4770 } 4771 } 4772 4773 static inline void MergeLeafRight(int* length, 4774 uint8_t* state, 4775 uint8_t leaf_state) { 4776 bool edge_surrogate = EndsWithSurrogate(leaf_state); 4777 if (!(*state & kRightmostEdgeIsCalculated)) { 4778 DCHECK(!(*state & kRightmostEdgeIsSurrogate)); 4779 *state |= (kRightmostEdgeIsCalculated 4780 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0)); 4781 } else if (edge_surrogate && StartsWithSurrogate(*state)) { 4782 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates; 4783 } 4784 if (StartsWithSurrogate(leaf_state)) { 4785 *state |= kStartsWithTrailingSurrogate; 4786 } else { 4787 *state &= ~kStartsWithTrailingSurrogate; 4788 } 4789 } 4790 4791 static inline void MergeTerminal(int* length, 4792 uint8_t state, 4793 uint8_t* state_out) { 4794 DCHECK((state & kLeftmostEdgeIsCalculated) && 4795 (state & kRightmostEdgeIsCalculated)); 4796 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) { 4797 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates; 4798 } 4799 *state_out = kInitialState | 4800 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) | 4801 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0); 4802 } 4803 4804 static int Calculate(i::ConsString* current, uint8_t* state_out) { 4805 using internal::ConsString; 4806 int total_length = 0; 4807 uint8_t state = kInitialState; 4808 while (true) { 4809 i::String* left = current->first(); 4810 i::String* right = current->second(); 4811 uint8_t right_leaf_state; 4812 uint8_t left_leaf_state; 4813 int leaf_length; 4814 ConsString* left_as_cons = 4815 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state); 4816 if (left_as_cons == NULL) { 4817 total_length += leaf_length; 4818 MergeLeafLeft(&total_length, &state, left_leaf_state); 4819 } 4820 ConsString* right_as_cons = 4821 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state); 4822 if (right_as_cons == NULL) { 4823 total_length += leaf_length; 4824 MergeLeafRight(&total_length, &state, right_leaf_state); 4825 if (left_as_cons != NULL) { 4826 // 1 Leaf node. Descend in place. 4827 current = left_as_cons; 4828 continue; 4829 } else { 4830 // Terminal node. 4831 MergeTerminal(&total_length, state, state_out); 4832 return total_length; 4833 } 4834 } else if (left_as_cons == NULL) { 4835 // 1 Leaf node. Descend in place. 4836 current = right_as_cons; 4837 continue; 4838 } 4839 // Both strings are ConsStrings. 4840 // Recurse on smallest. 4841 if (left->length() < right->length()) { 4842 total_length += Calculate(left_as_cons, &left_leaf_state); 4843 MergeLeafLeft(&total_length, &state, left_leaf_state); 4844 current = right_as_cons; 4845 } else { 4846 total_length += Calculate(right_as_cons, &right_leaf_state); 4847 MergeLeafRight(&total_length, &state, right_leaf_state); 4848 current = left_as_cons; 4849 } 4850 } 4851 UNREACHABLE(); 4852 return 0; 4853 } 4854 4855 static inline int Calculate(i::ConsString* current) { 4856 uint8_t state = kInitialState; 4857 return Calculate(current, &state); 4858 } 4859 4860 private: 4861 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper); 4862 }; 4863 4864 4865 static int Utf8Length(i::String* str, i::Isolate* isolate) { 4866 int length = str->length(); 4867 if (length == 0) return 0; 4868 uint8_t state; 4869 i::ConsString* cons_string = 4870 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state); 4871 if (cons_string == NULL) return length; 4872 return Utf8LengthHelper::Calculate(cons_string); 4873 } 4874 4875 4876 int String::Utf8Length() const { 4877 i::Handle<i::String> str = Utils::OpenHandle(this); 4878 i::Isolate* isolate = str->GetIsolate(); 4879 return v8::Utf8Length(*str, isolate); 4880 } 4881 4882 4883 class Utf8WriterVisitor { 4884 public: 4885 Utf8WriterVisitor( 4886 char* buffer, 4887 int capacity, 4888 bool skip_capacity_check, 4889 bool replace_invalid_utf8) 4890 : early_termination_(false), 4891 last_character_(unibrow::Utf16::kNoPreviousCharacter), 4892 buffer_(buffer), 4893 start_(buffer), 4894 capacity_(capacity), 4895 skip_capacity_check_(capacity == -1 || skip_capacity_check), 4896 replace_invalid_utf8_(replace_invalid_utf8), 4897 utf16_chars_read_(0) { 4898 } 4899 4900 static int WriteEndCharacter(uint16_t character, 4901 int last_character, 4902 int remaining, 4903 char* const buffer, 4904 bool replace_invalid_utf8) { 4905 DCHECK_GT(remaining, 0); 4906 // We can't use a local buffer here because Encode needs to modify 4907 // previous characters in the stream. We know, however, that 4908 // exactly one character will be advanced. 4909 if (unibrow::Utf16::IsSurrogatePair(last_character, character)) { 4910 int written = unibrow::Utf8::Encode(buffer, character, last_character, 4911 replace_invalid_utf8); 4912 DCHECK_EQ(written, 1); 4913 return written; 4914 } 4915 // Use a scratch buffer to check the required characters. 4916 char temp_buffer[unibrow::Utf8::kMaxEncodedSize]; 4917 // Can't encode using last_character as gcc has array bounds issues. 4918 int written = unibrow::Utf8::Encode(temp_buffer, character, 4919 unibrow::Utf16::kNoPreviousCharacter, 4920 replace_invalid_utf8); 4921 // Won't fit. 4922 if (written > remaining) return 0; 4923 // Copy over the character from temp_buffer. 4924 for (int j = 0; j < written; j++) { 4925 buffer[j] = temp_buffer[j]; 4926 } 4927 return written; 4928 } 4929 4930 // Visit writes out a group of code units (chars) of a v8::String to the 4931 // internal buffer_. This is done in two phases. The first phase calculates a 4932 // pesimistic estimate (writable_length) on how many code units can be safely 4933 // written without exceeding the buffer capacity and without writing the last 4934 // code unit (it could be a lead surrogate). The estimated number of code 4935 // units is then written out in one go, and the reported byte usage is used 4936 // to correct the estimate. This is repeated until the estimate becomes <= 0 4937 // or all code units have been written out. The second phase writes out code 4938 // units until the buffer capacity is reached, would be exceeded by the next 4939 // unit, or all units have been written out. 4940 template<typename Char> 4941 void Visit(const Char* chars, const int length) { 4942 DCHECK(!early_termination_); 4943 if (length == 0) return; 4944 // Copy state to stack. 4945 char* buffer = buffer_; 4946 int last_character = sizeof(Char) == 1 4947 ? unibrow::Utf16::kNoPreviousCharacter 4948 : last_character_; 4949 int i = 0; 4950 // Do a fast loop where there is no exit capacity check. 4951 while (true) { 4952 int fast_length; 4953 if (skip_capacity_check_) { 4954 fast_length = length; 4955 } else { 4956 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_); 4957 // Need enough space to write everything but one character. 4958 STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 4959 3); 4960 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3; 4961 int writable_length = 4962 (remaining_capacity - max_size_per_char)/max_size_per_char; 4963 // Need to drop into slow loop. 4964 if (writable_length <= 0) break; 4965 fast_length = i + writable_length; 4966 if (fast_length > length) fast_length = length; 4967 } 4968 // Write the characters to the stream. 4969 if (sizeof(Char) == 1) { 4970 for (; i < fast_length; i++) { 4971 buffer += unibrow::Utf8::EncodeOneByte( 4972 buffer, static_cast<uint8_t>(*chars++)); 4973 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_); 4974 } 4975 } else { 4976 for (; i < fast_length; i++) { 4977 uint16_t character = *chars++; 4978 buffer += unibrow::Utf8::Encode(buffer, character, last_character, 4979 replace_invalid_utf8_); 4980 last_character = character; 4981 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_); 4982 } 4983 } 4984 // Array is fully written. Exit. 4985 if (fast_length == length) { 4986 // Write state back out to object. 4987 last_character_ = last_character; 4988 buffer_ = buffer; 4989 utf16_chars_read_ += length; 4990 return; 4991 } 4992 } 4993 DCHECK(!skip_capacity_check_); 4994 // Slow loop. Must check capacity on each iteration. 4995 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_); 4996 DCHECK_GE(remaining_capacity, 0); 4997 for (; i < length && remaining_capacity > 0; i++) { 4998 uint16_t character = *chars++; 4999 // remaining_capacity is <= 3 bytes at this point, so we do not write out 5000 // an umatched lead surrogate. 5001 if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) { 5002 early_termination_ = true; 5003 break; 5004 } 5005 int written = WriteEndCharacter(character, 5006 last_character, 5007 remaining_capacity, 5008 buffer, 5009 replace_invalid_utf8_); 5010 if (written == 0) { 5011 early_termination_ = true; 5012 break; 5013 } 5014 buffer += written; 5015 remaining_capacity -= written; 5016 last_character = character; 5017 } 5018 // Write state back out to object. 5019 last_character_ = last_character; 5020 buffer_ = buffer; 5021 utf16_chars_read_ += i; 5022 } 5023 5024 inline bool IsDone() { 5025 return early_termination_; 5026 } 5027 5028 inline void VisitOneByteString(const uint8_t* chars, int length) { 5029 Visit(chars, length); 5030 } 5031 5032 inline void VisitTwoByteString(const uint16_t* chars, int length) { 5033 Visit(chars, length); 5034 } 5035 5036 int CompleteWrite(bool write_null, int* utf16_chars_read_out) { 5037 // Write out number of utf16 characters written to the stream. 5038 if (utf16_chars_read_out != NULL) { 5039 *utf16_chars_read_out = utf16_chars_read_; 5040 } 5041 // Only null terminate if all of the string was written and there's space. 5042 if (write_null && 5043 !early_termination_ && 5044 (capacity_ == -1 || (buffer_ - start_) < capacity_)) { 5045 *buffer_++ = '\0'; 5046 } 5047 return static_cast<int>(buffer_ - start_); 5048 } 5049 5050 private: 5051 bool early_termination_; 5052 int last_character_; 5053 char* buffer_; 5054 char* const start_; 5055 int capacity_; 5056 bool const skip_capacity_check_; 5057 bool const replace_invalid_utf8_; 5058 int utf16_chars_read_; 5059 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor); 5060 }; 5061 5062 5063 static bool RecursivelySerializeToUtf8(i::String* current, 5064 Utf8WriterVisitor* writer, 5065 int recursion_budget) { 5066 while (!writer->IsDone()) { 5067 i::ConsString* cons_string = i::String::VisitFlat(writer, current); 5068 if (cons_string == NULL) return true; // Leaf node. 5069 if (recursion_budget <= 0) return false; 5070 // Must write the left branch first. 5071 i::String* first = cons_string->first(); 5072 bool success = RecursivelySerializeToUtf8(first, 5073 writer, 5074 recursion_budget - 1); 5075 if (!success) return false; 5076 // Inline tail recurse for right branch. 5077 current = cons_string->second(); 5078 } 5079 return true; 5080 } 5081 5082 5083 int String::WriteUtf8(char* buffer, 5084 int capacity, 5085 int* nchars_ref, 5086 int options) const { 5087 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); 5088 LOG_API(isolate, "String::WriteUtf8"); 5089 ENTER_V8(isolate); 5090 i::Handle<i::String> str = Utils::OpenHandle(this); 5091 if (options & HINT_MANY_WRITES_EXPECTED) { 5092 str = i::String::Flatten(str); // Flatten the string for efficiency. 5093 } 5094 const int string_length = str->length(); 5095 bool write_null = !(options & NO_NULL_TERMINATION); 5096 bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8); 5097 int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize; 5098 // First check if we can just write the string without checking capacity. 5099 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) { 5100 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8); 5101 const int kMaxRecursion = 100; 5102 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion); 5103 if (success) return writer.CompleteWrite(write_null, nchars_ref); 5104 } else if (capacity >= string_length) { 5105 // First check that the buffer is large enough. 5106 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate()); 5107 if (utf8_bytes <= capacity) { 5108 // one-byte fast path. 5109 if (utf8_bytes == string_length) { 5110 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options); 5111 if (nchars_ref != NULL) *nchars_ref = string_length; 5112 if (write_null && (utf8_bytes+1 <= capacity)) { 5113 return string_length + 1; 5114 } 5115 return string_length; 5116 } 5117 if (write_null && (utf8_bytes+1 > capacity)) { 5118 options |= NO_NULL_TERMINATION; 5119 } 5120 // Recurse once without a capacity limit. 5121 // This will get into the first branch above. 5122 // TODO(dcarney) Check max left rec. in Utf8Length and fall through. 5123 return WriteUtf8(buffer, -1, nchars_ref, options); 5124 } 5125 } 5126 // Recursive slow path can potentially be unreasonable slow. Flatten. 5127 str = i::String::Flatten(str); 5128 Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8); 5129 i::String::VisitFlat(&writer, *str); 5130 return writer.CompleteWrite(write_null, nchars_ref); 5131 } 5132 5133 5134 template<typename CharType> 5135 static inline int WriteHelper(const String* string, 5136 CharType* buffer, 5137 int start, 5138 int length, 5139 int options) { 5140 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate(); 5141 LOG_API(isolate, "String::Write"); 5142 ENTER_V8(isolate); 5143 DCHECK(start >= 0 && length >= -1); 5144 i::Handle<i::String> str = Utils::OpenHandle(string); 5145 if (options & String::HINT_MANY_WRITES_EXPECTED) { 5146 // Flatten the string for efficiency. This applies whether we are 5147 // using StringCharacterStream or Get(i) to access the characters. 5148 str = i::String::Flatten(str); 5149 } 5150 int end = start + length; 5151 if ((length == -1) || (length > str->length() - start) ) 5152 end = str->length(); 5153 if (end < 0) return 0; 5154 i::String::WriteToFlat(*str, buffer, start, end); 5155 if (!(options & String::NO_NULL_TERMINATION) && 5156 (length == -1 || end - start < length)) { 5157 buffer[end - start] = '\0'; 5158 } 5159 return end - start; 5160 } 5161 5162 5163 int String::WriteOneByte(uint8_t* buffer, 5164 int start, 5165 int length, 5166 int options) const { 5167 return WriteHelper(this, buffer, start, length, options); 5168 } 5169 5170 5171 int String::Write(uint16_t* buffer, 5172 int start, 5173 int length, 5174 int options) const { 5175 return WriteHelper(this, buffer, start, length, options); 5176 } 5177 5178 5179 bool v8::String::IsExternal() const { 5180 i::Handle<i::String> str = Utils::OpenHandle(this); 5181 return i::StringShape(*str).IsExternalTwoByte(); 5182 } 5183 5184 5185 bool v8::String::IsExternalOneByte() const { 5186 i::Handle<i::String> str = Utils::OpenHandle(this); 5187 return i::StringShape(*str).IsExternalOneByte(); 5188 } 5189 5190 5191 void v8::String::VerifyExternalStringResource( 5192 v8::String::ExternalStringResource* value) const { 5193 i::Handle<i::String> str = Utils::OpenHandle(this); 5194 const v8::String::ExternalStringResource* expected; 5195 if (i::StringShape(*str).IsExternalTwoByte()) { 5196 const void* resource = 5197 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); 5198 expected = reinterpret_cast<const ExternalStringResource*>(resource); 5199 } else { 5200 expected = NULL; 5201 } 5202 CHECK_EQ(expected, value); 5203 } 5204 5205 void v8::String::VerifyExternalStringResourceBase( 5206 v8::String::ExternalStringResourceBase* value, Encoding encoding) const { 5207 i::Handle<i::String> str = Utils::OpenHandle(this); 5208 const v8::String::ExternalStringResourceBase* expected; 5209 Encoding expectedEncoding; 5210 if (i::StringShape(*str).IsExternalOneByte()) { 5211 const void* resource = 5212 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); 5213 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); 5214 expectedEncoding = ONE_BYTE_ENCODING; 5215 } else if (i::StringShape(*str).IsExternalTwoByte()) { 5216 const void* resource = 5217 i::Handle<i::ExternalTwoByteString>::cast(str)->resource(); 5218 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource); 5219 expectedEncoding = TWO_BYTE_ENCODING; 5220 } else { 5221 expected = NULL; 5222 expectedEncoding = 5223 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING; 5224 } 5225 CHECK_EQ(expected, value); 5226 CHECK_EQ(expectedEncoding, encoding); 5227 } 5228 5229 const v8::String::ExternalOneByteStringResource* 5230 v8::String::GetExternalOneByteStringResource() const { 5231 i::Handle<i::String> str = Utils::OpenHandle(this); 5232 if (i::StringShape(*str).IsExternalOneByte()) { 5233 const void* resource = 5234 i::Handle<i::ExternalOneByteString>::cast(str)->resource(); 5235 return reinterpret_cast<const ExternalOneByteStringResource*>(resource); 5236 } else { 5237 return NULL; 5238 } 5239 } 5240 5241 5242 Local<Value> Symbol::Name() const { 5243 i::Handle<i::Symbol> sym = Utils::OpenHandle(this); 5244 i::Handle<i::Object> name(sym->name(), sym->GetIsolate()); 5245 return Utils::ToLocal(name); 5246 } 5247 5248 5249 Local<Value> Private::Name() const { 5250 return reinterpret_cast<const Symbol*>(this)->Name(); 5251 } 5252 5253 5254 double Number::Value() const { 5255 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5256 return obj->Number(); 5257 } 5258 5259 5260 bool Boolean::Value() const { 5261 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5262 return obj->IsTrue(); 5263 } 5264 5265 5266 int64_t Integer::Value() const { 5267 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5268 if (obj->IsSmi()) { 5269 return i::Smi::cast(*obj)->value(); 5270 } else { 5271 return static_cast<int64_t>(obj->Number()); 5272 } 5273 } 5274 5275 5276 int32_t Int32::Value() const { 5277 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5278 if (obj->IsSmi()) { 5279 return i::Smi::cast(*obj)->value(); 5280 } else { 5281 return static_cast<int32_t>(obj->Number()); 5282 } 5283 } 5284 5285 5286 uint32_t Uint32::Value() const { 5287 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5288 if (obj->IsSmi()) { 5289 return i::Smi::cast(*obj)->value(); 5290 } else { 5291 return static_cast<uint32_t>(obj->Number()); 5292 } 5293 } 5294 5295 5296 int v8::Object::InternalFieldCount() { 5297 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this); 5298 if (!self->IsJSObject()) return 0; 5299 return i::Handle<i::JSObject>::cast(self)->GetInternalFieldCount(); 5300 } 5301 5302 5303 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index, 5304 const char* location) { 5305 return Utils::ApiCheck( 5306 obj->IsJSObject() && 5307 (index < i::Handle<i::JSObject>::cast(obj)->GetInternalFieldCount()), 5308 location, "Internal field out of bounds"); 5309 } 5310 5311 5312 Local<Value> v8::Object::SlowGetInternalField(int index) { 5313 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5314 const char* location = "v8::Object::GetInternalField()"; 5315 if (!InternalFieldOK(obj, index, location)) return Local<Value>(); 5316 i::Handle<i::Object> value( 5317 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), 5318 obj->GetIsolate()); 5319 return Utils::ToLocal(value); 5320 } 5321 5322 5323 void v8::Object::SetInternalField(int index, v8::Local<Value> value) { 5324 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5325 const char* location = "v8::Object::SetInternalField()"; 5326 if (!InternalFieldOK(obj, index, location)) return; 5327 i::Handle<i::Object> val = Utils::OpenHandle(*value); 5328 i::Handle<i::JSObject>::cast(obj)->SetInternalField(index, *val); 5329 } 5330 5331 5332 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) { 5333 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5334 const char* location = "v8::Object::GetAlignedPointerFromInternalField()"; 5335 if (!InternalFieldOK(obj, index, location)) return NULL; 5336 return DecodeSmiToAligned( 5337 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location); 5338 } 5339 5340 5341 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) { 5342 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this); 5343 const char* location = "v8::Object::SetAlignedPointerInInternalField()"; 5344 if (!InternalFieldOK(obj, index, location)) return; 5345 i::Handle<i::JSObject>::cast(obj) 5346 ->SetInternalField(index, EncodeAlignedAsSmi(value, location)); 5347 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index)); 5348 } 5349 5350 5351 static void* ExternalValue(i::Object* obj) { 5352 // Obscure semantics for undefined, but somehow checked in our unit tests... 5353 if (obj->IsUndefined()) return NULL; 5354 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0); 5355 return i::Foreign::cast(foreign)->foreign_address(); 5356 } 5357 5358 5359 // --- E n v i r o n m e n t --- 5360 5361 5362 void v8::V8::InitializePlatform(Platform* platform) { 5363 i::V8::InitializePlatform(platform); 5364 } 5365 5366 5367 void v8::V8::ShutdownPlatform() { 5368 i::V8::ShutdownPlatform(); 5369 } 5370 5371 5372 bool v8::V8::Initialize() { 5373 i::V8::Initialize(); 5374 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 5375 i::ReadNatives(); 5376 #endif 5377 return true; 5378 } 5379 5380 5381 void v8::V8::SetEntropySource(EntropySource entropy_source) { 5382 base::RandomNumberGenerator::SetEntropySource(entropy_source); 5383 } 5384 5385 5386 void v8::V8::SetReturnAddressLocationResolver( 5387 ReturnAddressLocationResolver return_address_resolver) { 5388 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver); 5389 } 5390 5391 5392 bool v8::V8::Dispose() { 5393 i::V8::TearDown(); 5394 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 5395 i::DisposeNatives(); 5396 #endif 5397 return true; 5398 } 5399 5400 5401 HeapStatistics::HeapStatistics(): total_heap_size_(0), 5402 total_heap_size_executable_(0), 5403 total_physical_size_(0), 5404 used_heap_size_(0), 5405 heap_size_limit_(0) { } 5406 5407 5408 HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0), 5409 space_size_(0), 5410 space_used_size_(0), 5411 space_available_size_(0), 5412 physical_space_size_(0) { } 5413 5414 5415 HeapObjectStatistics::HeapObjectStatistics() 5416 : object_type_(nullptr), 5417 object_sub_type_(nullptr), 5418 object_count_(0), 5419 object_size_(0) {} 5420 5421 5422 bool v8::V8::InitializeICU(const char* icu_data_file) { 5423 return i::InitializeICU(icu_data_file); 5424 } 5425 5426 5427 void v8::V8::InitializeExternalStartupData(const char* directory_path) { 5428 i::InitializeExternalStartupData(directory_path); 5429 } 5430 5431 5432 void v8::V8::InitializeExternalStartupData(const char* natives_blob, 5433 const char* snapshot_blob) { 5434 i::InitializeExternalStartupData(natives_blob, snapshot_blob); 5435 } 5436 5437 5438 const char* v8::V8::GetVersion() { 5439 return i::Version::GetVersion(); 5440 } 5441 5442 5443 static i::Handle<i::Context> CreateEnvironment( 5444 i::Isolate* isolate, v8::ExtensionConfiguration* extensions, 5445 v8::Local<ObjectTemplate> global_template, 5446 v8::Local<Value> maybe_global_proxy) { 5447 i::Handle<i::Context> env; 5448 5449 // Enter V8 via an ENTER_V8 scope. 5450 { 5451 ENTER_V8(isolate); 5452 v8::Local<ObjectTemplate> proxy_template = global_template; 5453 i::Handle<i::FunctionTemplateInfo> proxy_constructor; 5454 i::Handle<i::FunctionTemplateInfo> global_constructor; 5455 5456 if (!global_template.IsEmpty()) { 5457 // Make sure that the global_template has a constructor. 5458 global_constructor = EnsureConstructor(isolate, *global_template); 5459 5460 // Create a fresh template for the global proxy object. 5461 proxy_template = ObjectTemplate::New( 5462 reinterpret_cast<v8::Isolate*>(isolate)); 5463 proxy_constructor = EnsureConstructor(isolate, *proxy_template); 5464 5465 // Set the global template to be the prototype template of 5466 // global proxy template. 5467 proxy_constructor->set_prototype_template( 5468 *Utils::OpenHandle(*global_template)); 5469 5470 // Migrate security handlers from global_template to 5471 // proxy_template. Temporarily removing access check 5472 // information from the global template. 5473 if (!global_constructor->access_check_info()->IsUndefined()) { 5474 proxy_constructor->set_access_check_info( 5475 global_constructor->access_check_info()); 5476 proxy_constructor->set_needs_access_check( 5477 global_constructor->needs_access_check()); 5478 global_constructor->set_needs_access_check(false); 5479 global_constructor->set_access_check_info( 5480 isolate->heap()->undefined_value()); 5481 } 5482 } 5483 5484 i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true); 5485 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy; 5486 if (!proxy.is_null()) { 5487 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy); 5488 } 5489 // Create the environment. 5490 env = isolate->bootstrapper()->CreateEnvironment( 5491 maybe_proxy, proxy_template, extensions); 5492 5493 // Restore the access check info on the global template. 5494 if (!global_template.IsEmpty()) { 5495 DCHECK(!global_constructor.is_null()); 5496 DCHECK(!proxy_constructor.is_null()); 5497 global_constructor->set_access_check_info( 5498 proxy_constructor->access_check_info()); 5499 global_constructor->set_needs_access_check( 5500 proxy_constructor->needs_access_check()); 5501 } 5502 } 5503 // Leave V8. 5504 5505 return env; 5506 } 5507 5508 Local<Context> v8::Context::New(v8::Isolate* external_isolate, 5509 v8::ExtensionConfiguration* extensions, 5510 v8::Local<ObjectTemplate> global_template, 5511 v8::Local<Value> global_object) { 5512 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); 5513 LOG_API(isolate, "Context::New"); 5514 i::HandleScope scope(isolate); 5515 ExtensionConfiguration no_extensions; 5516 if (extensions == NULL) extensions = &no_extensions; 5517 i::Handle<i::Context> env = 5518 CreateEnvironment(isolate, extensions, global_template, global_object); 5519 if (env.is_null()) { 5520 if (isolate->has_pending_exception()) { 5521 isolate->OptionalRescheduleException(true); 5522 } 5523 return Local<Context>(); 5524 } 5525 return Utils::ToLocal(scope.CloseAndEscape(env)); 5526 } 5527 5528 5529 void v8::Context::SetSecurityToken(Local<Value> token) { 5530 i::Handle<i::Context> env = Utils::OpenHandle(this); 5531 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token); 5532 env->set_security_token(*token_handle); 5533 } 5534 5535 5536 void v8::Context::UseDefaultSecurityToken() { 5537 i::Handle<i::Context> env = Utils::OpenHandle(this); 5538 env->set_security_token(env->global_object()); 5539 } 5540 5541 5542 Local<Value> v8::Context::GetSecurityToken() { 5543 i::Handle<i::Context> env = Utils::OpenHandle(this); 5544 i::Isolate* isolate = env->GetIsolate(); 5545 i::Object* security_token = env->security_token(); 5546 i::Handle<i::Object> token_handle(security_token, isolate); 5547 return Utils::ToLocal(token_handle); 5548 } 5549 5550 5551 v8::Isolate* Context::GetIsolate() { 5552 i::Handle<i::Context> env = Utils::OpenHandle(this); 5553 return reinterpret_cast<Isolate*>(env->GetIsolate()); 5554 } 5555 5556 5557 v8::Local<v8::Object> Context::Global() { 5558 i::Handle<i::Context> context = Utils::OpenHandle(this); 5559 i::Isolate* isolate = context->GetIsolate(); 5560 i::Handle<i::Object> global(context->global_proxy(), isolate); 5561 // TODO(dcarney): This should always return the global proxy 5562 // but can't presently as calls to GetProtoype will return the wrong result. 5563 if (i::Handle<i::JSGlobalProxy>::cast( 5564 global)->IsDetachedFrom(context->global_object())) { 5565 global = i::Handle<i::Object>(context->global_object(), isolate); 5566 } 5567 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global)); 5568 } 5569 5570 5571 void Context::DetachGlobal() { 5572 i::Handle<i::Context> context = Utils::OpenHandle(this); 5573 i::Isolate* isolate = context->GetIsolate(); 5574 ENTER_V8(isolate); 5575 isolate->bootstrapper()->DetachGlobal(context); 5576 } 5577 5578 5579 Local<v8::Object> Context::GetExtrasBindingObject() { 5580 i::Handle<i::Context> context = Utils::OpenHandle(this); 5581 i::Isolate* isolate = context->GetIsolate(); 5582 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate); 5583 return Utils::ToLocal(binding); 5584 } 5585 5586 5587 void Context::AllowCodeGenerationFromStrings(bool allow) { 5588 i::Handle<i::Context> context = Utils::OpenHandle(this); 5589 i::Isolate* isolate = context->GetIsolate(); 5590 ENTER_V8(isolate); 5591 context->set_allow_code_gen_from_strings( 5592 allow ? isolate->heap()->true_value() : isolate->heap()->false_value()); 5593 } 5594 5595 5596 bool Context::IsCodeGenerationFromStringsAllowed() { 5597 i::Handle<i::Context> context = Utils::OpenHandle(this); 5598 return !context->allow_code_gen_from_strings()->IsFalse(); 5599 } 5600 5601 5602 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) { 5603 i::Handle<i::Context> context = Utils::OpenHandle(this); 5604 i::Handle<i::String> error_handle = Utils::OpenHandle(*error); 5605 context->set_error_message_for_code_gen_from_strings(*error_handle); 5606 } 5607 5608 5609 size_t Context::EstimatedSize() { 5610 return static_cast<size_t>( 5611 i::ContextMeasure(*Utils::OpenHandle(this)).Size()); 5612 } 5613 5614 5615 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) { 5616 PREPARE_FOR_EXECUTION(context, "v8::ObjectTemplate::NewInstance()", Object); 5617 auto self = Utils::OpenHandle(this); 5618 Local<Object> result; 5619 has_pending_exception = 5620 !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result); 5621 RETURN_ON_FAILED_EXECUTION(Object); 5622 RETURN_ESCAPED(result); 5623 } 5624 5625 5626 Local<v8::Object> ObjectTemplate::NewInstance() { 5627 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 5628 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object); 5629 } 5630 5631 5632 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) { 5633 PREPARE_FOR_EXECUTION(context, "v8::FunctionTemplate::GetFunction()", 5634 Function); 5635 auto self = Utils::OpenHandle(this); 5636 Local<Function> result; 5637 has_pending_exception = 5638 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result); 5639 RETURN_ON_FAILED_EXECUTION(Function); 5640 RETURN_ESCAPED(result); 5641 } 5642 5643 5644 Local<v8::Function> FunctionTemplate::GetFunction() { 5645 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 5646 RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function); 5647 } 5648 5649 5650 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) { 5651 auto self = Utils::OpenHandle(this); 5652 auto obj = Utils::OpenHandle(*value); 5653 return self->IsTemplateFor(*obj); 5654 } 5655 5656 5657 Local<External> v8::External::New(Isolate* isolate, void* value) { 5658 STATIC_ASSERT(sizeof(value) == sizeof(i::Address)); 5659 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5660 LOG_API(i_isolate, "External::New"); 5661 ENTER_V8(i_isolate); 5662 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value); 5663 return Utils::ExternalToLocal(external); 5664 } 5665 5666 5667 void* External::Value() const { 5668 return ExternalValue(*Utils::OpenHandle(this)); 5669 } 5670 5671 5672 // anonymous namespace for string creation helper functions 5673 namespace { 5674 5675 inline int StringLength(const char* string) { 5676 return i::StrLength(string); 5677 } 5678 5679 5680 inline int StringLength(const uint8_t* string) { 5681 return i::StrLength(reinterpret_cast<const char*>(string)); 5682 } 5683 5684 5685 inline int StringLength(const uint16_t* string) { 5686 int length = 0; 5687 while (string[length] != '\0') 5688 length++; 5689 return length; 5690 } 5691 5692 5693 MUST_USE_RESULT 5694 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, 5695 v8::NewStringType type, 5696 i::Vector<const char> string) { 5697 if (type == v8::NewStringType::kInternalized) { 5698 return factory->InternalizeUtf8String(string); 5699 } 5700 return factory->NewStringFromUtf8(string); 5701 } 5702 5703 5704 MUST_USE_RESULT 5705 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, 5706 v8::NewStringType type, 5707 i::Vector<const uint8_t> string) { 5708 if (type == v8::NewStringType::kInternalized) { 5709 return factory->InternalizeOneByteString(string); 5710 } 5711 return factory->NewStringFromOneByte(string); 5712 } 5713 5714 5715 MUST_USE_RESULT 5716 inline i::MaybeHandle<i::String> NewString(i::Factory* factory, 5717 v8::NewStringType type, 5718 i::Vector<const uint16_t> string) { 5719 if (type == v8::NewStringType::kInternalized) { 5720 return factory->InternalizeTwoByteString(string); 5721 } 5722 return factory->NewStringFromTwoByte(string); 5723 } 5724 5725 5726 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength); 5727 5728 5729 template <typename Char> 5730 inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location, 5731 const char* env, const Char* data, 5732 v8::NewStringType type, int length) { 5733 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate); 5734 if (length == 0) return String::Empty(v8_isolate); 5735 // TODO(dcarney): throw a context free exception. 5736 if (length > i::String::kMaxLength) return MaybeLocal<String>(); 5737 ENTER_V8(isolate); 5738 LOG_API(isolate, env); 5739 if (length < 0) length = StringLength(data); 5740 i::Handle<i::String> result = 5741 NewString(isolate->factory(), type, i::Vector<const Char>(data, length)) 5742 .ToHandleChecked(); 5743 return Utils::ToLocal(result); 5744 } 5745 5746 } // anonymous namespace 5747 5748 5749 Local<String> String::NewFromUtf8(Isolate* isolate, 5750 const char* data, 5751 NewStringType type, 5752 int length) { 5753 RETURN_TO_LOCAL_UNCHECKED( 5754 NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8", 5755 data, static_cast<v8::NewStringType>(type), length), 5756 String); 5757 } 5758 5759 5760 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data, 5761 v8::NewStringType type, int length) { 5762 return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8", 5763 data, type, length); 5764 } 5765 5766 5767 Local<String> String::NewFromOneByte(Isolate* isolate, 5768 const uint8_t* data, 5769 NewStringType type, 5770 int length) { 5771 RETURN_TO_LOCAL_UNCHECKED( 5772 NewString(isolate, "v8::String::NewFromOneByte()", 5773 "String::NewFromOneByte", data, 5774 static_cast<v8::NewStringType>(type), length), 5775 String); 5776 } 5777 5778 5779 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data, 5780 v8::NewStringType type, int length) { 5781 return NewString(isolate, "v8::String::NewFromOneByte()", 5782 "String::NewFromOneByte", data, type, length); 5783 } 5784 5785 5786 Local<String> String::NewFromTwoByte(Isolate* isolate, 5787 const uint16_t* data, 5788 NewStringType type, 5789 int length) { 5790 RETURN_TO_LOCAL_UNCHECKED( 5791 NewString(isolate, "v8::String::NewFromTwoByte()", 5792 "String::NewFromTwoByte", data, 5793 static_cast<v8::NewStringType>(type), length), 5794 String); 5795 } 5796 5797 5798 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate, 5799 const uint16_t* data, 5800 v8::NewStringType type, int length) { 5801 return NewString(isolate, "v8::String::NewFromTwoByte()", 5802 "String::NewFromTwoByte", data, type, length); 5803 } 5804 5805 5806 Local<String> v8::String::Concat(Local<String> left, Local<String> right) { 5807 i::Handle<i::String> left_string = Utils::OpenHandle(*left); 5808 i::Isolate* isolate = left_string->GetIsolate(); 5809 ENTER_V8(isolate); 5810 LOG_API(isolate, "v8::String::Concat"); 5811 i::Handle<i::String> right_string = Utils::OpenHandle(*right); 5812 // If we are steering towards a range error, do not wait for the error to be 5813 // thrown, and return the null handle instead. 5814 if (left_string->length() + right_string->length() > i::String::kMaxLength) { 5815 return Local<String>(); 5816 } 5817 i::Handle<i::String> result = isolate->factory()->NewConsString( 5818 left_string, right_string).ToHandleChecked(); 5819 return Utils::ToLocal(result); 5820 } 5821 5822 5823 MaybeLocal<String> v8::String::NewExternalTwoByte( 5824 Isolate* isolate, v8::String::ExternalStringResource* resource) { 5825 CHECK(resource && resource->data()); 5826 // TODO(dcarney): throw a context free exception. 5827 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 5828 return MaybeLocal<String>(); 5829 } 5830 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5831 ENTER_V8(i_isolate); 5832 LOG_API(i_isolate, "String::NewExternalTwoByte"); 5833 i::Handle<i::String> string = i_isolate->factory() 5834 ->NewExternalStringFromTwoByte(resource) 5835 .ToHandleChecked(); 5836 i_isolate->heap()->RegisterExternalString(*string); 5837 return Utils::ToLocal(string); 5838 } 5839 5840 5841 Local<String> v8::String::NewExternal( 5842 Isolate* isolate, v8::String::ExternalStringResource* resource) { 5843 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String); 5844 } 5845 5846 5847 MaybeLocal<String> v8::String::NewExternalOneByte( 5848 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { 5849 CHECK(resource && resource->data()); 5850 // TODO(dcarney): throw a context free exception. 5851 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) { 5852 return MaybeLocal<String>(); 5853 } 5854 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5855 ENTER_V8(i_isolate); 5856 LOG_API(i_isolate, "String::NewExternalOneByte"); 5857 i::Handle<i::String> string = i_isolate->factory() 5858 ->NewExternalStringFromOneByte(resource) 5859 .ToHandleChecked(); 5860 i_isolate->heap()->RegisterExternalString(*string); 5861 return Utils::ToLocal(string); 5862 } 5863 5864 5865 Local<String> v8::String::NewExternal( 5866 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { 5867 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String); 5868 } 5869 5870 5871 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { 5872 i::Handle<i::String> obj = Utils::OpenHandle(this); 5873 i::Isolate* isolate = obj->GetIsolate(); 5874 if (i::StringShape(*obj).IsExternal()) { 5875 return false; // Already an external string. 5876 } 5877 ENTER_V8(isolate); 5878 if (isolate->heap()->IsInGCPostProcessing()) { 5879 return false; 5880 } 5881 CHECK(resource && resource->data()); 5882 5883 bool result = obj->MakeExternal(resource); 5884 // Assert that if CanMakeExternal(), then externalizing actually succeeds. 5885 DCHECK(!CanMakeExternal() || result); 5886 if (result) { 5887 DCHECK(obj->IsExternalString()); 5888 isolate->heap()->RegisterExternalString(*obj); 5889 } 5890 return result; 5891 } 5892 5893 5894 bool v8::String::MakeExternal( 5895 v8::String::ExternalOneByteStringResource* resource) { 5896 i::Handle<i::String> obj = Utils::OpenHandle(this); 5897 i::Isolate* isolate = obj->GetIsolate(); 5898 if (i::StringShape(*obj).IsExternal()) { 5899 return false; // Already an external string. 5900 } 5901 ENTER_V8(isolate); 5902 if (isolate->heap()->IsInGCPostProcessing()) { 5903 return false; 5904 } 5905 CHECK(resource && resource->data()); 5906 5907 bool result = obj->MakeExternal(resource); 5908 // Assert that if CanMakeExternal(), then externalizing actually succeeds. 5909 DCHECK(!CanMakeExternal() || result); 5910 if (result) { 5911 DCHECK(obj->IsExternalString()); 5912 isolate->heap()->RegisterExternalString(*obj); 5913 } 5914 return result; 5915 } 5916 5917 5918 bool v8::String::CanMakeExternal() { 5919 i::Handle<i::String> obj = Utils::OpenHandle(this); 5920 i::Isolate* isolate = obj->GetIsolate(); 5921 5922 // Old space strings should be externalized. 5923 if (!isolate->heap()->new_space()->Contains(*obj)) return true; 5924 int size = obj->Size(); // Byte size of the original string. 5925 if (size <= i::ExternalString::kShortSize) return false; 5926 i::StringShape shape(*obj); 5927 return !shape.IsExternal(); 5928 } 5929 5930 5931 Isolate* v8::Object::GetIsolate() { 5932 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate(); 5933 return reinterpret_cast<Isolate*>(i_isolate); 5934 } 5935 5936 5937 Local<v8::Object> v8::Object::New(Isolate* isolate) { 5938 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5939 LOG_API(i_isolate, "Object::New"); 5940 ENTER_V8(i_isolate); 5941 i::Handle<i::JSObject> obj = 5942 i_isolate->factory()->NewJSObject(i_isolate->object_function()); 5943 return Utils::ToLocal(obj); 5944 } 5945 5946 5947 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) { 5948 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5949 LOG_API(i_isolate, "NumberObject::New"); 5950 ENTER_V8(i_isolate); 5951 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value); 5952 i::Handle<i::Object> obj = 5953 i::Object::ToObject(i_isolate, number).ToHandleChecked(); 5954 return Utils::ToLocal(obj); 5955 } 5956 5957 5958 double v8::NumberObject::ValueOf() const { 5959 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5960 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj); 5961 i::Isolate* isolate = jsvalue->GetIsolate(); 5962 LOG_API(isolate, "NumberObject::NumberValue"); 5963 return jsvalue->value()->Number(); 5964 } 5965 5966 5967 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) { 5968 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 5969 LOG_API(i_isolate, "BooleanObject::New"); 5970 ENTER_V8(i_isolate); 5971 i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value() 5972 : i_isolate->heap()->false_value(), 5973 i_isolate); 5974 i::Handle<i::Object> obj = 5975 i::Object::ToObject(i_isolate, boolean).ToHandleChecked(); 5976 return Utils::ToLocal(obj); 5977 } 5978 5979 5980 Local<v8::Value> v8::BooleanObject::New(bool value) { 5981 return New(Isolate::GetCurrent(), value); 5982 } 5983 5984 5985 bool v8::BooleanObject::ValueOf() const { 5986 i::Handle<i::Object> obj = Utils::OpenHandle(this); 5987 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj); 5988 i::Isolate* isolate = jsvalue->GetIsolate(); 5989 LOG_API(isolate, "BooleanObject::BooleanValue"); 5990 return jsvalue->value()->IsTrue(); 5991 } 5992 5993 5994 Local<v8::Value> v8::StringObject::New(Local<String> value) { 5995 i::Handle<i::String> string = Utils::OpenHandle(*value); 5996 i::Isolate* isolate = string->GetIsolate(); 5997 LOG_API(isolate, "StringObject::New"); 5998 ENTER_V8(isolate); 5999 i::Handle<i::Object> obj = 6000 i::Object::ToObject(isolate, string).ToHandleChecked(); 6001 return Utils::ToLocal(obj); 6002 } 6003 6004 6005 Local<v8::String> v8::StringObject::ValueOf() const { 6006 i::Handle<i::Object> obj = Utils::OpenHandle(this); 6007 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj); 6008 i::Isolate* isolate = jsvalue->GetIsolate(); 6009 LOG_API(isolate, "StringObject::StringValue"); 6010 return Utils::ToLocal( 6011 i::Handle<i::String>(i::String::cast(jsvalue->value()))); 6012 } 6013 6014 6015 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) { 6016 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6017 LOG_API(i_isolate, "SymbolObject::New"); 6018 ENTER_V8(i_isolate); 6019 i::Handle<i::Object> obj = i::Object::ToObject( 6020 i_isolate, Utils::OpenHandle(*value)).ToHandleChecked(); 6021 return Utils::ToLocal(obj); 6022 } 6023 6024 6025 Local<v8::Symbol> v8::SymbolObject::ValueOf() const { 6026 i::Handle<i::Object> obj = Utils::OpenHandle(this); 6027 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj); 6028 i::Isolate* isolate = jsvalue->GetIsolate(); 6029 LOG_API(isolate, "SymbolObject::SymbolValue"); 6030 return Utils::ToLocal( 6031 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value()))); 6032 } 6033 6034 6035 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) { 6036 if (std::isnan(time)) { 6037 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. 6038 time = std::numeric_limits<double>::quiet_NaN(); 6039 } 6040 PREPARE_FOR_EXECUTION(context, "Date::New", Value); 6041 Local<Value> result; 6042 has_pending_exception = !ToLocal<Value>( 6043 i::JSDate::New(isolate->date_function(), isolate->date_function(), time), 6044 &result); 6045 RETURN_ON_FAILED_EXECUTION(Value); 6046 RETURN_ESCAPED(result); 6047 } 6048 6049 6050 Local<v8::Value> v8::Date::New(Isolate* isolate, double time) { 6051 auto context = isolate->GetCurrentContext(); 6052 RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value); 6053 } 6054 6055 6056 double v8::Date::ValueOf() const { 6057 i::Handle<i::Object> obj = Utils::OpenHandle(this); 6058 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj); 6059 i::Isolate* isolate = jsdate->GetIsolate(); 6060 LOG_API(isolate, "Date::NumberValue"); 6061 return jsdate->value()->Number(); 6062 } 6063 6064 6065 void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) { 6066 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6067 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification"); 6068 ENTER_V8(i_isolate); 6069 i_isolate->date_cache()->ResetDateCache(); 6070 if (!i_isolate->eternal_handles()->Exists( 6071 i::EternalHandles::DATE_CACHE_VERSION)) { 6072 return; 6073 } 6074 i::Handle<i::FixedArray> date_cache_version = 6075 i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton( 6076 i::EternalHandles::DATE_CACHE_VERSION)); 6077 DCHECK_EQ(1, date_cache_version->length()); 6078 CHECK(date_cache_version->get(0)->IsSmi()); 6079 date_cache_version->set( 6080 0, 6081 i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1)); 6082 } 6083 6084 6085 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context, 6086 Local<String> pattern, Flags flags) { 6087 PREPARE_FOR_EXECUTION(context, "RegExp::New", RegExp); 6088 Local<v8::RegExp> result; 6089 has_pending_exception = 6090 !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern), 6091 static_cast<i::JSRegExp::Flags>(flags)), 6092 &result); 6093 RETURN_ON_FAILED_EXECUTION(RegExp); 6094 RETURN_ESCAPED(result); 6095 } 6096 6097 6098 Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) { 6099 auto isolate = 6100 reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate()); 6101 auto context = isolate->GetCurrentContext(); 6102 RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp); 6103 } 6104 6105 6106 Local<v8::String> v8::RegExp::GetSource() const { 6107 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this); 6108 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern())); 6109 } 6110 6111 6112 // Assert that the static flags cast in GetFlags is valid. 6113 #define REGEXP_FLAG_ASSERT_EQ(flag) \ 6114 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \ 6115 static_cast<int>(i::JSRegExp::flag)) 6116 REGEXP_FLAG_ASSERT_EQ(kNone); 6117 REGEXP_FLAG_ASSERT_EQ(kGlobal); 6118 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase); 6119 REGEXP_FLAG_ASSERT_EQ(kMultiline); 6120 REGEXP_FLAG_ASSERT_EQ(kSticky); 6121 REGEXP_FLAG_ASSERT_EQ(kUnicode); 6122 #undef REGEXP_FLAG_ASSERT_EQ 6123 6124 v8::RegExp::Flags v8::RegExp::GetFlags() const { 6125 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this); 6126 return RegExp::Flags(static_cast<int>(obj->GetFlags())); 6127 } 6128 6129 6130 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) { 6131 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6132 LOG_API(i_isolate, "Array::New"); 6133 ENTER_V8(i_isolate); 6134 int real_length = length > 0 ? length : 0; 6135 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length); 6136 i::Handle<i::Object> length_obj = 6137 i_isolate->factory()->NewNumberFromInt(real_length); 6138 obj->set_length(*length_obj); 6139 return Utils::ToLocal(obj); 6140 } 6141 6142 6143 uint32_t v8::Array::Length() const { 6144 i::Handle<i::JSArray> obj = Utils::OpenHandle(this); 6145 i::Object* length = obj->length(); 6146 if (length->IsSmi()) { 6147 return i::Smi::cast(length)->value(); 6148 } else { 6149 return static_cast<uint32_t>(length->Number()); 6150 } 6151 } 6152 6153 6154 MaybeLocal<Object> Array::CloneElementAt(Local<Context> context, 6155 uint32_t index) { 6156 PREPARE_FOR_EXECUTION(context, "v8::Array::CloneElementAt()", Object); 6157 auto self = Utils::OpenHandle(this); 6158 if (!self->HasFastObjectElements()) return Local<Object>(); 6159 i::FixedArray* elms = i::FixedArray::cast(self->elements()); 6160 i::Object* paragon = elms->get(index); 6161 if (!paragon->IsJSObject()) return Local<Object>(); 6162 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon)); 6163 Local<Object> result; 6164 has_pending_exception = 6165 !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle), 6166 &result); 6167 RETURN_ON_FAILED_EXECUTION(Object); 6168 RETURN_ESCAPED(result); 6169 } 6170 6171 6172 Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); } 6173 6174 6175 Local<v8::Map> v8::Map::New(Isolate* isolate) { 6176 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6177 LOG_API(i_isolate, "Map::New"); 6178 ENTER_V8(i_isolate); 6179 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap(); 6180 return Utils::ToLocal(obj); 6181 } 6182 6183 6184 size_t v8::Map::Size() const { 6185 i::Handle<i::JSMap> obj = Utils::OpenHandle(this); 6186 return i::OrderedHashMap::cast(obj->table())->NumberOfElements(); 6187 } 6188 6189 6190 void Map::Clear() { 6191 auto self = Utils::OpenHandle(this); 6192 i::Isolate* isolate = self->GetIsolate(); 6193 LOG_API(isolate, "Map::Clear"); 6194 ENTER_V8(isolate); 6195 i::JSMap::Clear(self); 6196 } 6197 6198 6199 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) { 6200 PREPARE_FOR_EXECUTION(context, "Map::Get", Value); 6201 auto self = Utils::OpenHandle(this); 6202 Local<Value> result; 6203 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6204 has_pending_exception = 6205 !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self, 6206 arraysize(argv), argv), 6207 &result); 6208 RETURN_ON_FAILED_EXECUTION(Value); 6209 RETURN_ESCAPED(result); 6210 } 6211 6212 6213 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key, 6214 Local<Value> value) { 6215 PREPARE_FOR_EXECUTION(context, "Map::Set", Map); 6216 auto self = Utils::OpenHandle(this); 6217 i::Handle<i::Object> result; 6218 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key), 6219 Utils::OpenHandle(*value)}; 6220 has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self, 6221 arraysize(argv), argv) 6222 .ToHandle(&result); 6223 RETURN_ON_FAILED_EXECUTION(Map); 6224 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result))); 6225 } 6226 6227 6228 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) { 6229 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool); 6230 auto self = Utils::OpenHandle(this); 6231 i::Handle<i::Object> result; 6232 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6233 has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self, 6234 arraysize(argv), argv) 6235 .ToHandle(&result); 6236 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6237 return Just(result->IsTrue()); 6238 } 6239 6240 6241 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) { 6242 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool); 6243 auto self = Utils::OpenHandle(this); 6244 i::Handle<i::Object> result; 6245 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6246 has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(), 6247 self, arraysize(argv), argv) 6248 .ToHandle(&result); 6249 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6250 return Just(result->IsTrue()); 6251 } 6252 6253 6254 Local<Array> Map::AsArray() const { 6255 i::Handle<i::JSMap> obj = Utils::OpenHandle(this); 6256 i::Isolate* isolate = obj->GetIsolate(); 6257 i::Factory* factory = isolate->factory(); 6258 LOG_API(isolate, "Map::AsArray"); 6259 ENTER_V8(isolate); 6260 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table())); 6261 int size = table->NumberOfElements(); 6262 int length = size * 2; 6263 i::Handle<i::FixedArray> result = factory->NewFixedArray(length); 6264 for (int i = 0; i < size; ++i) { 6265 if (table->KeyAt(i)->IsTheHole()) continue; 6266 result->set(i * 2, table->KeyAt(i)); 6267 result->set(i * 2 + 1, table->ValueAt(i)); 6268 } 6269 i::Handle<i::JSArray> result_array = 6270 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length); 6271 return Utils::ToLocal(result_array); 6272 } 6273 6274 6275 Local<v8::Set> v8::Set::New(Isolate* isolate) { 6276 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6277 LOG_API(i_isolate, "Set::New"); 6278 ENTER_V8(i_isolate); 6279 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet(); 6280 return Utils::ToLocal(obj); 6281 } 6282 6283 6284 size_t v8::Set::Size() const { 6285 i::Handle<i::JSSet> obj = Utils::OpenHandle(this); 6286 return i::OrderedHashSet::cast(obj->table())->NumberOfElements(); 6287 } 6288 6289 6290 void Set::Clear() { 6291 auto self = Utils::OpenHandle(this); 6292 i::Isolate* isolate = self->GetIsolate(); 6293 LOG_API(isolate, "Set::Clear"); 6294 ENTER_V8(isolate); 6295 i::JSSet::Clear(self); 6296 } 6297 6298 6299 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) { 6300 PREPARE_FOR_EXECUTION(context, "Set::Add", Set); 6301 auto self = Utils::OpenHandle(this); 6302 i::Handle<i::Object> result; 6303 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6304 has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self, 6305 arraysize(argv), argv) 6306 .ToHandle(&result); 6307 RETURN_ON_FAILED_EXECUTION(Set); 6308 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result))); 6309 } 6310 6311 6312 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) { 6313 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool); 6314 auto self = Utils::OpenHandle(this); 6315 i::Handle<i::Object> result; 6316 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6317 has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self, 6318 arraysize(argv), argv) 6319 .ToHandle(&result); 6320 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6321 return Just(result->IsTrue()); 6322 } 6323 6324 6325 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) { 6326 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool); 6327 auto self = Utils::OpenHandle(this); 6328 i::Handle<i::Object> result; 6329 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)}; 6330 has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(), 6331 self, arraysize(argv), argv) 6332 .ToHandle(&result); 6333 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6334 return Just(result->IsTrue()); 6335 } 6336 6337 6338 Local<Array> Set::AsArray() const { 6339 i::Handle<i::JSSet> obj = Utils::OpenHandle(this); 6340 i::Isolate* isolate = obj->GetIsolate(); 6341 i::Factory* factory = isolate->factory(); 6342 LOG_API(isolate, "Set::AsArray"); 6343 ENTER_V8(isolate); 6344 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table())); 6345 int length = table->NumberOfElements(); 6346 i::Handle<i::FixedArray> result = factory->NewFixedArray(length); 6347 for (int i = 0; i < length; ++i) { 6348 i::Object* key = table->KeyAt(i); 6349 if (!key->IsTheHole()) { 6350 result->set(i, key); 6351 } 6352 } 6353 i::Handle<i::JSArray> result_array = 6354 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length); 6355 return Utils::ToLocal(result_array); 6356 } 6357 6358 6359 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) { 6360 PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver); 6361 i::Handle<i::Object> result; 6362 has_pending_exception = 6363 !i::Execution::Call(isolate, isolate->promise_create(), 6364 isolate->factory()->undefined_value(), 0, NULL) 6365 .ToHandle(&result); 6366 RETURN_ON_FAILED_EXECUTION(Promise::Resolver); 6367 RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result))); 6368 } 6369 6370 6371 Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) { 6372 RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()), 6373 Promise::Resolver); 6374 } 6375 6376 6377 Local<Promise> Promise::Resolver::GetPromise() { 6378 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); 6379 return Local<Promise>::Cast(Utils::ToLocal(promise)); 6380 } 6381 6382 6383 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context, 6384 Local<Value> value) { 6385 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool); 6386 auto self = Utils::OpenHandle(this); 6387 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)}; 6388 has_pending_exception = 6389 i::Execution::Call(isolate, isolate->promise_resolve(), 6390 isolate->factory()->undefined_value(), arraysize(argv), 6391 argv) 6392 .is_null(); 6393 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6394 return Just(true); 6395 } 6396 6397 6398 void Promise::Resolver::Resolve(Local<Value> value) { 6399 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 6400 USE(Resolve(context, value)); 6401 } 6402 6403 6404 Maybe<bool> Promise::Resolver::Reject(Local<Context> context, 6405 Local<Value> value) { 6406 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool); 6407 auto self = Utils::OpenHandle(this); 6408 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)}; 6409 has_pending_exception = 6410 i::Execution::Call(isolate, isolate->promise_reject(), 6411 isolate->factory()->undefined_value(), arraysize(argv), 6412 argv) 6413 .is_null(); 6414 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); 6415 return Just(true); 6416 } 6417 6418 6419 void Promise::Resolver::Reject(Local<Value> value) { 6420 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 6421 USE(Reject(context, value)); 6422 } 6423 6424 6425 namespace { 6426 6427 MaybeLocal<Promise> DoChain(Value* value, Local<Context> context, 6428 Local<Function> handler) { 6429 PREPARE_FOR_EXECUTION(context, "Promise::Chain", Promise); 6430 auto self = Utils::OpenHandle(value); 6431 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)}; 6432 i::Handle<i::Object> result; 6433 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(), 6434 self, arraysize(argv), argv) 6435 .ToHandle(&result); 6436 RETURN_ON_FAILED_EXECUTION(Promise); 6437 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 6438 } 6439 6440 } // namespace 6441 6442 6443 MaybeLocal<Promise> Promise::Chain(Local<Context> context, 6444 Local<Function> handler) { 6445 return DoChain(this, context, handler); 6446 } 6447 6448 6449 Local<Promise> Promise::Chain(Local<Function> handler) { 6450 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 6451 RETURN_TO_LOCAL_UNCHECKED(DoChain(this, context, handler), Promise); 6452 } 6453 6454 6455 MaybeLocal<Promise> Promise::Catch(Local<Context> context, 6456 Local<Function> handler) { 6457 PREPARE_FOR_EXECUTION(context, "Promise::Catch", Promise); 6458 auto self = Utils::OpenHandle(this); 6459 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) }; 6460 i::Handle<i::Object> result; 6461 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(), 6462 self, arraysize(argv), argv) 6463 .ToHandle(&result); 6464 RETURN_ON_FAILED_EXECUTION(Promise); 6465 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 6466 } 6467 6468 6469 Local<Promise> Promise::Catch(Local<Function> handler) { 6470 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 6471 RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise); 6472 } 6473 6474 6475 MaybeLocal<Promise> Promise::Then(Local<Context> context, 6476 Local<Function> handler) { 6477 PREPARE_FOR_EXECUTION(context, "Promise::Then", Promise); 6478 auto self = Utils::OpenHandle(this); 6479 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) }; 6480 i::Handle<i::Object> result; 6481 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(), 6482 self, arraysize(argv), argv) 6483 .ToHandle(&result); 6484 RETURN_ON_FAILED_EXECUTION(Promise); 6485 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result))); 6486 } 6487 6488 6489 Local<Promise> Promise::Then(Local<Function> handler) { 6490 auto context = ContextFromHeapObject(Utils::OpenHandle(this)); 6491 RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise); 6492 } 6493 6494 6495 bool Promise::HasHandler() { 6496 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this); 6497 i::Isolate* isolate = promise->GetIsolate(); 6498 LOG_API(isolate, "Promise::HasRejectHandler"); 6499 ENTER_V8(isolate); 6500 i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol(); 6501 return i::JSReceiver::GetDataProperty(promise, key)->IsTrue(); 6502 } 6503 6504 6505 Local<Object> Proxy::GetTarget() { 6506 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 6507 i::Handle<i::JSReceiver> target(self->target()); 6508 return Utils::ToLocal(target); 6509 } 6510 6511 6512 Local<Value> Proxy::GetHandler() { 6513 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 6514 i::Handle<i::Object> handler(self->handler(), self->GetIsolate()); 6515 return Utils::ToLocal(handler); 6516 } 6517 6518 6519 bool Proxy::IsRevoked() { 6520 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 6521 return self->IsRevoked(); 6522 } 6523 6524 6525 void Proxy::Revoke() { 6526 i::Handle<i::JSProxy> self = Utils::OpenHandle(this); 6527 i::JSProxy::Revoke(self); 6528 } 6529 6530 6531 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target, 6532 Local<Object> local_handler) { 6533 PREPARE_FOR_EXECUTION(context, "Proxy::New", Proxy); 6534 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target); 6535 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler); 6536 Local<Proxy> result; 6537 has_pending_exception = 6538 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result); 6539 RETURN_ON_FAILED_EXECUTION(Proxy); 6540 RETURN_ESCAPED(result); 6541 } 6542 6543 bool v8::ArrayBuffer::IsExternal() const { 6544 return Utils::OpenHandle(this)->is_external(); 6545 } 6546 6547 6548 bool v8::ArrayBuffer::IsNeuterable() const { 6549 return Utils::OpenHandle(this)->is_neuterable(); 6550 } 6551 6552 6553 v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() { 6554 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); 6555 i::Isolate* isolate = self->GetIsolate(); 6556 Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize", 6557 "ArrayBuffer already externalized"); 6558 self->set_is_external(true); 6559 isolate->heap()->UnregisterArrayBuffer(*self); 6560 6561 return GetContents(); 6562 } 6563 6564 6565 v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() { 6566 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); 6567 size_t byte_length = static_cast<size_t>(self->byte_length()->Number()); 6568 Contents contents; 6569 contents.data_ = self->backing_store(); 6570 contents.byte_length_ = byte_length; 6571 return contents; 6572 } 6573 6574 6575 void v8::ArrayBuffer::Neuter() { 6576 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 6577 i::Isolate* isolate = obj->GetIsolate(); 6578 Utils::ApiCheck(obj->is_external(), 6579 "v8::ArrayBuffer::Neuter", 6580 "Only externalized ArrayBuffers can be neutered"); 6581 Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter", 6582 "Only neuterable ArrayBuffers can be neutered"); 6583 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()"); 6584 ENTER_V8(isolate); 6585 obj->Neuter(); 6586 } 6587 6588 6589 size_t v8::ArrayBuffer::ByteLength() const { 6590 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 6591 return static_cast<size_t>(obj->byte_length()->Number()); 6592 } 6593 6594 6595 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { 6596 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6597 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)"); 6598 ENTER_V8(i_isolate); 6599 i::Handle<i::JSArrayBuffer> obj = 6600 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); 6601 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length); 6602 return Utils::ToLocal(obj); 6603 } 6604 6605 6606 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data, 6607 size_t byte_length, 6608 ArrayBufferCreationMode mode) { 6609 // Embedders must guarantee that the external backing store is valid. 6610 CHECK(byte_length == 0 || data != NULL); 6611 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6612 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)"); 6613 ENTER_V8(i_isolate); 6614 i::Handle<i::JSArrayBuffer> obj = 6615 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); 6616 i::JSArrayBuffer::Setup(obj, i_isolate, 6617 mode == ArrayBufferCreationMode::kExternalized, data, 6618 byte_length); 6619 return Utils::ToLocal(obj); 6620 } 6621 6622 6623 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() { 6624 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 6625 i::Handle<i::JSArrayBuffer> buffer; 6626 if (obj->IsJSDataView()) { 6627 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj)); 6628 DCHECK(data_view->buffer()->IsJSArrayBuffer()); 6629 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer())); 6630 } else { 6631 DCHECK(obj->IsJSTypedArray()); 6632 buffer = i::JSTypedArray::cast(*obj)->GetBuffer(); 6633 } 6634 return Utils::ToLocal(buffer); 6635 } 6636 6637 6638 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { 6639 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this); 6640 i::Isolate* isolate = self->GetIsolate(); 6641 size_t byte_offset = i::NumberToSize(isolate, self->byte_offset()); 6642 size_t bytes_to_copy = 6643 i::Min(byte_length, i::NumberToSize(isolate, self->byte_length())); 6644 if (bytes_to_copy) { 6645 i::DisallowHeapAllocation no_gc; 6646 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer())); 6647 const char* source = reinterpret_cast<char*>(buffer->backing_store()); 6648 if (source == nullptr) { 6649 DCHECK(self->IsJSTypedArray()); 6650 i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self)); 6651 i::Handle<i::FixedTypedArrayBase> fixed_array( 6652 i::FixedTypedArrayBase::cast(typed_array->elements())); 6653 source = reinterpret_cast<char*>(fixed_array->DataPtr()); 6654 } 6655 memcpy(dest, source + byte_offset, bytes_to_copy); 6656 } 6657 return bytes_to_copy; 6658 } 6659 6660 6661 bool v8::ArrayBufferView::HasBuffer() const { 6662 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this); 6663 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer())); 6664 return buffer->backing_store() != nullptr; 6665 } 6666 6667 6668 size_t v8::ArrayBufferView::ByteOffset() { 6669 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 6670 return static_cast<size_t>(obj->byte_offset()->Number()); 6671 } 6672 6673 6674 size_t v8::ArrayBufferView::ByteLength() { 6675 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); 6676 return static_cast<size_t>(obj->byte_length()->Number()); 6677 } 6678 6679 6680 size_t v8::TypedArray::Length() { 6681 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this); 6682 return static_cast<size_t>(obj->length_value()); 6683 } 6684 6685 6686 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \ 6687 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \ 6688 size_t byte_offset, size_t length) { \ 6689 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ 6690 LOG_API(isolate, \ 6691 "v8::" #Type "Array::New(Local<ArrayBuffer>, size_t, size_t)"); \ 6692 ENTER_V8(isolate); \ 6693 if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \ 6694 "v8::" #Type \ 6695 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \ 6696 "length exceeds max allowed value")) { \ 6697 return Local<Type##Array>(); \ 6698 } \ 6699 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \ 6700 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \ 6701 i::kExternal##Type##Array, buffer, byte_offset, length); \ 6702 return Utils::ToLocal##Type##Array(obj); \ 6703 } \ 6704 Local<Type##Array> Type##Array::New( \ 6705 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \ 6706 size_t length) { \ 6707 CHECK(i::FLAG_harmony_sharedarraybuffer); \ 6708 i::Isolate* isolate = \ 6709 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \ 6710 LOG_API(isolate, "v8::" #Type \ 6711 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)"); \ 6712 ENTER_V8(isolate); \ 6713 if (!Utils::ApiCheck( \ 6714 length <= static_cast<size_t>(i::Smi::kMaxValue), \ 6715 "v8::" #Type \ 6716 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \ 6717 "length exceeds max allowed value")) { \ 6718 return Local<Type##Array>(); \ 6719 } \ 6720 i::Handle<i::JSArrayBuffer> buffer = \ 6721 Utils::OpenHandle(*shared_array_buffer); \ 6722 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \ 6723 i::kExternal##Type##Array, buffer, byte_offset, length); \ 6724 return Utils::ToLocal##Type##Array(obj); \ 6725 } 6726 6727 6728 TYPED_ARRAYS(TYPED_ARRAY_NEW) 6729 #undef TYPED_ARRAY_NEW 6730 6731 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer, 6732 size_t byte_offset, size_t byte_length) { 6733 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); 6734 i::Isolate* isolate = buffer->GetIsolate(); 6735 LOG_API(isolate, "v8::DataView::New(Local<ArrayBuffer>, size_t, size_t)"); 6736 ENTER_V8(isolate); 6737 i::Handle<i::JSDataView> obj = 6738 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length); 6739 return Utils::ToLocal(obj); 6740 } 6741 6742 6743 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer, 6744 size_t byte_offset, size_t byte_length) { 6745 CHECK(i::FLAG_harmony_sharedarraybuffer); 6746 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer); 6747 i::Isolate* isolate = buffer->GetIsolate(); 6748 LOG_API(isolate, 6749 "v8::DataView::New(Local<SharedArrayBuffer>, size_t, size_t)"); 6750 ENTER_V8(isolate); 6751 i::Handle<i::JSDataView> obj = 6752 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length); 6753 return Utils::ToLocal(obj); 6754 } 6755 6756 6757 bool v8::SharedArrayBuffer::IsExternal() const { 6758 return Utils::OpenHandle(this)->is_external(); 6759 } 6760 6761 6762 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { 6763 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); 6764 i::Isolate* isolate = self->GetIsolate(); 6765 Utils::ApiCheck(!self->is_external(), "v8::SharedArrayBuffer::Externalize", 6766 "SharedArrayBuffer already externalized"); 6767 self->set_is_external(true); 6768 isolate->heap()->UnregisterArrayBuffer(*self); 6769 return GetContents(); 6770 } 6771 6772 6773 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() { 6774 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); 6775 size_t byte_length = static_cast<size_t>(self->byte_length()->Number()); 6776 Contents contents; 6777 contents.data_ = self->backing_store(); 6778 contents.byte_length_ = byte_length; 6779 return contents; 6780 } 6781 6782 6783 size_t v8::SharedArrayBuffer::ByteLength() const { 6784 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this); 6785 return static_cast<size_t>(obj->byte_length()->Number()); 6786 } 6787 6788 6789 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate, 6790 size_t byte_length) { 6791 CHECK(i::FLAG_harmony_sharedarraybuffer); 6792 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6793 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(size_t)"); 6794 ENTER_V8(i_isolate); 6795 i::Handle<i::JSArrayBuffer> obj = 6796 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); 6797 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true, 6798 i::SharedFlag::kShared); 6799 return Utils::ToLocalShared(obj); 6800 } 6801 6802 6803 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( 6804 Isolate* isolate, void* data, size_t byte_length, 6805 ArrayBufferCreationMode mode) { 6806 CHECK(i::FLAG_harmony_sharedarraybuffer); 6807 // Embedders must guarantee that the external backing store is valid. 6808 CHECK(byte_length == 0 || data != NULL); 6809 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6810 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(void*, size_t)"); 6811 ENTER_V8(i_isolate); 6812 i::Handle<i::JSArrayBuffer> obj = 6813 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); 6814 i::JSArrayBuffer::Setup(obj, i_isolate, 6815 mode == ArrayBufferCreationMode::kExternalized, data, 6816 byte_length, i::SharedFlag::kShared); 6817 return Utils::ToLocalShared(obj); 6818 } 6819 6820 6821 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) { 6822 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6823 LOG_API(i_isolate, "Symbol::New()"); 6824 ENTER_V8(i_isolate); 6825 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol(); 6826 if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name)); 6827 return Utils::ToLocal(result); 6828 } 6829 6830 6831 static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate, 6832 i::Handle<i::String> name, 6833 i::Handle<i::String> part, 6834 bool private_symbol) { 6835 i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry(); 6836 i::Handle<i::JSObject> symbols = 6837 i::Handle<i::JSObject>::cast( 6838 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked()); 6839 i::Handle<i::Object> symbol = 6840 i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked(); 6841 if (!symbol->IsSymbol()) { 6842 DCHECK(symbol->IsUndefined()); 6843 if (private_symbol) 6844 symbol = isolate->factory()->NewPrivateSymbol(); 6845 else 6846 symbol = isolate->factory()->NewSymbol(); 6847 i::Handle<i::Symbol>::cast(symbol)->set_name(*name); 6848 i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert(); 6849 } 6850 return i::Handle<i::Symbol>::cast(symbol); 6851 } 6852 6853 6854 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) { 6855 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6856 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 6857 i::Handle<i::String> part = i_isolate->factory()->for_string(); 6858 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false)); 6859 } 6860 6861 6862 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) { 6863 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6864 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 6865 i::Handle<i::String> part = i_isolate->factory()->for_api_string(); 6866 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false)); 6867 } 6868 6869 6870 Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) { 6871 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6872 return Utils::ToLocal(i_isolate->factory()->iterator_symbol()); 6873 } 6874 6875 6876 Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) { 6877 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6878 return Utils::ToLocal(i_isolate->factory()->unscopables_symbol()); 6879 } 6880 6881 6882 Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) { 6883 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6884 return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol()); 6885 } 6886 6887 6888 Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) { 6889 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6890 return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol()); 6891 } 6892 6893 6894 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) { 6895 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6896 LOG_API(i_isolate, "Private::New()"); 6897 ENTER_V8(i_isolate); 6898 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol(); 6899 if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name)); 6900 Local<Symbol> result = Utils::ToLocal(symbol); 6901 return v8::Local<Private>(reinterpret_cast<Private*>(*result)); 6902 } 6903 6904 6905 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) { 6906 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 6907 i::Handle<i::String> i_name = Utils::OpenHandle(*name); 6908 i::Handle<i::String> part = i_isolate->factory()->private_api_string(); 6909 Local<Symbol> result = 6910 Utils::ToLocal(SymbolFor(i_isolate, i_name, part, true)); 6911 return v8::Local<Private>(reinterpret_cast<Private*>(*result)); 6912 } 6913 6914 6915 Local<Number> v8::Number::New(Isolate* isolate, double value) { 6916 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 6917 if (std::isnan(value)) { 6918 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs. 6919 value = std::numeric_limits<double>::quiet_NaN(); 6920 } 6921 ENTER_V8(internal_isolate); 6922 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 6923 return Utils::NumberToLocal(result); 6924 } 6925 6926 6927 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) { 6928 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 6929 if (i::Smi::IsValid(value)) { 6930 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value), 6931 internal_isolate)); 6932 } 6933 ENTER_V8(internal_isolate); 6934 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 6935 return Utils::IntegerToLocal(result); 6936 } 6937 6938 6939 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) { 6940 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 6941 bool fits_into_int32_t = (value & (1 << 31)) == 0; 6942 if (fits_into_int32_t) { 6943 return Integer::New(isolate, static_cast<int32_t>(value)); 6944 } 6945 ENTER_V8(internal_isolate); 6946 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value); 6947 return Utils::IntegerToLocal(result); 6948 } 6949 6950 6951 void Isolate::ReportExternalAllocationLimitReached() { 6952 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap(); 6953 if (heap->gc_state() != i::Heap::NOT_IN_GC) return; 6954 heap->ReportExternalMemoryPressure( 6955 "external memory allocation limit reached."); 6956 } 6957 6958 6959 HeapProfiler* Isolate::GetHeapProfiler() { 6960 i::HeapProfiler* heap_profiler = 6961 reinterpret_cast<i::Isolate*>(this)->heap_profiler(); 6962 return reinterpret_cast<HeapProfiler*>(heap_profiler); 6963 } 6964 6965 6966 CpuProfiler* Isolate::GetCpuProfiler() { 6967 i::CpuProfiler* cpu_profiler = 6968 reinterpret_cast<i::Isolate*>(this)->cpu_profiler(); 6969 return reinterpret_cast<CpuProfiler*>(cpu_profiler); 6970 } 6971 6972 6973 bool Isolate::InContext() { 6974 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 6975 return isolate->context() != NULL; 6976 } 6977 6978 6979 v8::Local<v8::Context> Isolate::GetCurrentContext() { 6980 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 6981 i::Context* context = isolate->context(); 6982 if (context == NULL) return Local<Context>(); 6983 i::Context* native_context = context->native_context(); 6984 if (native_context == NULL) return Local<Context>(); 6985 return Utils::ToLocal(i::Handle<i::Context>(native_context)); 6986 } 6987 6988 6989 v8::Local<v8::Context> Isolate::GetCallingContext() { 6990 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 6991 i::Handle<i::Object> calling = isolate->GetCallingNativeContext(); 6992 if (calling.is_null()) return Local<Context>(); 6993 return Utils::ToLocal(i::Handle<i::Context>::cast(calling)); 6994 } 6995 6996 6997 v8::Local<v8::Context> Isolate::GetEnteredContext() { 6998 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 6999 i::Handle<i::Object> last = 7000 isolate->handle_scope_implementer()->LastEnteredContext(); 7001 if (last.is_null()) return Local<Context>(); 7002 return Utils::ToLocal(i::Handle<i::Context>::cast(last)); 7003 } 7004 7005 7006 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) { 7007 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7008 ENTER_V8(isolate); 7009 // If we're passed an empty handle, we throw an undefined exception 7010 // to deal more gracefully with out of memory situations. 7011 if (value.IsEmpty()) { 7012 isolate->ScheduleThrow(isolate->heap()->undefined_value()); 7013 } else { 7014 isolate->ScheduleThrow(*Utils::OpenHandle(*value)); 7015 } 7016 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 7017 } 7018 7019 7020 void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) { 7021 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this); 7022 internal_isolate->global_handles()->SetObjectGroupId( 7023 v8::internal::Handle<v8::internal::Object>(object).location(), 7024 id); 7025 } 7026 7027 7028 void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) { 7029 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this); 7030 internal_isolate->global_handles()->SetReferenceFromGroup( 7031 id, 7032 v8::internal::Handle<v8::internal::Object>(object).location()); 7033 } 7034 7035 7036 void Isolate::SetReference(internal::Object** parent, 7037 internal::Object** child) { 7038 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this); 7039 i::Object** parent_location = 7040 v8::internal::Handle<v8::internal::Object>(parent).location(); 7041 internal_isolate->global_handles()->SetReference( 7042 reinterpret_cast<i::HeapObject**>(parent_location), 7043 v8::internal::Handle<v8::internal::Object>(child).location()); 7044 } 7045 7046 7047 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) { 7048 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7049 isolate->heap()->AddGCPrologueCallback(callback, gc_type); 7050 } 7051 7052 7053 void Isolate::RemoveGCPrologueCallback(GCCallback callback) { 7054 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7055 isolate->heap()->RemoveGCPrologueCallback(callback); 7056 } 7057 7058 7059 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) { 7060 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7061 isolate->heap()->AddGCEpilogueCallback(callback, gc_type); 7062 } 7063 7064 7065 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) { 7066 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7067 isolate->heap()->RemoveGCEpilogueCallback(callback); 7068 } 7069 7070 7071 void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) { 7072 i::Isolate* isolate = i::Isolate::Current(); 7073 isolate->heap()->AddGCPrologueCallback( 7074 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false); 7075 } 7076 7077 7078 void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) { 7079 i::Isolate* isolate = i::Isolate::Current(); 7080 isolate->heap()->AddGCEpilogueCallback( 7081 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false); 7082 } 7083 7084 7085 void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback, 7086 ObjectSpace space, 7087 AllocationAction action) { 7088 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7089 isolate->memory_allocator()->AddMemoryAllocationCallback( 7090 callback, space, action); 7091 } 7092 7093 7094 void Isolate::RemoveMemoryAllocationCallback( 7095 MemoryAllocationCallback callback) { 7096 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7097 isolate->memory_allocator()->RemoveMemoryAllocationCallback( 7098 callback); 7099 } 7100 7101 7102 void Isolate::TerminateExecution() { 7103 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7104 isolate->stack_guard()->RequestTerminateExecution(); 7105 } 7106 7107 7108 bool Isolate::IsExecutionTerminating() { 7109 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7110 return IsExecutionTerminatingCheck(isolate); 7111 } 7112 7113 7114 void Isolate::CancelTerminateExecution() { 7115 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7116 isolate->stack_guard()->ClearTerminateExecution(); 7117 isolate->CancelTerminateExecution(); 7118 } 7119 7120 7121 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) { 7122 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7123 isolate->RequestInterrupt(callback, data); 7124 } 7125 7126 7127 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) { 7128 CHECK(i::FLAG_expose_gc); 7129 if (type == kMinorGarbageCollection) { 7130 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage( 7131 i::NEW_SPACE, "Isolate::RequestGarbageCollection", 7132 kGCCallbackFlagForced); 7133 } else { 7134 DCHECK_EQ(kFullGarbageCollection, type); 7135 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage( 7136 i::Heap::kAbortIncrementalMarkingMask, 7137 "Isolate::RequestGarbageCollection", kGCCallbackFlagForced); 7138 } 7139 } 7140 7141 7142 Isolate* Isolate::GetCurrent() { 7143 i::Isolate* isolate = i::Isolate::Current(); 7144 return reinterpret_cast<Isolate*>(isolate); 7145 } 7146 7147 7148 Isolate* Isolate::New(const Isolate::CreateParams& params) { 7149 i::Isolate* isolate = new i::Isolate(false); 7150 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate); 7151 CHECK(params.array_buffer_allocator != NULL); 7152 isolate->set_array_buffer_allocator(params.array_buffer_allocator); 7153 if (params.snapshot_blob != NULL) { 7154 isolate->set_snapshot_blob(params.snapshot_blob); 7155 } else { 7156 isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob()); 7157 } 7158 if (params.entry_hook) { 7159 isolate->set_function_entry_hook(params.entry_hook); 7160 } 7161 if (params.code_event_handler) { 7162 isolate->InitializeLoggingAndCounters(); 7163 isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault, 7164 params.code_event_handler); 7165 } 7166 if (params.counter_lookup_callback) { 7167 v8_isolate->SetCounterFunction(params.counter_lookup_callback); 7168 } 7169 7170 if (params.create_histogram_callback) { 7171 v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback); 7172 } 7173 7174 if (params.add_histogram_sample_callback) { 7175 v8_isolate->SetAddHistogramSampleFunction( 7176 params.add_histogram_sample_callback); 7177 } 7178 SetResourceConstraints(isolate, params.constraints); 7179 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this. 7180 Isolate::Scope isolate_scope(v8_isolate); 7181 if (params.entry_hook || !i::Snapshot::Initialize(isolate)) { 7182 // If the isolate has a function entry hook, it needs to re-build all its 7183 // code stubs with entry hooks embedded, so don't deserialize a snapshot. 7184 if (i::Snapshot::EmbedsScript(isolate)) { 7185 // If the snapshot embeds a script, we cannot initialize the isolate 7186 // without the snapshot as a fallback. This is unlikely to happen though. 7187 V8_Fatal(__FILE__, __LINE__, 7188 "Initializing isolate from custom startup snapshot failed"); 7189 } 7190 isolate->Init(NULL); 7191 } 7192 return v8_isolate; 7193 } 7194 7195 7196 void Isolate::Dispose() { 7197 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7198 if (!Utils::ApiCheck(!isolate->IsInUse(), 7199 "v8::Isolate::Dispose()", 7200 "Disposing the isolate that is entered by a thread.")) { 7201 return; 7202 } 7203 isolate->TearDown(); 7204 } 7205 7206 7207 void Isolate::DiscardThreadSpecificMetadata() { 7208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7209 isolate->DiscardPerThreadDataForThisThread(); 7210 } 7211 7212 7213 void Isolate::Enter() { 7214 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7215 isolate->Enter(); 7216 } 7217 7218 7219 void Isolate::Exit() { 7220 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7221 isolate->Exit(); 7222 } 7223 7224 7225 void Isolate::SetAbortOnUncaughtExceptionCallback( 7226 AbortOnUncaughtExceptionCallback callback) { 7227 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7228 isolate->SetAbortOnUncaughtExceptionCallback(callback); 7229 } 7230 7231 7232 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope( 7233 Isolate* isolate, 7234 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) 7235 : on_failure_(on_failure) { 7236 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7237 if (on_failure_ == CRASH_ON_FAILURE) { 7238 internal_ = reinterpret_cast<void*>( 7239 new i::DisallowJavascriptExecution(i_isolate)); 7240 } else { 7241 DCHECK_EQ(THROW_ON_FAILURE, on_failure); 7242 internal_ = reinterpret_cast<void*>( 7243 new i::ThrowOnJavascriptExecution(i_isolate)); 7244 } 7245 } 7246 7247 7248 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() { 7249 if (on_failure_ == CRASH_ON_FAILURE) { 7250 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_); 7251 } else { 7252 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_); 7253 } 7254 } 7255 7256 7257 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope( 7258 Isolate* isolate) { 7259 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7260 internal_assert_ = reinterpret_cast<void*>( 7261 new i::AllowJavascriptExecution(i_isolate)); 7262 internal_throws_ = reinterpret_cast<void*>( 7263 new i::NoThrowOnJavascriptExecution(i_isolate)); 7264 } 7265 7266 7267 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() { 7268 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_); 7269 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_); 7270 } 7271 7272 7273 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope( 7274 Isolate* isolate) 7275 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) { 7276 isolate_->handle_scope_implementer()->IncrementCallDepth(); 7277 } 7278 7279 7280 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() { 7281 isolate_->handle_scope_implementer()->DecrementCallDepth(); 7282 } 7283 7284 7285 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) { 7286 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7287 i::Heap* heap = isolate->heap(); 7288 heap_statistics->total_heap_size_ = heap->CommittedMemory(); 7289 heap_statistics->total_heap_size_executable_ = 7290 heap->CommittedMemoryExecutable(); 7291 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory(); 7292 heap_statistics->total_available_size_ = heap->Available(); 7293 heap_statistics->used_heap_size_ = heap->SizeOfObjects(); 7294 heap_statistics->heap_size_limit_ = heap->MaxReserved(); 7295 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage(); 7296 } 7297 7298 7299 size_t Isolate::NumberOfHeapSpaces() { 7300 return i::LAST_SPACE - i::FIRST_SPACE + 1; 7301 } 7302 7303 7304 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics, 7305 size_t index) { 7306 if (!space_statistics) return false; 7307 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index))) 7308 return false; 7309 7310 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7311 i::Heap* heap = isolate->heap(); 7312 i::Space* space = heap->space(static_cast<int>(index)); 7313 7314 space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index)); 7315 space_statistics->space_size_ = space->CommittedMemory(); 7316 space_statistics->space_used_size_ = space->SizeOfObjects(); 7317 space_statistics->space_available_size_ = space->Available(); 7318 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory(); 7319 return true; 7320 } 7321 7322 7323 size_t Isolate::NumberOfTrackedHeapObjectTypes() { 7324 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7325 i::Heap* heap = isolate->heap(); 7326 return heap->NumberOfTrackedHeapObjectTypes(); 7327 } 7328 7329 7330 bool Isolate::GetHeapObjectStatisticsAtLastGC( 7331 HeapObjectStatistics* object_statistics, size_t type_index) { 7332 if (!object_statistics) return false; 7333 if (!i::FLAG_track_gc_object_stats) return false; 7334 7335 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7336 i::Heap* heap = isolate->heap(); 7337 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false; 7338 7339 const char* object_type; 7340 const char* object_sub_type; 7341 size_t object_count = heap->ObjectCountAtLastGC(type_index); 7342 size_t object_size = heap->ObjectSizeAtLastGC(type_index); 7343 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) { 7344 // There should be no objects counted when the type is unknown. 7345 DCHECK_EQ(object_count, 0U); 7346 DCHECK_EQ(object_size, 0U); 7347 return false; 7348 } 7349 7350 object_statistics->object_type_ = object_type; 7351 object_statistics->object_sub_type_ = object_sub_type; 7352 object_statistics->object_count_ = object_count; 7353 object_statistics->object_size_ = object_size; 7354 return true; 7355 } 7356 7357 7358 void Isolate::GetStackSample(const RegisterState& state, void** frames, 7359 size_t frames_limit, SampleInfo* sample_info) { 7360 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7361 i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame, 7362 frames, frames_limit, sample_info); 7363 } 7364 7365 7366 void Isolate::SetEventLogger(LogEventCallback that) { 7367 // Do not overwrite the event logger if we want to log explicitly. 7368 if (i::FLAG_log_internal_timer_events) return; 7369 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7370 isolate->set_event_logger(that); 7371 } 7372 7373 7374 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) { 7375 if (callback == NULL) return; 7376 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7377 isolate->AddCallCompletedCallback(callback); 7378 } 7379 7380 7381 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) { 7382 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7383 isolate->RemoveCallCompletedCallback(callback); 7384 } 7385 7386 7387 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { 7388 if (callback == NULL) return; 7389 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7390 isolate->SetPromiseRejectCallback(callback); 7391 } 7392 7393 7394 void Isolate::RunMicrotasks() { 7395 reinterpret_cast<i::Isolate*>(this)->RunMicrotasks(); 7396 } 7397 7398 7399 void Isolate::EnqueueMicrotask(Local<Function> microtask) { 7400 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7401 isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask)); 7402 } 7403 7404 7405 void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) { 7406 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7407 i::HandleScope scope(isolate); 7408 i::Handle<i::CallHandlerInfo> callback_info = 7409 i::Handle<i::CallHandlerInfo>::cast( 7410 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE)); 7411 SET_FIELD_WRAPPED(callback_info, set_callback, microtask); 7412 SET_FIELD_WRAPPED(callback_info, set_data, data); 7413 isolate->EnqueueMicrotask(callback_info); 7414 } 7415 7416 7417 void Isolate::SetAutorunMicrotasks(bool autorun) { 7418 reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun); 7419 } 7420 7421 7422 bool Isolate::WillAutorunMicrotasks() const { 7423 return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks(); 7424 } 7425 7426 7427 void Isolate::SetUseCounterCallback(UseCounterCallback callback) { 7428 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback); 7429 } 7430 7431 7432 void Isolate::SetCounterFunction(CounterLookupCallback callback) { 7433 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7434 isolate->stats_table()->SetCounterFunction(callback); 7435 isolate->InitializeLoggingAndCounters(); 7436 isolate->counters()->ResetCounters(); 7437 } 7438 7439 7440 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) { 7441 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7442 isolate->stats_table()->SetCreateHistogramFunction(callback); 7443 isolate->InitializeLoggingAndCounters(); 7444 isolate->counters()->ResetHistograms(); 7445 } 7446 7447 7448 void Isolate::SetAddHistogramSampleFunction( 7449 AddHistogramSampleCallback callback) { 7450 reinterpret_cast<i::Isolate*>(this) 7451 ->stats_table() 7452 ->SetAddHistogramSampleFunction(callback); 7453 } 7454 7455 7456 bool Isolate::IdleNotification(int idle_time_in_ms) { 7457 // Returning true tells the caller that it need not 7458 // continue to call IdleNotification. 7459 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7460 if (!i::FLAG_use_idle_notification) return true; 7461 return isolate->heap()->IdleNotification(idle_time_in_ms); 7462 } 7463 7464 7465 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) { 7466 // Returning true tells the caller that it need not 7467 // continue to call IdleNotification. 7468 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7469 if (!i::FLAG_use_idle_notification) return true; 7470 return isolate->heap()->IdleNotification(deadline_in_seconds); 7471 } 7472 7473 7474 void Isolate::LowMemoryNotification() { 7475 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7476 { 7477 i::HistogramTimerScope idle_notification_scope( 7478 isolate->counters()->gc_low_memory_notification()); 7479 isolate->heap()->CollectAllAvailableGarbage("low memory notification"); 7480 } 7481 } 7482 7483 7484 int Isolate::ContextDisposedNotification(bool dependant_context) { 7485 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7486 return isolate->heap()->NotifyContextDisposed(dependant_context); 7487 } 7488 7489 7490 void Isolate::IsolateInForegroundNotification() { 7491 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7492 return isolate->heap()->SetOptimizeForLatency(); 7493 } 7494 7495 7496 void Isolate::IsolateInBackgroundNotification() { 7497 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7498 return isolate->heap()->SetOptimizeForMemoryUsage(); 7499 } 7500 7501 7502 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options, 7503 JitCodeEventHandler event_handler) { 7504 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7505 // Ensure that logging is initialized for our isolate. 7506 isolate->InitializeLoggingAndCounters(); 7507 isolate->logger()->SetCodeEventHandler(options, event_handler); 7508 } 7509 7510 7511 void Isolate::SetStackLimit(uintptr_t stack_limit) { 7512 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7513 CHECK(stack_limit); 7514 isolate->stack_guard()->SetStackLimit(stack_limit); 7515 } 7516 7517 7518 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) { 7519 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7520 if (isolate->code_range()->valid()) { 7521 *start = isolate->code_range()->start(); 7522 *length_in_bytes = isolate->code_range()->size(); 7523 } else { 7524 *start = NULL; 7525 *length_in_bytes = 0; 7526 } 7527 } 7528 7529 7530 void Isolate::SetFatalErrorHandler(FatalErrorCallback that) { 7531 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7532 isolate->set_exception_behavior(that); 7533 } 7534 7535 7536 void Isolate::SetAllowCodeGenerationFromStringsCallback( 7537 AllowCodeGenerationFromStringsCallback callback) { 7538 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7539 isolate->set_allow_code_gen_callback(callback); 7540 } 7541 7542 7543 bool Isolate::IsDead() { 7544 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7545 return isolate->IsDead(); 7546 } 7547 7548 7549 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) { 7550 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7551 ENTER_V8(isolate); 7552 i::HandleScope scope(isolate); 7553 NeanderArray listeners(isolate->factory()->message_listeners()); 7554 NeanderObject obj(isolate, 2); 7555 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that))); 7556 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value() 7557 : *Utils::OpenHandle(*data)); 7558 listeners.add(isolate, obj.value()); 7559 return true; 7560 } 7561 7562 7563 void Isolate::RemoveMessageListeners(MessageCallback that) { 7564 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7565 ENTER_V8(isolate); 7566 i::HandleScope scope(isolate); 7567 NeanderArray listeners(isolate->factory()->message_listeners()); 7568 for (int i = 0; i < listeners.length(); i++) { 7569 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones 7570 7571 NeanderObject listener(i::JSObject::cast(listeners.get(i))); 7572 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0))); 7573 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) { 7574 listeners.set(i, isolate->heap()->undefined_value()); 7575 } 7576 } 7577 } 7578 7579 7580 void Isolate::SetFailedAccessCheckCallbackFunction( 7581 FailedAccessCheckCallback callback) { 7582 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7583 isolate->SetFailedAccessCheckCallback(callback); 7584 } 7585 7586 7587 void Isolate::SetCaptureStackTraceForUncaughtExceptions( 7588 bool capture, int frame_limit, StackTrace::StackTraceOptions options) { 7589 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7590 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit, 7591 options); 7592 } 7593 7594 7595 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) { 7596 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7597 isolate->heap()->VisitExternalResources(visitor); 7598 } 7599 7600 7601 class VisitorAdapter : public i::ObjectVisitor { 7602 public: 7603 explicit VisitorAdapter(PersistentHandleVisitor* visitor) 7604 : visitor_(visitor) {} 7605 void VisitPointers(i::Object** start, i::Object** end) override { 7606 UNREACHABLE(); 7607 } 7608 void VisitEmbedderReference(i::Object** p, uint16_t class_id) override { 7609 Value* value = ToApi<Value>(i::Handle<i::Object>(p)); 7610 visitor_->VisitPersistentHandle( 7611 reinterpret_cast<Persistent<Value>*>(&value), class_id); 7612 } 7613 7614 private: 7615 PersistentHandleVisitor* visitor_; 7616 }; 7617 7618 7619 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) { 7620 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7621 i::DisallowHeapAllocation no_allocation; 7622 VisitorAdapter visitor_adapter(visitor); 7623 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter); 7624 } 7625 7626 7627 void Isolate::VisitHandlesForPartialDependence( 7628 PersistentHandleVisitor* visitor) { 7629 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7630 i::DisallowHeapAllocation no_allocation; 7631 VisitorAdapter visitor_adapter(visitor); 7632 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds( 7633 &visitor_adapter); 7634 } 7635 7636 7637 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { 7638 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); 7639 i::DisallowHeapAllocation no_allocation; 7640 VisitorAdapter visitor_adapter(visitor); 7641 isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds( 7642 &visitor_adapter); 7643 } 7644 7645 7646 String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj) 7647 : str_(NULL), length_(0) { 7648 if (obj.IsEmpty()) return; 7649 i::Isolate* isolate = i::Isolate::Current(); 7650 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate); 7651 ENTER_V8(isolate); 7652 i::HandleScope scope(isolate); 7653 Local<Context> context = v8_isolate->GetCurrentContext(); 7654 TryCatch try_catch(v8_isolate); 7655 Local<String> str; 7656 if (!obj->ToString(context).ToLocal(&str)) return; 7657 i::Handle<i::String> i_str = Utils::OpenHandle(*str); 7658 length_ = v8::Utf8Length(*i_str, isolate); 7659 str_ = i::NewArray<char>(length_ + 1); 7660 str->WriteUtf8(str_); 7661 } 7662 7663 7664 String::Utf8Value::~Utf8Value() { 7665 i::DeleteArray(str_); 7666 } 7667 7668 7669 String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) { 7670 if (obj.IsEmpty()) return; 7671 i::Isolate* isolate = i::Isolate::Current(); 7672 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate); 7673 ENTER_V8(isolate); 7674 i::HandleScope scope(isolate); 7675 Local<Context> context = v8_isolate->GetCurrentContext(); 7676 TryCatch try_catch(v8_isolate); 7677 Local<String> str; 7678 if (!obj->ToString(context).ToLocal(&str)) return; 7679 length_ = str->Length(); 7680 str_ = i::NewArray<uint16_t>(length_ + 1); 7681 str->Write(str_); 7682 } 7683 7684 7685 String::Value::~Value() { 7686 i::DeleteArray(str_); 7687 } 7688 7689 7690 #define DEFINE_ERROR(NAME, name) \ 7691 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \ 7692 i::Isolate* isolate = i::Isolate::Current(); \ 7693 LOG_API(isolate, #NAME); \ 7694 ENTER_V8(isolate); \ 7695 i::Object* error; \ 7696 { \ 7697 i::HandleScope scope(isolate); \ 7698 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \ 7699 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \ 7700 error = *isolate->factory()->NewError(constructor, message); \ 7701 } \ 7702 i::Handle<i::Object> result(error, isolate); \ 7703 return Utils::ToLocal(result); \ 7704 } 7705 7706 DEFINE_ERROR(RangeError, range_error) 7707 DEFINE_ERROR(ReferenceError, reference_error) 7708 DEFINE_ERROR(SyntaxError, syntax_error) 7709 DEFINE_ERROR(TypeError, type_error) 7710 DEFINE_ERROR(Error, error) 7711 7712 #undef DEFINE_ERROR 7713 7714 7715 Local<Message> Exception::CreateMessage(Isolate* isolate, 7716 Local<Value> exception) { 7717 i::Handle<i::Object> obj = Utils::OpenHandle(*exception); 7718 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7719 ENTER_V8(i_isolate); 7720 i::HandleScope scope(i_isolate); 7721 return Utils::MessageToLocal( 7722 scope.CloseAndEscape(i_isolate->CreateMessage(obj, NULL))); 7723 } 7724 7725 7726 Local<Message> Exception::CreateMessage(Local<Value> exception) { 7727 i::Handle<i::Object> obj = Utils::OpenHandle(*exception); 7728 if (!obj->IsHeapObject()) return Local<Message>(); 7729 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); 7730 return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception); 7731 } 7732 7733 7734 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) { 7735 i::Handle<i::Object> obj = Utils::OpenHandle(*exception); 7736 if (!obj->IsJSObject()) return Local<StackTrace>(); 7737 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj); 7738 i::Isolate* isolate = js_obj->GetIsolate(); 7739 ENTER_V8(isolate); 7740 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj)); 7741 } 7742 7743 7744 // --- D e b u g S u p p o r t --- 7745 7746 bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that, 7747 Local<Value> data) { 7748 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7749 ENTER_V8(i_isolate); 7750 i::HandleScope scope(i_isolate); 7751 i::Handle<i::Object> foreign = i_isolate->factory()->undefined_value(); 7752 if (that != NULL) { 7753 foreign = i_isolate->factory()->NewForeign(FUNCTION_ADDR(that)); 7754 } 7755 i_isolate->debug()->SetEventListener(foreign, Utils::OpenHandle(*data, true)); 7756 return true; 7757 } 7758 7759 7760 bool Debug::SetDebugEventListener(EventCallback that, Local<Value> data) { 7761 return SetDebugEventListener( 7762 reinterpret_cast<Isolate*>(i::Isolate::Current()), that, data); 7763 } 7764 7765 7766 void Debug::DebugBreak(Isolate* isolate) { 7767 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak(); 7768 } 7769 7770 7771 void Debug::CancelDebugBreak(Isolate* isolate) { 7772 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 7773 internal_isolate->stack_guard()->ClearDebugBreak(); 7774 } 7775 7776 7777 bool Debug::CheckDebugBreak(Isolate* isolate) { 7778 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 7779 return internal_isolate->stack_guard()->CheckDebugBreak(); 7780 } 7781 7782 7783 void Debug::SetMessageHandler(Isolate* isolate, 7784 v8::Debug::MessageHandler handler) { 7785 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7786 ENTER_V8(i_isolate); 7787 i_isolate->debug()->SetMessageHandler(handler); 7788 } 7789 7790 7791 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { 7792 SetMessageHandler(reinterpret_cast<Isolate*>(i::Isolate::Current()), handler); 7793 } 7794 7795 7796 void Debug::SendCommand(Isolate* isolate, 7797 const uint16_t* command, 7798 int length, 7799 ClientData* client_data) { 7800 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 7801 internal_isolate->debug()->EnqueueCommandMessage( 7802 i::Vector<const uint16_t>(command, length), client_data); 7803 } 7804 7805 7806 MaybeLocal<Value> Debug::Call(Local<Context> context, 7807 v8::Local<v8::Function> fun, 7808 v8::Local<v8::Value> data) { 7809 PREPARE_FOR_EXECUTION(context, "v8::Debug::Call()", Value); 7810 i::Handle<i::Object> data_obj; 7811 if (data.IsEmpty()) { 7812 data_obj = isolate->factory()->undefined_value(); 7813 } else { 7814 data_obj = Utils::OpenHandle(*data); 7815 } 7816 Local<Value> result; 7817 has_pending_exception = 7818 !ToLocal<Value>(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj), 7819 &result); 7820 RETURN_ON_FAILED_EXECUTION(Value); 7821 RETURN_ESCAPED(result); 7822 } 7823 7824 7825 Local<Value> Debug::Call(v8::Local<v8::Function> fun, 7826 v8::Local<v8::Value> data) { 7827 auto context = ContextFromHeapObject(Utils::OpenHandle(*fun)); 7828 RETURN_TO_LOCAL_UNCHECKED(Call(context, fun, data), Value); 7829 } 7830 7831 7832 MaybeLocal<Value> Debug::GetMirror(Local<Context> context, 7833 v8::Local<v8::Value> obj) { 7834 PREPARE_FOR_EXECUTION(context, "v8::Debug::GetMirror()", Value); 7835 i::Debug* isolate_debug = isolate->debug(); 7836 has_pending_exception = !isolate_debug->Load(); 7837 RETURN_ON_FAILED_EXECUTION(Value); 7838 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object()); 7839 auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror"); 7840 auto fun_obj = i::Object::GetProperty(debug, name).ToHandleChecked(); 7841 auto v8_fun = Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(fun_obj)); 7842 const int kArgc = 1; 7843 v8::Local<v8::Value> argv[kArgc] = {obj}; 7844 Local<Value> result; 7845 has_pending_exception = 7846 !v8_fun->Call(context, Utils::ToLocal(debug), kArgc, argv) 7847 .ToLocal(&result); 7848 RETURN_ON_FAILED_EXECUTION(Value); 7849 RETURN_ESCAPED(result); 7850 } 7851 7852 7853 Local<Value> Debug::GetMirror(v8::Local<v8::Value> obj) { 7854 RETURN_TO_LOCAL_UNCHECKED(GetMirror(Local<Context>(), obj), Value); 7855 } 7856 7857 7858 void Debug::ProcessDebugMessages(Isolate* isolate) { 7859 reinterpret_cast<i::Isolate*>(isolate)->debug()->ProcessDebugMessages(true); 7860 } 7861 7862 7863 void Debug::ProcessDebugMessages() { 7864 ProcessDebugMessages(reinterpret_cast<Isolate*>(i::Isolate::Current())); 7865 } 7866 7867 7868 Local<Context> Debug::GetDebugContext(Isolate* isolate) { 7869 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 7870 ENTER_V8(i_isolate); 7871 return Utils::ToLocal(i_isolate->debug()->GetDebugContext()); 7872 } 7873 7874 7875 Local<Context> Debug::GetDebugContext() { 7876 return GetDebugContext(reinterpret_cast<Isolate*>(i::Isolate::Current())); 7877 } 7878 7879 7880 void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) { 7881 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 7882 internal_isolate->debug()->set_live_edit_enabled(enable); 7883 } 7884 7885 7886 MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate, 7887 Local<Value> value) { 7888 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); 7889 ENTER_V8(isolate); 7890 i::Handle<i::Object> val = Utils::OpenHandle(*value); 7891 i::Handle<i::JSArray> result; 7892 if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result)) 7893 return MaybeLocal<Array>(); 7894 return Utils::ToLocal(result); 7895 } 7896 7897 7898 Local<String> CpuProfileNode::GetFunctionName() const { 7899 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7900 i::Isolate* isolate = node->isolate(); 7901 const i::CodeEntry* entry = node->entry(); 7902 i::Handle<i::String> name = 7903 isolate->factory()->InternalizeUtf8String(entry->name()); 7904 if (!entry->has_name_prefix()) { 7905 return ToApiHandle<String>(name); 7906 } else { 7907 // We do not expect this to fail. Change this if it does. 7908 i::Handle<i::String> cons = isolate->factory()->NewConsString( 7909 isolate->factory()->InternalizeUtf8String(entry->name_prefix()), 7910 name).ToHandleChecked(); 7911 return ToApiHandle<String>(cons); 7912 } 7913 } 7914 7915 7916 int CpuProfileNode::GetScriptId() const { 7917 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7918 const i::CodeEntry* entry = node->entry(); 7919 return entry->script_id(); 7920 } 7921 7922 7923 Local<String> CpuProfileNode::GetScriptResourceName() const { 7924 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7925 i::Isolate* isolate = node->isolate(); 7926 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String( 7927 node->entry()->resource_name())); 7928 } 7929 7930 7931 int CpuProfileNode::GetLineNumber() const { 7932 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number(); 7933 } 7934 7935 7936 int CpuProfileNode::GetColumnNumber() const { 7937 return reinterpret_cast<const i::ProfileNode*>(this)-> 7938 entry()->column_number(); 7939 } 7940 7941 7942 unsigned int CpuProfileNode::GetHitLineCount() const { 7943 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7944 return node->GetHitLineCount(); 7945 } 7946 7947 7948 bool CpuProfileNode::GetLineTicks(LineTick* entries, 7949 unsigned int length) const { 7950 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7951 return node->GetLineTicks(entries, length); 7952 } 7953 7954 7955 const char* CpuProfileNode::GetBailoutReason() const { 7956 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7957 return node->entry()->bailout_reason(); 7958 } 7959 7960 7961 unsigned CpuProfileNode::GetHitCount() const { 7962 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks(); 7963 } 7964 7965 7966 unsigned CpuProfileNode::GetCallUid() const { 7967 return reinterpret_cast<const i::ProfileNode*>(this)->function_id(); 7968 } 7969 7970 7971 unsigned CpuProfileNode::GetNodeId() const { 7972 return reinterpret_cast<const i::ProfileNode*>(this)->id(); 7973 } 7974 7975 7976 int CpuProfileNode::GetChildrenCount() const { 7977 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length(); 7978 } 7979 7980 7981 const CpuProfileNode* CpuProfileNode::GetChild(int index) const { 7982 const i::ProfileNode* child = 7983 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index); 7984 return reinterpret_cast<const CpuProfileNode*>(child); 7985 } 7986 7987 7988 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const { 7989 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this); 7990 return node->deopt_infos(); 7991 } 7992 7993 7994 void CpuProfile::Delete() { 7995 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this); 7996 i::Isolate* isolate = profile->top_down()->isolate(); 7997 i::CpuProfiler* profiler = isolate->cpu_profiler(); 7998 DCHECK(profiler != NULL); 7999 profiler->DeleteProfile(profile); 8000 } 8001 8002 8003 Local<String> CpuProfile::GetTitle() const { 8004 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8005 i::Isolate* isolate = profile->top_down()->isolate(); 8006 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String( 8007 profile->title())); 8008 } 8009 8010 8011 const CpuProfileNode* CpuProfile::GetTopDownRoot() const { 8012 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8013 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root()); 8014 } 8015 8016 8017 const CpuProfileNode* CpuProfile::GetSample(int index) const { 8018 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8019 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index)); 8020 } 8021 8022 8023 int64_t CpuProfile::GetSampleTimestamp(int index) const { 8024 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8025 return (profile->sample_timestamp(index) - base::TimeTicks()) 8026 .InMicroseconds(); 8027 } 8028 8029 8030 int64_t CpuProfile::GetStartTime() const { 8031 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8032 return (profile->start_time() - base::TimeTicks()).InMicroseconds(); 8033 } 8034 8035 8036 int64_t CpuProfile::GetEndTime() const { 8037 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this); 8038 return (profile->end_time() - base::TimeTicks()).InMicroseconds(); 8039 } 8040 8041 8042 int CpuProfile::GetSamplesCount() const { 8043 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count(); 8044 } 8045 8046 8047 void CpuProfiler::SetSamplingInterval(int us) { 8048 DCHECK_GE(us, 0); 8049 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval( 8050 base::TimeDelta::FromMicroseconds(us)); 8051 } 8052 8053 8054 void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) { 8055 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling( 8056 *Utils::OpenHandle(*title), record_samples); 8057 } 8058 8059 8060 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) { 8061 return reinterpret_cast<CpuProfile*>( 8062 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling( 8063 *Utils::OpenHandle(*title))); 8064 } 8065 8066 8067 void CpuProfiler::SetIdle(bool is_idle) { 8068 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate(); 8069 v8::StateTag state = isolate->current_vm_state(); 8070 DCHECK(state == v8::EXTERNAL || state == v8::IDLE); 8071 if (isolate->js_entry_sp() != NULL) return; 8072 if (is_idle) { 8073 isolate->set_current_vm_state(v8::IDLE); 8074 } else if (state == v8::IDLE) { 8075 isolate->set_current_vm_state(v8::EXTERNAL); 8076 } 8077 } 8078 8079 8080 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) { 8081 return const_cast<i::HeapGraphEdge*>( 8082 reinterpret_cast<const i::HeapGraphEdge*>(edge)); 8083 } 8084 8085 8086 HeapGraphEdge::Type HeapGraphEdge::GetType() const { 8087 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type()); 8088 } 8089 8090 8091 Local<Value> HeapGraphEdge::GetName() const { 8092 i::HeapGraphEdge* edge = ToInternal(this); 8093 i::Isolate* isolate = edge->isolate(); 8094 switch (edge->type()) { 8095 case i::HeapGraphEdge::kContextVariable: 8096 case i::HeapGraphEdge::kInternal: 8097 case i::HeapGraphEdge::kProperty: 8098 case i::HeapGraphEdge::kShortcut: 8099 case i::HeapGraphEdge::kWeak: 8100 return ToApiHandle<String>( 8101 isolate->factory()->InternalizeUtf8String(edge->name())); 8102 case i::HeapGraphEdge::kElement: 8103 case i::HeapGraphEdge::kHidden: 8104 return ToApiHandle<Number>( 8105 isolate->factory()->NewNumberFromInt(edge->index())); 8106 default: UNREACHABLE(); 8107 } 8108 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)); 8109 } 8110 8111 8112 const HeapGraphNode* HeapGraphEdge::GetFromNode() const { 8113 const i::HeapEntry* from = ToInternal(this)->from(); 8114 return reinterpret_cast<const HeapGraphNode*>(from); 8115 } 8116 8117 8118 const HeapGraphNode* HeapGraphEdge::GetToNode() const { 8119 const i::HeapEntry* to = ToInternal(this)->to(); 8120 return reinterpret_cast<const HeapGraphNode*>(to); 8121 } 8122 8123 8124 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) { 8125 return const_cast<i::HeapEntry*>( 8126 reinterpret_cast<const i::HeapEntry*>(entry)); 8127 } 8128 8129 8130 HeapGraphNode::Type HeapGraphNode::GetType() const { 8131 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type()); 8132 } 8133 8134 8135 Local<String> HeapGraphNode::GetName() const { 8136 i::Isolate* isolate = ToInternal(this)->isolate(); 8137 return ToApiHandle<String>( 8138 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name())); 8139 } 8140 8141 8142 SnapshotObjectId HeapGraphNode::GetId() const { 8143 return ToInternal(this)->id(); 8144 } 8145 8146 8147 size_t HeapGraphNode::GetShallowSize() const { 8148 return ToInternal(this)->self_size(); 8149 } 8150 8151 8152 int HeapGraphNode::GetChildrenCount() const { 8153 return ToInternal(this)->children().length(); 8154 } 8155 8156 8157 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const { 8158 return reinterpret_cast<const HeapGraphEdge*>( 8159 ToInternal(this)->children()[index]); 8160 } 8161 8162 8163 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) { 8164 return const_cast<i::HeapSnapshot*>( 8165 reinterpret_cast<const i::HeapSnapshot*>(snapshot)); 8166 } 8167 8168 8169 void HeapSnapshot::Delete() { 8170 i::Isolate* isolate = ToInternal(this)->profiler()->isolate(); 8171 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) { 8172 ToInternal(this)->Delete(); 8173 } else { 8174 // If this is the last snapshot, clean up all accessory data as well. 8175 isolate->heap_profiler()->DeleteAllSnapshots(); 8176 } 8177 } 8178 8179 8180 const HeapGraphNode* HeapSnapshot::GetRoot() const { 8181 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root()); 8182 } 8183 8184 8185 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const { 8186 return reinterpret_cast<const HeapGraphNode*>( 8187 ToInternal(this)->GetEntryById(id)); 8188 } 8189 8190 8191 int HeapSnapshot::GetNodesCount() const { 8192 return ToInternal(this)->entries().length(); 8193 } 8194 8195 8196 const HeapGraphNode* HeapSnapshot::GetNode(int index) const { 8197 return reinterpret_cast<const HeapGraphNode*>( 8198 &ToInternal(this)->entries().at(index)); 8199 } 8200 8201 8202 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const { 8203 return ToInternal(this)->max_snapshot_js_object_id(); 8204 } 8205 8206 8207 void HeapSnapshot::Serialize(OutputStream* stream, 8208 HeapSnapshot::SerializationFormat format) const { 8209 Utils::ApiCheck(format == kJSON, 8210 "v8::HeapSnapshot::Serialize", 8211 "Unknown serialization format"); 8212 Utils::ApiCheck(stream->GetChunkSize() > 0, 8213 "v8::HeapSnapshot::Serialize", 8214 "Invalid stream chunk size"); 8215 i::HeapSnapshotJSONSerializer serializer(ToInternal(this)); 8216 serializer.Serialize(stream); 8217 } 8218 8219 8220 // static 8221 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId 8222 HeapProfiler::kUnknownObjectId; 8223 8224 8225 int HeapProfiler::GetSnapshotCount() { 8226 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount(); 8227 } 8228 8229 8230 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) { 8231 return reinterpret_cast<const HeapSnapshot*>( 8232 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index)); 8233 } 8234 8235 8236 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) { 8237 i::Handle<i::Object> obj = Utils::OpenHandle(*value); 8238 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj); 8239 } 8240 8241 8242 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) { 8243 i::Handle<i::Object> obj = 8244 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id); 8245 if (obj.is_null()) return Local<Value>(); 8246 return Utils::ToLocal(obj); 8247 } 8248 8249 8250 void HeapProfiler::ClearObjectIds() { 8251 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap(); 8252 } 8253 8254 8255 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot( 8256 ActivityControl* control, ObjectNameResolver* resolver) { 8257 return reinterpret_cast<const HeapSnapshot*>( 8258 reinterpret_cast<i::HeapProfiler*>(this) 8259 ->TakeSnapshot(control, resolver)); 8260 } 8261 8262 8263 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) { 8264 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking( 8265 track_allocations); 8266 } 8267 8268 8269 void HeapProfiler::StopTrackingHeapObjects() { 8270 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking(); 8271 } 8272 8273 8274 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream, 8275 int64_t* timestamp_us) { 8276 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this); 8277 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us); 8278 } 8279 8280 8281 void HeapProfiler::DeleteAllHeapSnapshots() { 8282 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots(); 8283 } 8284 8285 8286 void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id, 8287 WrapperInfoCallback callback) { 8288 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id, 8289 callback); 8290 } 8291 8292 8293 size_t HeapProfiler::GetProfilerMemorySize() { 8294 return reinterpret_cast<i::HeapProfiler*>(this)-> 8295 GetMemorySizeUsedByProfiler(); 8296 } 8297 8298 8299 void HeapProfiler::SetRetainedObjectInfo(UniqueId id, 8300 RetainedObjectInfo* info) { 8301 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info); 8302 } 8303 8304 8305 v8::Testing::StressType internal::Testing::stress_type_ = 8306 v8::Testing::kStressTypeOpt; 8307 8308 8309 void Testing::SetStressRunType(Testing::StressType type) { 8310 internal::Testing::set_stress_type(type); 8311 } 8312 8313 8314 int Testing::GetStressRuns() { 8315 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs; 8316 #ifdef DEBUG 8317 // In debug mode the code runs much slower so stressing will only make two 8318 // runs. 8319 return 2; 8320 #else 8321 return 5; 8322 #endif 8323 } 8324 8325 8326 static void SetFlagsFromString(const char* flags) { 8327 V8::SetFlagsFromString(flags, i::StrLength(flags)); 8328 } 8329 8330 8331 void Testing::PrepareStressRun(int run) { 8332 static const char* kLazyOptimizations = 8333 "--prepare-always-opt " 8334 "--max-inlined-source-size=999999 " 8335 "--max-inlined-nodes=999999 " 8336 "--max-inlined-nodes-cumulative=999999 " 8337 "--noalways-opt"; 8338 static const char* kForcedOptimizations = "--always-opt"; 8339 8340 // If deoptimization stressed turn on frequent deoptimization. If no value 8341 // is spefified through --deopt-every-n-times use a default default value. 8342 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13"; 8343 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt && 8344 internal::FLAG_deopt_every_n_times == 0) { 8345 SetFlagsFromString(kDeoptEvery13Times); 8346 } 8347 8348 #ifdef DEBUG 8349 // As stressing in debug mode only make two runs skip the deopt stressing 8350 // here. 8351 if (run == GetStressRuns() - 1) { 8352 SetFlagsFromString(kForcedOptimizations); 8353 } else { 8354 SetFlagsFromString(kLazyOptimizations); 8355 } 8356 #else 8357 if (run == GetStressRuns() - 1) { 8358 SetFlagsFromString(kForcedOptimizations); 8359 } else if (run != GetStressRuns() - 2) { 8360 SetFlagsFromString(kLazyOptimizations); 8361 } 8362 #endif 8363 } 8364 8365 8366 void Testing::DeoptimizeAll(Isolate* isolate) { 8367 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 8368 i::HandleScope scope(i_isolate); 8369 internal::Deoptimizer::DeoptimizeAll(i_isolate); 8370 } 8371 8372 8373 namespace internal { 8374 8375 8376 void HandleScopeImplementer::FreeThreadResources() { 8377 Free(); 8378 } 8379 8380 8381 char* HandleScopeImplementer::ArchiveThread(char* storage) { 8382 HandleScopeData* current = isolate_->handle_scope_data(); 8383 handle_scope_data_ = *current; 8384 MemCopy(storage, this, sizeof(*this)); 8385 8386 ResetAfterArchive(); 8387 current->Initialize(); 8388 8389 return storage + ArchiveSpacePerThread(); 8390 } 8391 8392 8393 int HandleScopeImplementer::ArchiveSpacePerThread() { 8394 return sizeof(HandleScopeImplementer); 8395 } 8396 8397 8398 char* HandleScopeImplementer::RestoreThread(char* storage) { 8399 MemCopy(this, storage, sizeof(*this)); 8400 *isolate_->handle_scope_data() = handle_scope_data_; 8401 return storage + ArchiveSpacePerThread(); 8402 } 8403 8404 8405 void HandleScopeImplementer::IterateThis(ObjectVisitor* v) { 8406 #ifdef DEBUG 8407 bool found_block_before_deferred = false; 8408 #endif 8409 // Iterate over all handles in the blocks except for the last. 8410 for (int i = blocks()->length() - 2; i >= 0; --i) { 8411 Object** block = blocks()->at(i); 8412 if (last_handle_before_deferred_block_ != NULL && 8413 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) && 8414 (last_handle_before_deferred_block_ >= block)) { 8415 v->VisitPointers(block, last_handle_before_deferred_block_); 8416 DCHECK(!found_block_before_deferred); 8417 #ifdef DEBUG 8418 found_block_before_deferred = true; 8419 #endif 8420 } else { 8421 v->VisitPointers(block, &block[kHandleBlockSize]); 8422 } 8423 } 8424 8425 DCHECK(last_handle_before_deferred_block_ == NULL || 8426 found_block_before_deferred); 8427 8428 // Iterate over live handles in the last block (if any). 8429 if (!blocks()->is_empty()) { 8430 v->VisitPointers(blocks()->last(), handle_scope_data_.next); 8431 } 8432 8433 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_}; 8434 for (unsigned i = 0; i < arraysize(context_lists); i++) { 8435 if (context_lists[i]->is_empty()) continue; 8436 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first()); 8437 v->VisitPointers(start, start + context_lists[i]->length()); 8438 } 8439 } 8440 8441 8442 void HandleScopeImplementer::Iterate(ObjectVisitor* v) { 8443 HandleScopeData* current = isolate_->handle_scope_data(); 8444 handle_scope_data_ = *current; 8445 IterateThis(v); 8446 } 8447 8448 8449 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { 8450 HandleScopeImplementer* scope_implementer = 8451 reinterpret_cast<HandleScopeImplementer*>(storage); 8452 scope_implementer->IterateThis(v); 8453 return storage + ArchiveSpacePerThread(); 8454 } 8455 8456 8457 DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) { 8458 DeferredHandles* deferred = 8459 new DeferredHandles(isolate()->handle_scope_data()->next, isolate()); 8460 8461 while (!blocks_.is_empty()) { 8462 Object** block_start = blocks_.last(); 8463 Object** block_limit = &block_start[kHandleBlockSize]; 8464 // We should not need to check for SealHandleScope here. Assert this. 8465 DCHECK(prev_limit == block_limit || 8466 !(block_start <= prev_limit && prev_limit <= block_limit)); 8467 if (prev_limit == block_limit) break; 8468 deferred->blocks_.Add(blocks_.last()); 8469 blocks_.RemoveLast(); 8470 } 8471 8472 // deferred->blocks_ now contains the blocks installed on the 8473 // HandleScope stack since BeginDeferredScope was called, but in 8474 // reverse order. 8475 8476 DCHECK(prev_limit == NULL || !blocks_.is_empty()); 8477 8478 DCHECK(!blocks_.is_empty() && prev_limit != NULL); 8479 DCHECK(last_handle_before_deferred_block_ != NULL); 8480 last_handle_before_deferred_block_ = NULL; 8481 return deferred; 8482 } 8483 8484 8485 void HandleScopeImplementer::BeginDeferredScope() { 8486 DCHECK(last_handle_before_deferred_block_ == NULL); 8487 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next; 8488 } 8489 8490 8491 DeferredHandles::~DeferredHandles() { 8492 isolate_->UnlinkDeferredHandles(this); 8493 8494 for (int i = 0; i < blocks_.length(); i++) { 8495 #ifdef ENABLE_HANDLE_ZAPPING 8496 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]); 8497 #endif 8498 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]); 8499 } 8500 } 8501 8502 8503 void DeferredHandles::Iterate(ObjectVisitor* v) { 8504 DCHECK(!blocks_.is_empty()); 8505 8506 DCHECK((first_block_limit_ >= blocks_.first()) && 8507 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize])); 8508 8509 v->VisitPointers(blocks_.first(), first_block_limit_); 8510 8511 for (int i = 1; i < blocks_.length(); i++) { 8512 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]); 8513 } 8514 } 8515 8516 8517 void InvokeAccessorGetterCallback( 8518 v8::Local<v8::Name> property, 8519 const v8::PropertyCallbackInfo<v8::Value>& info, 8520 v8::AccessorNameGetterCallback getter) { 8521 // Leaving JavaScript. 8522 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); 8523 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>( 8524 getter)); 8525 VMState<EXTERNAL> state(isolate); 8526 ExternalCallbackScope call_scope(isolate, getter_address); 8527 getter(property, info); 8528 } 8529 8530 8531 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info, 8532 v8::FunctionCallback callback) { 8533 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); 8534 Address callback_address = 8535 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); 8536 VMState<EXTERNAL> state(isolate); 8537 ExternalCallbackScope call_scope(isolate, callback_address); 8538 callback(info); 8539 } 8540 8541 8542 } // namespace internal 8543 } // namespace v8 8544