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