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