Line data Source code
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 : #if defined(LEAK_SANITIZER)
12 : #include <sanitizer/lsan_interface.h>
13 : #endif // defined(LEAK_SANITIZER)
14 : #include <cmath> // For isnan.
15 : #include <limits>
16 : #include <vector>
17 : #include "include/v8-debug.h"
18 : #include "include/v8-profiler.h"
19 : #include "include/v8-testing.h"
20 : #include "include/v8-util.h"
21 : #include "src/accessors.h"
22 : #include "src/api-natives.h"
23 : #include "src/assert-scope.h"
24 : #include "src/base/functional.h"
25 : #include "src/base/logging.h"
26 : #include "src/base/platform/platform.h"
27 : #include "src/base/platform/time.h"
28 : #include "src/base/safe_conversions.h"
29 : #include "src/base/utils/random-number-generator.h"
30 : #include "src/bootstrapper.h"
31 : #include "src/builtins/builtins-utils.h"
32 : #include "src/char-predicates-inl.h"
33 : #include "src/code-stubs.h"
34 : #include "src/compiler-dispatcher/compiler-dispatcher.h"
35 : #include "src/compiler.h"
36 : #include "src/contexts.h"
37 : #include "src/conversions-inl.h"
38 : #include "src/counters.h"
39 : #include "src/debug/debug-coverage.h"
40 : #include "src/debug/debug-type-profile.h"
41 : #include "src/debug/debug.h"
42 : #include "src/deoptimizer.h"
43 : #include "src/detachable-vector.h"
44 : #include "src/execution.h"
45 : #include "src/frames-inl.h"
46 : #include "src/gdb-jit.h"
47 : #include "src/global-handles.h"
48 : #include "src/globals.h"
49 : #include "src/icu_util.h"
50 : #include "src/isolate-inl.h"
51 : #include "src/json-parser.h"
52 : #include "src/json-stringifier.h"
53 : #include "src/messages.h"
54 : #include "src/objects-inl.h"
55 : #include "src/parsing/background-parsing-task.h"
56 : #include "src/parsing/parser.h"
57 : #include "src/parsing/scanner-character-streams.h"
58 : #include "src/pending-compilation-error-handler.h"
59 : #include "src/profiler/cpu-profiler.h"
60 : #include "src/profiler/heap-profiler.h"
61 : #include "src/profiler/heap-snapshot-generator-inl.h"
62 : #include "src/profiler/profile-generator-inl.h"
63 : #include "src/profiler/tick-sample.h"
64 : #include "src/property-descriptor.h"
65 : #include "src/property-details.h"
66 : #include "src/property.h"
67 : #include "src/prototype.h"
68 : #include "src/runtime-profiler.h"
69 : #include "src/runtime/runtime.h"
70 : #include "src/simulator.h"
71 : #include "src/snapshot/builtin-serializer.h"
72 : #include "src/snapshot/code-serializer.h"
73 : #include "src/snapshot/natives.h"
74 : #include "src/snapshot/snapshot.h"
75 : #include "src/startup-data-util.h"
76 : #include "src/tracing/trace-event.h"
77 : #include "src/trap-handler/trap-handler.h"
78 : #include "src/unicode-cache-inl.h"
79 : #include "src/unicode-inl.h"
80 : #include "src/v8.h"
81 : #include "src/v8threads.h"
82 : #include "src/value-serializer.h"
83 : #include "src/version.h"
84 : #include "src/vm-state-inl.h"
85 : #include "src/wasm/compilation-manager.h"
86 : #include "src/wasm/streaming-decoder.h"
87 : #include "src/wasm/wasm-objects-inl.h"
88 : #include "src/wasm/wasm-result.h"
89 :
90 : namespace v8 {
91 :
92 : /*
93 : * Most API methods should use one of the three macros:
94 : *
95 : * ENTER_V8, ENTER_V8_NO_SCRIPT, ENTER_V8_NO_SCRIPT_NO_EXCEPTION.
96 : *
97 : * The latter two assume that no script is executed, and no exceptions are
98 : * scheduled in addition (respectively). Creating a pending exception and
99 : * removing it before returning is ok.
100 : *
101 : * Exceptions should be handled either by invoking one of the
102 : * RETURN_ON_FAILED_EXECUTION* macros.
103 : *
104 : * Don't use macros with DO_NOT_USE in their name.
105 : *
106 : * TODO(jochen): Document debugger specific macros.
107 : * TODO(jochen): Document LOG_API and other RuntimeCallStats macros.
108 : * TODO(jochen): All API methods should invoke one of the ENTER_V8* macros.
109 : * TODO(jochen): Remove calls form API methods to DO_NOT_USE macros.
110 : */
111 :
112 : #define LOG_API(isolate, class_name, function_name) \
113 : i::RuntimeCallTimerScope _runtime_timer( \
114 : isolate, &i::RuntimeCallStats::API_##class_name##_##function_name); \
115 : LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name))
116 :
117 : #define ENTER_V8_DO_NOT_USE(isolate) i::VMState<v8::OTHER> __state__((isolate))
118 :
119 : #define ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, \
120 : function_name, bailout_value, \
121 : HandleScopeClass, do_callback) \
122 : if (IsExecutionTerminatingCheck(isolate)) { \
123 : return bailout_value; \
124 : } \
125 : HandleScopeClass handle_scope(isolate); \
126 : CallDepthScope<do_callback> call_depth_scope(isolate, context); \
127 : LOG_API(isolate, class_name, function_name); \
128 : i::VMState<v8::OTHER> __state__((isolate)); \
129 : bool has_pending_exception = false
130 :
131 : #define PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, T) \
132 : if (IsExecutionTerminatingCheck(isolate)) { \
133 : return MaybeLocal<T>(); \
134 : } \
135 : InternalEscapableScope handle_scope(isolate); \
136 : CallDepthScope<false> call_depth_scope(isolate, v8::Local<v8::Context>()); \
137 : i::VMState<v8::OTHER> __state__((isolate)); \
138 : bool has_pending_exception = false
139 :
140 : #define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
141 : bailout_value, HandleScopeClass, \
142 : do_callback) \
143 : auto isolate = context.IsEmpty() \
144 : ? i::Isolate::Current() \
145 : : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
146 : ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
147 : bailout_value, HandleScopeClass, do_callback);
148 :
149 : #define PREPARE_FOR_EXECUTION(context, class_name, function_name, T) \
150 : PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
151 : MaybeLocal<T>(), InternalEscapableScope, \
152 : false)
153 :
154 : #define ENTER_V8(isolate, context, class_name, function_name, bailout_value, \
155 : HandleScopeClass) \
156 : ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
157 : bailout_value, HandleScopeClass, true)
158 :
159 : #ifdef DEBUG
160 : #define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \
161 : bailout_value, HandleScopeClass) \
162 : ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
163 : bailout_value, HandleScopeClass, false); \
164 : i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate))
165 :
166 : #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \
167 : i::VMState<v8::OTHER> __state__((isolate)); \
168 : i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \
169 : i::DisallowExceptions __no_exceptions__((isolate))
170 :
171 : #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \
172 : i::VMState<v8::OTHER> __state__((isolate)); \
173 : i::DisallowExceptions __no_exceptions__((isolate))
174 : #else
175 : #define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \
176 : bailout_value, HandleScopeClass) \
177 : ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
178 : bailout_value, HandleScopeClass, false)
179 :
180 : #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \
181 : i::VMState<v8::OTHER> __state__((isolate));
182 :
183 : #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \
184 : i::VMState<v8::OTHER> __state__((isolate));
185 : #endif // DEBUG
186 :
187 : #define EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, value) \
188 : do { \
189 : if (has_pending_exception) { \
190 : call_depth_scope.Escape(); \
191 : return value; \
192 : } \
193 : } while (false)
194 :
195 : #define RETURN_ON_FAILED_EXECUTION(T) \
196 : EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, MaybeLocal<T>())
197 :
198 : #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \
199 : EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, Nothing<T>())
200 :
201 : #define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \
202 : return maybe_local.FromMaybe(Local<T>());
203 :
204 :
205 : #define RETURN_ESCAPED(value) return handle_scope.Escape(value);
206 :
207 :
208 : namespace {
209 :
210 : Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) {
211 : return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate())
212 0 : ->GetCurrentContext();
213 : }
214 :
215 : class InternalEscapableScope : public v8::EscapableHandleScope {
216 : public:
217 : explicit inline InternalEscapableScope(i::Isolate* isolate)
218 81420783 : : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {}
219 : };
220 :
221 : // TODO(jochen): This should be #ifdef DEBUG
222 : #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY
223 : void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
224 : auto handle_scope_implementer = isolate->handle_scope_implementer();
225 : if (handle_scope_implementer->microtasks_policy() ==
226 : v8::MicrotasksPolicy::kScoped) {
227 : DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
228 : !handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
229 : }
230 : }
231 : #endif
232 :
233 : template <bool do_callback>
234 : class CallDepthScope {
235 : public:
236 278915473 : explicit CallDepthScope(i::Isolate* isolate, Local<Context> context)
237 133677475 : : isolate_(isolate), context_(context), escaped_(false) {
238 : // TODO(dcarney): remove this when blink stops crashing.
239 : DCHECK(!isolate_->external_caught_exception());
240 133677475 : isolate_->handle_scope_implementer()->IncrementCallDepth();
241 133677475 : if (!context.IsEmpty()) {
242 : i::Handle<i::Context> env = Utils::OpenHandle(*context);
243 : i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
244 267247027 : if (isolate->context() != nullptr &&
245 : isolate->context()->native_context() == env->native_context()) {
246 122110598 : context_ = Local<Context>();
247 : } else {
248 : impl->SaveContext(isolate->context());
249 : isolate->set_context(*env);
250 : }
251 : }
252 10717040 : if (do_callback) isolate_->FireBeforeCallEnteredCallback();
253 133677475 : }
254 133677515 : ~CallDepthScope() {
255 133677515 : if (!context_.IsEmpty()) {
256 145227099 : i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
257 11563700 : isolate_->set_context(impl->RestoreContext());
258 : }
259 133677515 : if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
260 10717080 : if (do_callback) isolate_->FireCallCompletedCallback();
261 : // TODO(jochen): This should be #ifdef DEBUG
262 : #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY
263 : if (do_callback) CheckMicrotasksScopesConsistency(isolate_);
264 : #endif
265 133677520 : }
266 :
267 14118 : void Escape() {
268 : DCHECK(!escaped_);
269 14118 : escaped_ = true;
270 14118 : auto handle_scope_implementer = isolate_->handle_scope_implementer();
271 : handle_scope_implementer->DecrementCallDepth();
272 : bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
273 14118 : isolate_->OptionalRescheduleException(call_depth_is_zero);
274 14118 : }
275 :
276 : private:
277 : i::Isolate* const isolate_;
278 : Local<Context> context_;
279 : bool escaped_;
280 : bool do_callback_;
281 : };
282 :
283 : } // namespace
284 :
285 :
286 18604 : static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
287 : i::Handle<i::Script> script) {
288 18604 : i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
289 : i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
290 : i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(),
291 : isolate);
292 : v8::Isolate* v8_isolate =
293 : reinterpret_cast<v8::Isolate*>(script->GetIsolate());
294 : ScriptOriginOptions options(script->origin_options());
295 : v8::ScriptOrigin origin(
296 : Utils::ToLocal(scriptName),
297 : v8::Integer::New(v8_isolate, script->line_offset()),
298 : v8::Integer::New(v8_isolate, script->column_offset()),
299 : v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
300 : v8::Integer::New(v8_isolate, script->id()),
301 : Utils::ToLocal(source_map_url),
302 : v8::Boolean::New(v8_isolate, options.IsOpaque()),
303 : v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM),
304 : v8::Boolean::New(v8_isolate, options.IsModule()),
305 55812 : Utils::ToLocal(host_defined_options));
306 18604 : return origin;
307 : }
308 :
309 :
310 : // --- E x c e p t i o n B e h a v i o r ---
311 :
312 :
313 6 : void i::FatalProcessOutOfMemory(const char* location) {
314 6 : i::V8::FatalProcessOutOfMemory(location, false);
315 : }
316 :
317 : // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
318 : // OOM error handler is called and execution is stopped.
319 18 : void i::V8::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) {
320 : i::Isolate* isolate = i::Isolate::Current();
321 : char last_few_messages[Heap::kTraceRingBufferSize + 1];
322 : char js_stacktrace[Heap::kStacktraceBufferSize + 1];
323 : i::HeapStats heap_stats;
324 :
325 18 : if (isolate == nullptr) {
326 : // On a background thread -> we cannot retrieve memory information from the
327 : // Isolate. Write easy-to-recognize values on the stack.
328 : memset(last_few_messages, 0x0badc0de, Heap::kTraceRingBufferSize + 1);
329 : memset(js_stacktrace, 0x0badc0de, Heap::kStacktraceBufferSize + 1);
330 : memset(&heap_stats, 0xbadc0de, sizeof(heap_stats));
331 : // Note that the embedder's oom handler won't be called in this case. We
332 : // just crash.
333 0 : FATAL("API fatal error handler returned after process out of memory");
334 : return;
335 : }
336 :
337 : memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
338 : memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
339 :
340 : intptr_t start_marker;
341 18 : heap_stats.start_marker = &start_marker;
342 : size_t new_space_size;
343 18 : heap_stats.new_space_size = &new_space_size;
344 : size_t new_space_capacity;
345 18 : heap_stats.new_space_capacity = &new_space_capacity;
346 : size_t old_space_size;
347 18 : heap_stats.old_space_size = &old_space_size;
348 : size_t old_space_capacity;
349 18 : heap_stats.old_space_capacity = &old_space_capacity;
350 : size_t code_space_size;
351 18 : heap_stats.code_space_size = &code_space_size;
352 : size_t code_space_capacity;
353 18 : heap_stats.code_space_capacity = &code_space_capacity;
354 : size_t map_space_size;
355 18 : heap_stats.map_space_size = &map_space_size;
356 : size_t map_space_capacity;
357 18 : heap_stats.map_space_capacity = &map_space_capacity;
358 : size_t lo_space_size;
359 18 : heap_stats.lo_space_size = &lo_space_size;
360 : size_t global_handle_count;
361 18 : heap_stats.global_handle_count = &global_handle_count;
362 : size_t weak_global_handle_count;
363 18 : heap_stats.weak_global_handle_count = &weak_global_handle_count;
364 : size_t pending_global_handle_count;
365 18 : heap_stats.pending_global_handle_count = &pending_global_handle_count;
366 : size_t near_death_global_handle_count;
367 18 : heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
368 : size_t free_global_handle_count;
369 18 : heap_stats.free_global_handle_count = &free_global_handle_count;
370 : size_t memory_allocator_size;
371 18 : heap_stats.memory_allocator_size = &memory_allocator_size;
372 : size_t memory_allocator_capacity;
373 18 : heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
374 : size_t malloced_memory;
375 18 : heap_stats.malloced_memory = &malloced_memory;
376 : size_t malloced_peak_memory;
377 18 : heap_stats.malloced_peak_memory = &malloced_peak_memory;
378 18 : size_t objects_per_type[LAST_TYPE + 1] = {0};
379 18 : heap_stats.objects_per_type = objects_per_type;
380 18 : size_t size_per_type[LAST_TYPE + 1] = {0};
381 18 : heap_stats.size_per_type = size_per_type;
382 : int os_error;
383 18 : heap_stats.os_error = &os_error;
384 18 : heap_stats.last_few_messages = last_few_messages;
385 18 : heap_stats.js_stacktrace = js_stacktrace;
386 : intptr_t end_marker;
387 18 : heap_stats.end_marker = &end_marker;
388 18 : if (isolate->heap()->HasBeenSetUp()) {
389 : // BUG(1718): Don't use the take_snapshot since we don't support
390 : // HeapIterator here without doing a special GC.
391 18 : isolate->heap()->RecordStats(&heap_stats, false);
392 : char* first_newline = strchr(last_few_messages, '\n');
393 18 : if (first_newline == nullptr || first_newline[1] == '\0')
394 : first_newline = last_few_messages;
395 18 : PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
396 18 : PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
397 : }
398 18 : Utils::ReportOOMFailure(location, is_heap_oom);
399 : // If the fatal error handler returns, we stop execution.
400 0 : FATAL("API fatal error handler returned after process out of memory");
401 : }
402 :
403 :
404 10 : void Utils::ReportApiFailure(const char* location, const char* message) {
405 10 : i::Isolate* isolate = i::Isolate::Current();
406 : FatalErrorCallback callback = isolate->exception_behavior();
407 10 : if (callback == nullptr) {
408 : base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
409 0 : message);
410 0 : base::OS::Abort();
411 : } else {
412 10 : callback(location, message);
413 : }
414 : isolate->SignalFatalError();
415 10 : }
416 :
417 18 : void Utils::ReportOOMFailure(const char* location, bool is_heap_oom) {
418 36 : i::Isolate* isolate = i::Isolate::Current();
419 : OOMErrorCallback oom_callback = isolate->oom_behavior();
420 18 : if (oom_callback == nullptr) {
421 : // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
422 : // crbug.com/614440.
423 : FatalErrorCallback fatal_callback = isolate->exception_behavior();
424 18 : if (fatal_callback == nullptr) {
425 : base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
426 0 : is_heap_oom ? "javascript" : "process", location);
427 0 : base::OS::Abort();
428 : } else {
429 : fatal_callback(location,
430 : is_heap_oom
431 : ? "Allocation failed - JavaScript heap out of memory"
432 18 : : "Allocation failed - process out of memory");
433 : }
434 : } else {
435 0 : oom_callback(location, is_heap_oom);
436 : }
437 : isolate->SignalFatalError();
438 0 : }
439 :
440 : static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
441 133734214 : if (isolate->has_scheduled_exception()) {
442 : return isolate->scheduled_exception() ==
443 181 : isolate->heap()->termination_exception();
444 : }
445 : return false;
446 : }
447 :
448 :
449 53983 : void V8::SetNativesDataBlob(StartupData* natives_blob) {
450 53983 : i::V8::SetNativesBlob(natives_blob);
451 53983 : }
452 :
453 :
454 53983 : void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
455 53983 : i::V8::SetSnapshotBlob(snapshot_blob);
456 53983 : }
457 :
458 0 : void* v8::ArrayBuffer::Allocator::Reserve(size_t length) { UNIMPLEMENTED(); }
459 :
460 0 : void v8::ArrayBuffer::Allocator::Free(void* data, size_t length,
461 : AllocationMode mode) {
462 0 : switch (mode) {
463 : case AllocationMode::kNormal: {
464 0 : Free(data, length);
465 0 : return;
466 : }
467 : case AllocationMode::kReservation: {
468 0 : UNIMPLEMENTED();
469 : return;
470 : }
471 : }
472 : }
473 :
474 0 : void v8::ArrayBuffer::Allocator::SetProtection(
475 : void* data, size_t length,
476 : v8::ArrayBuffer::Allocator::Protection protection) {
477 0 : UNIMPLEMENTED();
478 : }
479 :
480 : namespace {
481 :
482 189681 : class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
483 : public:
484 6959 : virtual void* Allocate(size_t length) {
485 6959 : void* data = AllocateUninitialized(length);
486 13918 : return data == nullptr ? data : memset(data, 0, length);
487 : }
488 7100 : virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
489 6937 : virtual void Free(void* data, size_t) { free(data); }
490 :
491 691 : virtual void* Reserve(size_t length) {
492 : void* address =
493 691 : base::OS::ReserveRegion(length, base::OS::GetRandomMmapAddr());
494 : #if defined(LEAK_SANITIZER)
495 : __lsan_register_root_region(address, length);
496 : #endif
497 691 : return address;
498 : }
499 :
500 7597 : virtual void Free(void* data, size_t length,
501 : v8::ArrayBuffer::Allocator::AllocationMode mode) {
502 7597 : switch (mode) {
503 : case v8::ArrayBuffer::Allocator::AllocationMode::kNormal: {
504 6908 : return Free(data, length);
505 : }
506 : case v8::ArrayBuffer::Allocator::AllocationMode::kReservation: {
507 689 : base::OS::ReleaseRegion(data, length);
508 689 : return;
509 : }
510 : }
511 : }
512 :
513 861 : virtual void SetProtection(
514 : void* data, size_t length,
515 : v8::ArrayBuffer::Allocator::Protection protection) {
516 861 : switch (protection) {
517 : case v8::ArrayBuffer::Allocator::Protection::kNoAccess: {
518 0 : base::OS::Guard(data, length);
519 0 : return;
520 : }
521 : case v8::ArrayBuffer::Allocator::Protection::kReadWrite: {
522 861 : base::OS::SetReadAndWritable(data, length, true);
523 861 : return;
524 : }
525 : }
526 : }
527 : };
528 :
529 50 : bool RunExtraCode(Isolate* isolate, Local<Context> context,
530 : const char* utf8_source, const char* name) {
531 : base::ElapsedTimer timer;
532 : timer.Start();
533 : Context::Scope context_scope(context);
534 100 : TryCatch try_catch(isolate);
535 : Local<String> source_string;
536 50 : if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal)
537 50 : .ToLocal(&source_string)) {
538 : return false;
539 : }
540 : Local<String> resource_name =
541 : String::NewFromUtf8(isolate, name, NewStringType::kNormal)
542 50 : .ToLocalChecked();
543 : ScriptOrigin origin(resource_name);
544 : ScriptCompiler::Source source(source_string, origin);
545 : Local<Script> script;
546 100 : if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false;
547 100 : if (script->Run(context).IsEmpty()) return false;
548 50 : if (i::FLAG_profile_deserialization) {
549 : i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name,
550 0 : timer.Elapsed().InMillisecondsF());
551 : }
552 : timer.Stop();
553 50 : CHECK(!try_catch.HasCaught());
554 : return true;
555 : }
556 :
557 363 : struct SnapshotCreatorData {
558 : explicit SnapshotCreatorData(Isolate* isolate)
559 : : isolate_(isolate),
560 : default_context_(),
561 : contexts_(isolate),
562 : templates_(isolate),
563 242 : created_(false) {}
564 :
565 : static SnapshotCreatorData* cast(void* data) {
566 : return reinterpret_cast<SnapshotCreatorData*>(data);
567 : }
568 :
569 : ArrayBufferAllocator allocator_;
570 : Isolate* isolate_;
571 : Persistent<Context> default_context_;
572 : SerializeInternalFieldsCallback default_embedder_fields_serializer_;
573 : PersistentValueVector<Context> contexts_;
574 : PersistentValueVector<Template> templates_;
575 : std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
576 : bool created_;
577 : };
578 :
579 : } // namespace
580 :
581 121 : SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
582 : StartupData* existing_snapshot) {
583 121 : i::Isolate* internal_isolate = new i::Isolate(true);
584 : Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
585 121 : SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
586 : data->isolate_ = isolate;
587 121 : internal_isolate->set_array_buffer_allocator(&data->allocator_);
588 : internal_isolate->set_api_external_references(external_references);
589 : isolate->Enter();
590 : const StartupData* blob = existing_snapshot
591 : ? existing_snapshot
592 121 : : i::Snapshot::DefaultSnapshotBlob();
593 121 : if (blob && blob->raw_size > 0) {
594 : internal_isolate->set_snapshot_blob(blob);
595 120 : i::Snapshot::Initialize(internal_isolate);
596 : } else {
597 1 : internal_isolate->Init(nullptr);
598 : }
599 121 : data_ = data;
600 121 : }
601 :
602 121 : SnapshotCreator::~SnapshotCreator() {
603 121 : SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
604 : DCHECK(data->created_);
605 121 : Isolate* isolate = data->isolate_;
606 : isolate->Exit();
607 121 : isolate->Dispose();
608 121 : delete data;
609 121 : }
610 :
611 60 : Isolate* SnapshotCreator::GetIsolate() {
612 121 : return SnapshotCreatorData::cast(data_)->isolate_;
613 : }
614 :
615 121 : void SnapshotCreator::SetDefaultContext(
616 : Local<Context> context, SerializeInternalFieldsCallback callback) {
617 : DCHECK(!context.IsEmpty());
618 121 : SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
619 : DCHECK(!data->created_);
620 : DCHECK(data->default_context_.IsEmpty());
621 121 : Isolate* isolate = data->isolate_;
622 121 : CHECK_EQ(isolate, context->GetIsolate());
623 : data->default_context_.Reset(isolate, context);
624 121 : data->default_embedder_fields_serializer_ = callback;
625 121 : }
626 :
627 20 : size_t SnapshotCreator::AddContext(Local<Context> context,
628 : SerializeInternalFieldsCallback callback) {
629 : DCHECK(!context.IsEmpty());
630 20 : SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
631 : DCHECK(!data->created_);
632 20 : Isolate* isolate = data->isolate_;
633 20 : CHECK_EQ(isolate, context->GetIsolate());
634 20 : size_t index = static_cast<int>(data->contexts_.Size());
635 20 : data->contexts_.Append(context);
636 20 : data->embedder_fields_serializers_.push_back(callback);
637 20 : return index;
638 : }
639 :
640 10 : size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) {
641 : DCHECK(!template_obj.IsEmpty());
642 10 : SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
643 : DCHECK(!data->created_);
644 : DCHECK_EQ(reinterpret_cast<i::Isolate*>(data->isolate_),
645 : Utils::OpenHandle(*template_obj)->GetIsolate());
646 : size_t index = static_cast<int>(data->templates_.Size());
647 10 : data->templates_.Append(template_obj);
648 10 : return index;
649 : }
650 :
651 121 : StartupData SnapshotCreator::CreateBlob(
652 : SnapshotCreator::FunctionCodeHandling function_code_handling) {
653 121 : SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
654 242 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
655 : DCHECK(!data->created_);
656 : DCHECK(!data->default_context_.IsEmpty());
657 :
658 121 : int num_additional_contexts = static_cast<int>(data->contexts_.Size());
659 :
660 : {
661 121 : int num_templates = static_cast<int>(data->templates_.Size());
662 : i::HandleScope scope(isolate);
663 : i::Handle<i::FixedArray> templates =
664 121 : isolate->factory()->NewFixedArray(num_templates, i::TENURED);
665 131 : for (int i = 0; i < num_templates; i++) {
666 20 : templates->set(i, *v8::Utils::OpenHandle(*data->templates_.Get(i)));
667 : }
668 121 : isolate->heap()->SetSerializedTemplates(*templates);
669 121 : data->templates_.Clear();
670 :
671 : // We need to store the global proxy size upfront in case we need the
672 : // bootstrapper to create a global proxy before we deserialize the context.
673 : i::Handle<i::FixedArray> global_proxy_sizes =
674 121 : isolate->factory()->NewFixedArray(num_additional_contexts, i::TENURED);
675 141 : for (int i = 0; i < num_additional_contexts; i++) {
676 : i::Handle<i::Context> context =
677 40 : v8::Utils::OpenHandle(*data->contexts_.Get(i));
678 : global_proxy_sizes->set(i,
679 20 : i::Smi::FromInt(context->global_proxy()->Size()));
680 : }
681 121 : isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
682 : }
683 :
684 : // We might rehash strings and re-sort descriptors. Clear the lookup cache.
685 121 : isolate->descriptor_lookup_cache()->Clear();
686 :
687 : // If we don't do this then we end up with a stray root pointing at the
688 : // context even after we have disposed of the context.
689 : isolate->heap()->CollectAllAvailableGarbage(
690 121 : i::GarbageCollectionReason::kSnapshotCreator);
691 121 : isolate->heap()->CompactWeakFixedArrays();
692 :
693 : i::DisallowHeapAllocation no_gc_from_here_on;
694 :
695 : std::vector<i::Object*> contexts;
696 121 : contexts.reserve(num_additional_contexts);
697 : i::Object* default_context;
698 : {
699 : i::HandleScope scope(isolate);
700 : default_context =
701 242 : *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_));
702 : data->default_context_.Reset();
703 20 : for (int i = 0; i < num_additional_contexts; i++) {
704 : i::Handle<i::Context> context =
705 40 : v8::Utils::OpenHandle(*data->contexts_.Get(i));
706 40 : contexts.push_back(*context);
707 : }
708 121 : data->contexts_.Clear();
709 : }
710 :
711 : // Complete in-object slack tracking for all functions.
712 242 : i::HeapIterator heap_iterator(isolate->heap());
713 1274168 : while (i::HeapObject* current_obj = heap_iterator.next()) {
714 1274047 : if (!current_obj->IsJSFunction()) continue;
715 : i::JSFunction* fun = i::JSFunction::cast(current_obj);
716 153528 : fun->CompleteInobjectSlackTrackingIfActive();
717 : }
718 :
719 242 : i::StartupSerializer startup_serializer(isolate, function_code_handling);
720 121 : startup_serializer.SerializeStrongReferences();
721 :
722 : // Serialize each context with a new partial serializer.
723 : std::vector<i::SnapshotData*> context_snapshots;
724 121 : context_snapshots.reserve(num_additional_contexts + 1);
725 :
726 : // TODO(6593): generalize rehashing, and remove this flag.
727 : bool can_be_rehashed = true;
728 :
729 : {
730 : // The default context is created with a handler for embedder fields which
731 : // determines how they are handled if encountered during serialization.
732 : i::PartialSerializer partial_serializer(
733 : isolate, &startup_serializer,
734 121 : data->default_embedder_fields_serializer_);
735 121 : partial_serializer.Serialize(&default_context, false);
736 121 : can_be_rehashed = can_be_rehashed && partial_serializer.can_be_rehashed();
737 242 : context_snapshots.push_back(new i::SnapshotData(&partial_serializer));
738 : }
739 :
740 141 : for (int i = 0; i < num_additional_contexts; i++) {
741 : i::PartialSerializer partial_serializer(
742 40 : isolate, &startup_serializer, data->embedder_fields_serializers_[i]);
743 40 : partial_serializer.Serialize(&contexts[i], true);
744 20 : can_be_rehashed = can_be_rehashed && partial_serializer.can_be_rehashed();
745 40 : context_snapshots.push_back(new i::SnapshotData(&partial_serializer));
746 20 : }
747 :
748 : // Builtin serialization places additional objects into the partial snapshot
749 : // cache and thus needs to happen before SerializeWeakReferencesAndDeferred
750 : // is called below.
751 242 : i::BuiltinSerializer builtin_serializer(isolate, &startup_serializer);
752 121 : builtin_serializer.SerializeBuiltins();
753 :
754 121 : startup_serializer.SerializeWeakReferencesAndDeferred();
755 121 : can_be_rehashed = can_be_rehashed && startup_serializer.can_be_rehashed();
756 :
757 121 : i::SnapshotData startup_snapshot(&startup_serializer);
758 121 : i::BuiltinSnapshotData builtin_snapshot(&builtin_serializer);
759 : StartupData result = i::Snapshot::CreateSnapshotBlob(
760 121 : &startup_snapshot, &builtin_snapshot, context_snapshots, can_be_rehashed);
761 :
762 : // Delete heap-allocated context snapshot instances.
763 383 : for (const auto context_snapshot : context_snapshots) {
764 141 : delete context_snapshot;
765 : }
766 121 : data->created_ = true;
767 242 : return result;
768 : }
769 :
770 51 : StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) {
771 : // Create a new isolate and a new context from scratch, optionally run
772 : // a script to embed, and serialize to create a snapshot blob.
773 : StartupData result = {nullptr, 0};
774 : base::ElapsedTimer timer;
775 : timer.Start();
776 : {
777 51 : SnapshotCreator snapshot_creator;
778 : Isolate* isolate = snapshot_creator.GetIsolate();
779 : {
780 : HandleScope scope(isolate);
781 51 : Local<Context> context = Context::New(isolate);
782 91 : if (embedded_source != nullptr &&
783 40 : !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
784 0 : return result;
785 : }
786 51 : snapshot_creator.SetDefaultContext(context);
787 : }
788 : result = snapshot_creator.CreateBlob(
789 51 : SnapshotCreator::FunctionCodeHandling::kClear);
790 : }
791 :
792 51 : if (i::FLAG_profile_deserialization) {
793 : i::PrintF("Creating snapshot took %0.3f ms\n",
794 5 : timer.Elapsed().InMillisecondsF());
795 : }
796 : timer.Stop();
797 51 : return result;
798 : }
799 :
800 10 : StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,
801 : const char* warmup_source) {
802 10 : CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != nullptr);
803 10 : CHECK_NOT_NULL(warmup_source);
804 : // Use following steps to create a warmed up snapshot blob from a cold one:
805 : // - Create a new isolate from the cold snapshot.
806 : // - Create a new context to run the warmup script. This will trigger
807 : // compilation of executed functions.
808 : // - Create a new context. This context will be unpolluted.
809 : // - Serialize the isolate and the second context into a new snapshot blob.
810 : StartupData result = {nullptr, 0};
811 : base::ElapsedTimer timer;
812 : timer.Start();
813 : {
814 10 : SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
815 : Isolate* isolate = snapshot_creator.GetIsolate();
816 : {
817 : HandleScope scope(isolate);
818 10 : Local<Context> context = Context::New(isolate);
819 10 : if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
820 0 : return result;
821 : }
822 : }
823 : {
824 : HandleScope handle_scope(isolate);
825 : isolate->ContextDisposedNotification(false);
826 10 : Local<Context> context = Context::New(isolate);
827 10 : snapshot_creator.SetDefaultContext(context);
828 : }
829 : result = snapshot_creator.CreateBlob(
830 10 : SnapshotCreator::FunctionCodeHandling::kKeep);
831 : }
832 :
833 10 : if (i::FLAG_profile_deserialization) {
834 : i::PrintF("Warming up snapshot took %0.3f ms\n",
835 0 : timer.Elapsed().InMillisecondsF());
836 : }
837 : timer.Stop();
838 10 : return result;
839 : }
840 :
841 5 : void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
842 5 : v8::base::SetDcheckFunction(that);
843 5 : }
844 :
845 80349 : void V8::SetFlagsFromString(const char* str, int length) {
846 97954 : i::FlagList::SetFlagsFromString(str, length);
847 97954 : i::FlagList::EnforceFlagImplications();
848 80349 : }
849 :
850 :
851 30264 : void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
852 30264 : i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
853 30264 : }
854 :
855 : RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
856 :
857 0 : RegisteredExtension::RegisteredExtension(Extension* extension)
858 395213 : : extension_(extension) { }
859 :
860 :
861 0 : void RegisteredExtension::Register(RegisteredExtension* that) {
862 395213 : that->next_ = first_extension_;
863 395213 : first_extension_ = that;
864 0 : }
865 :
866 :
867 29500 : void RegisteredExtension::UnregisterAll() {
868 206290 : RegisteredExtension* re = first_extension_;
869 235790 : while (re != nullptr) {
870 : RegisteredExtension* next = re->next();
871 176790 : delete re;
872 : re = next;
873 : }
874 29500 : first_extension_ = nullptr;
875 29500 : }
876 :
877 :
878 395213 : void RegisterExtension(Extension* that) {
879 395213 : RegisteredExtension* extension = new RegisteredExtension(that);
880 : RegisteredExtension::Register(extension);
881 395213 : }
882 :
883 :
884 395213 : Extension::Extension(const char* name,
885 : const char* source,
886 : int dep_count,
887 : const char** deps,
888 : int source_length)
889 : : name_(name),
890 : source_length_(source_length >= 0 ?
891 : source_length :
892 395193 : (source ? static_cast<int>(strlen(source)) : 0)),
893 : source_(source, source_length_),
894 : dep_count_(dep_count),
895 : deps_(deps),
896 1185619 : auto_enable_(false) {
897 395213 : CHECK(source != nullptr || source_length_ == 0);
898 395213 : }
899 :
900 54788 : ResourceConstraints::ResourceConstraints()
901 : : max_semi_space_size_in_kb_(0),
902 : max_old_space_size_(0),
903 : stack_limit_(nullptr),
904 : code_range_size_(0),
905 54788 : max_zone_pool_size_(0) {}
906 :
907 26783 : void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
908 : uint64_t virtual_memory_limit) {
909 : set_max_semi_space_size_in_kb(
910 : i::Heap::ComputeMaxSemiSpaceSize(physical_memory));
911 : set_max_old_space_size(
912 : static_cast<int>(i::Heap::ComputeMaxOldGenerationSize(physical_memory)));
913 : set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSize);
914 :
915 26783 : if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
916 : // Reserve no more than 1/8 of the memory for the code range, but at most
917 : // kMaximalCodeRangeSize.
918 : set_code_range_size(
919 : i::Min(i::kMaximalCodeRangeSize / i::MB,
920 0 : static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
921 : }
922 26783 : }
923 :
924 109636 : void SetResourceConstraints(i::Isolate* isolate,
925 109636 : const ResourceConstraints& constraints) {
926 : size_t semi_space_size = constraints.max_semi_space_size_in_kb();
927 : int old_space_size = constraints.max_old_space_size();
928 : size_t code_range_size = constraints.code_range_size();
929 : size_t max_pool_size = constraints.max_zone_pool_size();
930 54818 : if (semi_space_size != 0 || old_space_size != 0 || code_range_size != 0) {
931 : isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
932 26808 : code_range_size);
933 : }
934 54818 : isolate->allocator()->ConfigureSegmentPool(max_pool_size);
935 :
936 54818 : if (constraints.stack_limit() != nullptr) {
937 0 : uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
938 0 : isolate->stack_guard()->SetStackLimit(limit);
939 : }
940 54818 : }
941 :
942 :
943 8137560 : i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
944 5425040 : LOG_API(isolate, Persistent, New);
945 5425040 : i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
946 : #ifdef VERIFY_HEAP
947 : if (i::FLAG_verify_heap) {
948 : (*obj)->ObjectVerify();
949 : }
950 : #endif // VERIFY_HEAP
951 2712520 : return result.location();
952 : }
953 :
954 :
955 10 : i::Object** V8::CopyPersistent(i::Object** obj) {
956 10 : i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
957 : #ifdef VERIFY_HEAP
958 : if (i::FLAG_verify_heap) {
959 : (*obj)->ObjectVerify();
960 : }
961 : #endif // VERIFY_HEAP
962 10 : return result.location();
963 : }
964 :
965 0 : void V8::RegisterExternallyReferencedObject(i::Object** object,
966 : i::Isolate* isolate) {
967 0 : isolate->heap()->RegisterExternallyReferencedObject(object);
968 0 : }
969 :
970 0 : void V8::MakeWeak(i::Object** location, void* parameter,
971 : int embedder_field_index1, int embedder_field_index2,
972 : WeakCallbackInfo<void>::Callback weak_callback) {
973 : WeakCallbackType type = WeakCallbackType::kParameter;
974 0 : if (embedder_field_index1 == 0) {
975 : if (embedder_field_index2 == 1) {
976 : type = WeakCallbackType::kInternalFields;
977 : } else {
978 : DCHECK_EQ(embedder_field_index2, -1);
979 : type = WeakCallbackType::kInternalFields;
980 : }
981 : } else {
982 : DCHECK_EQ(embedder_field_index1, -1);
983 : DCHECK_EQ(embedder_field_index2, -1);
984 : }
985 0 : i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
986 0 : }
987 :
988 53721 : void V8::MakeWeak(i::Object** location, void* parameter,
989 : WeakCallbackInfo<void>::Callback weak_callback,
990 : WeakCallbackType type) {
991 53721 : i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
992 53721 : }
993 :
994 11 : void V8::MakeWeak(i::Object*** location_addr) {
995 11 : i::GlobalHandles::MakeWeak(location_addr);
996 11 : }
997 :
998 25 : void* V8::ClearWeak(i::Object** location) {
999 25 : return i::GlobalHandles::ClearWeakness(location);
1000 : }
1001 :
1002 2709546 : void V8::DisposeGlobal(i::Object** location) {
1003 2709546 : i::GlobalHandles::Destroy(location);
1004 2709546 : }
1005 :
1006 10240 : Value* V8::Eternalize(Isolate* v8_isolate, Value* value) {
1007 20480 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1008 : i::Object* object = *Utils::OpenHandle(value);
1009 10240 : int index = -1;
1010 10240 : isolate->eternal_handles()->Create(isolate, object, &index);
1011 : return reinterpret_cast<Value*>(
1012 20480 : isolate->eternal_handles()->Get(index).location());
1013 : }
1014 :
1015 :
1016 0 : void V8::FromJustIsNothing() {
1017 : Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
1018 0 : }
1019 :
1020 :
1021 0 : void V8::ToLocalEmpty() {
1022 : Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
1023 0 : }
1024 :
1025 0 : void V8::InternalFieldOutOfBounds(int index) {
1026 : Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
1027 : "WeakCallbackInfo::GetInternalField",
1028 0 : "Internal field out of bounds.");
1029 0 : }
1030 :
1031 :
1032 : // --- H a n d l e s ---
1033 :
1034 :
1035 526669119 : HandleScope::HandleScope(Isolate* isolate) {
1036 526669311 : Initialize(isolate);
1037 526669119 : }
1038 :
1039 :
1040 608311856 : void HandleScope::Initialize(Isolate* isolate) {
1041 38292 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
1042 : // We do not want to check the correct usage of the Locker class all over the
1043 : // place, so we do it only here: Without a HandleScope, an embedder can do
1044 : // almost nothing, so it is enough to check in this central place.
1045 : // We make an exception if the serializer is enabled, which means that the
1046 : // Isolate is exclusively used to create a snapshot.
1047 : Utils::ApiCheck(
1048 608350133 : !v8::Locker::IsActive() ||
1049 608350132 : internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
1050 : internal_isolate->serializer_enabled(),
1051 : "HandleScope::HandleScope",
1052 : "Entering the V8 API without proper locking in place");
1053 : i::HandleScopeData* current = internal_isolate->handle_scope_data();
1054 608311840 : isolate_ = internal_isolate;
1055 608311840 : prev_next_ = current->next;
1056 608311840 : prev_limit_ = current->limit;
1057 608311840 : current->level++;
1058 608311840 : }
1059 :
1060 :
1061 608311681 : HandleScope::~HandleScope() {
1062 608311863 : i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
1063 608311724 : }
1064 :
1065 0 : void* HandleScope::operator new(size_t) { base::OS::Abort(); }
1066 0 : void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
1067 0 : void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1068 0 : void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1069 :
1070 6036 : int HandleScope::NumberOfHandles(Isolate* isolate) {
1071 : return i::HandleScope::NumberOfHandles(
1072 6036 : reinterpret_cast<i::Isolate*>(isolate));
1073 : }
1074 :
1075 :
1076 84164927 : i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
1077 84164916 : return i::HandleScope::CreateHandle(isolate, value);
1078 : }
1079 :
1080 :
1081 203 : i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
1082 : i::Object* value) {
1083 : DCHECK(heap_object->IsHeapObject());
1084 203 : return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
1085 : }
1086 :
1087 :
1088 81642644 : EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
1089 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1090 81642644 : escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
1091 81642626 : Initialize(v8_isolate);
1092 81642615 : }
1093 :
1094 :
1095 81599585 : i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
1096 81599590 : i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
1097 81599585 : Utils::ApiCheck((*escape_slot_)->IsTheHole(heap->isolate()),
1098 : "EscapableHandleScope::Escape", "Escape value set twice");
1099 81599589 : if (escape_value == nullptr) {
1100 10 : *escape_slot_ = heap->undefined_value();
1101 5 : return nullptr;
1102 : }
1103 81599584 : *escape_slot_ = *escape_value;
1104 81599584 : return escape_slot_;
1105 : }
1106 :
1107 0 : void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
1108 0 : void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
1109 0 : void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1110 0 : void EscapableHandleScope::operator delete[](void*, size_t) {
1111 0 : base::OS::Abort();
1112 : }
1113 :
1114 5 : SealHandleScope::SealHandleScope(Isolate* isolate)
1115 5 : : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
1116 : i::HandleScopeData* current = isolate_->handle_scope_data();
1117 5 : prev_limit_ = current->limit;
1118 5 : current->limit = current->next;
1119 5 : prev_sealed_level_ = current->sealed_level;
1120 5 : current->sealed_level = current->level;
1121 5 : }
1122 :
1123 :
1124 5 : SealHandleScope::~SealHandleScope() {
1125 5 : i::HandleScopeData* current = isolate_->handle_scope_data();
1126 : DCHECK_EQ(current->next, current->limit);
1127 5 : current->limit = prev_limit_;
1128 : DCHECK_EQ(current->level, current->sealed_level);
1129 5 : current->sealed_level = prev_sealed_level_;
1130 5 : }
1131 :
1132 0 : void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
1133 0 : void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
1134 0 : void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
1135 0 : void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1136 :
1137 1202123 : void Context::Enter() {
1138 : i::Handle<i::Context> env = Utils::OpenHandle(this);
1139 2404305 : i::Isolate* isolate = env->GetIsolate();
1140 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1141 : i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1142 1202123 : impl->EnterContext(env);
1143 : impl->SaveContext(isolate->context());
1144 : isolate->set_context(*env);
1145 1202169 : }
1146 :
1147 1187189 : void Context::Exit() {
1148 : i::Handle<i::Context> env = Utils::OpenHandle(this);
1149 1187189 : i::Isolate* isolate = env->GetIsolate();
1150 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1151 : i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1152 1187194 : if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
1153 : "v8::Context::Exit()",
1154 : "Cannot exit non-entered context")) {
1155 1187194 : return;
1156 : }
1157 : impl->LeaveContext();
1158 : isolate->set_context(impl->RestoreContext());
1159 : }
1160 :
1161 0 : Context::BackupIncumbentScope::BackupIncumbentScope(
1162 : Local<Context> backup_incumbent_context)
1163 0 : : backup_incumbent_context_(backup_incumbent_context) {
1164 : DCHECK(!backup_incumbent_context_.IsEmpty());
1165 :
1166 : i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1167 0 : i::Isolate* isolate = env->GetIsolate();
1168 0 : prev_ = isolate->top_backup_incumbent_scope();
1169 : isolate->set_top_backup_incumbent_scope(this);
1170 0 : }
1171 :
1172 0 : Context::BackupIncumbentScope::~BackupIncumbentScope() {
1173 : i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1174 : i::Isolate* isolate = env->GetIsolate();
1175 0 : isolate->set_top_backup_incumbent_scope(prev_);
1176 0 : }
1177 :
1178 : static void* DecodeSmiToAligned(i::Object* value, const char* location) {
1179 : Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
1180 : return reinterpret_cast<void*>(value);
1181 : }
1182 :
1183 :
1184 : static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
1185 : i::Smi* smi = reinterpret_cast<i::Smi*>(value);
1186 : Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
1187 : return smi;
1188 : }
1189 :
1190 :
1191 97525 : static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
1192 : int index,
1193 : bool can_grow,
1194 : const char* location) {
1195 : i::Handle<i::Context> env = Utils::OpenHandle(context);
1196 : i::Isolate* isolate = env->GetIsolate();
1197 : bool ok =
1198 97525 : Utils::ApiCheck(env->IsNativeContext(),
1199 : location,
1200 195050 : "Not a native context") &&
1201 97525 : Utils::ApiCheck(index >= 0, location, "Negative index");
1202 97525 : if (!ok) return i::Handle<i::FixedArray>();
1203 : i::Handle<i::FixedArray> data(env->embedder_data());
1204 97525 : if (index < data->length()) return data;
1205 1707 : if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
1206 0 : return i::Handle<i::FixedArray>();
1207 : }
1208 3414 : int new_size = i::Max(index, data->length() << 1) + 1;
1209 1707 : int grow_by = new_size - data->length();
1210 1707 : data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
1211 : env->set_embedder_data(*data);
1212 1707 : return data;
1213 : }
1214 :
1215 :
1216 0 : v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1217 : const char* location = "v8::Context::GetEmbedderData()";
1218 0 : i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
1219 0 : if (data.is_null()) return Local<Value>();
1220 : i::Handle<i::Object> result(data->get(index), data->GetIsolate());
1221 : return Utils::ToLocal(result);
1222 : }
1223 :
1224 :
1225 54 : void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1226 : const char* location = "v8::Context::SetEmbedderData()";
1227 54 : i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
1228 108 : if (data.is_null()) return;
1229 : i::Handle<i::Object> val = Utils::OpenHandle(*value);
1230 54 : data->set(index, *val);
1231 : DCHECK_EQ(*Utils::OpenHandle(*value),
1232 : *Utils::OpenHandle(*GetEmbedderData(index)));
1233 : }
1234 :
1235 :
1236 0 : void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1237 : const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1238 0 : i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
1239 0 : if (data.is_null()) return nullptr;
1240 0 : return DecodeSmiToAligned(data->get(index), location);
1241 : }
1242 :
1243 :
1244 97471 : void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1245 : const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1246 97471 : i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
1247 : data->set(index, EncodeAlignedAsSmi(value, location));
1248 : DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1249 97471 : }
1250 :
1251 :
1252 : // --- T e m p l a t e ---
1253 :
1254 :
1255 3399010 : static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
1256 : that->set_number_of_properties(0);
1257 3399010 : that->set_tag(i::Smi::FromInt(type));
1258 3399011 : }
1259 :
1260 :
1261 1724933 : void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1262 : v8::PropertyAttribute attribute) {
1263 : auto templ = Utils::OpenHandle(this);
1264 : i::Isolate* isolate = templ->GetIsolate();
1265 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1266 : i::HandleScope scope(isolate);
1267 : auto value_obj = Utils::OpenHandle(*value);
1268 1724933 : CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
1269 1724933 : if (value_obj->IsObjectTemplateInfo()) {
1270 183872 : templ->set_serial_number(i::Smi::kZero);
1271 183872 : if (templ->IsFunctionTemplateInfo()) {
1272 0 : i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
1273 : }
1274 : }
1275 : i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1276 : value_obj,
1277 1724933 : static_cast<i::PropertyAttributes>(attribute));
1278 1724933 : }
1279 :
1280 0 : void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1281 : v8::PropertyAttribute attribute) {
1282 : Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1283 0 : attribute);
1284 0 : }
1285 :
1286 105 : void Template::SetAccessorProperty(
1287 : v8::Local<v8::Name> name,
1288 : v8::Local<FunctionTemplate> getter,
1289 : v8::Local<FunctionTemplate> setter,
1290 : v8::PropertyAttribute attribute,
1291 : v8::AccessControl access_control) {
1292 : // TODO(verwaest): Remove |access_control|.
1293 : DCHECK_EQ(v8::DEFAULT, access_control);
1294 : auto templ = Utils::OpenHandle(this);
1295 : auto isolate = templ->GetIsolate();
1296 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1297 : DCHECK(!name.IsEmpty());
1298 : DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1299 : i::HandleScope scope(isolate);
1300 : i::ApiNatives::AddAccessorProperty(
1301 : isolate, templ, Utils::OpenHandle(*name),
1302 : Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1303 105 : static_cast<i::PropertyAttributes>(attribute));
1304 105 : }
1305 :
1306 :
1307 : // --- F u n c t i o n T e m p l a t e ---
1308 3020045 : static void InitializeFunctionTemplate(
1309 : i::Handle<i::FunctionTemplateInfo> info) {
1310 3020045 : InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
1311 : info->set_flag(0);
1312 3020046 : }
1313 :
1314 : static Local<ObjectTemplate> ObjectTemplateNew(
1315 : i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1316 : bool do_not_cache);
1317 :
1318 137004 : Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1319 : i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
1320 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1321 : i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
1322 : i_isolate);
1323 137004 : if (result->IsUndefined(i_isolate)) {
1324 : // Do not cache prototype objects.
1325 : result = Utils::OpenHandle(
1326 91812 : *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1327 45906 : Utils::OpenHandle(this)->set_prototype_template(*result);
1328 : }
1329 137004 : return ToApiHandle<ObjectTemplate>(result);
1330 : }
1331 :
1332 5 : void FunctionTemplate::SetPrototypeProviderTemplate(
1333 : Local<FunctionTemplate> prototype_provider) {
1334 : i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
1335 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1336 : i::Handle<i::Object> result = Utils::OpenHandle(*prototype_provider);
1337 : auto info = Utils::OpenHandle(this);
1338 5 : CHECK(info->prototype_template()->IsUndefined(i_isolate));
1339 5 : CHECK(info->parent_template()->IsUndefined(i_isolate));
1340 5 : info->set_prototype_provider_template(*result);
1341 5 : }
1342 :
1343 4448937 : static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
1344 : const char* func) {
1345 4448937 : Utils::ApiCheck(!info->instantiated(), func,
1346 : "FunctionTemplate already instantiated");
1347 4448936 : }
1348 :
1349 :
1350 245 : void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1351 : auto info = Utils::OpenHandle(this);
1352 245 : EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
1353 : i::Isolate* i_isolate = info->GetIsolate();
1354 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1355 245 : CHECK(info->prototype_provider_template()->IsUndefined(i_isolate));
1356 245 : info->set_parent_template(*Utils::OpenHandle(*value));
1357 245 : }
1358 :
1359 3020046 : static Local<FunctionTemplate> FunctionTemplateNew(
1360 : i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1361 : v8::Local<Signature> signature, int length, bool do_not_cache,
1362 : v8::Local<Private> cached_property_name = v8::Local<Private>()) {
1363 : i::Handle<i::Struct> struct_obj =
1364 3020046 : isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE, i::TENURED);
1365 : i::Handle<i::FunctionTemplateInfo> obj =
1366 : i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1367 3020045 : InitializeFunctionTemplate(obj);
1368 6040092 : obj->set_do_not_cache(do_not_cache);
1369 : int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber;
1370 3020046 : if (!do_not_cache) {
1371 : next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1372 : }
1373 3020046 : obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1374 3020046 : if (callback != 0) {
1375 2922039 : if (data.IsEmpty()) {
1376 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1377 : }
1378 2922039 : Utils::ToLocal(obj)->SetCallHandler(callback, data);
1379 : }
1380 : obj->set_length(length);
1381 3020046 : obj->set_undetectable(false);
1382 3020046 : obj->set_needs_access_check(false);
1383 3020046 : obj->set_accept_any_receiver(true);
1384 3020046 : if (!signature.IsEmpty()) {
1385 136805 : obj->set_signature(*Utils::OpenHandle(*signature));
1386 : }
1387 : obj->set_cached_property_name(
1388 : cached_property_name.IsEmpty()
1389 3020023 : ? isolate->heap()->the_hole_value()
1390 6040092 : : *Utils::OpenHandle(*cached_property_name));
1391 3020046 : return Utils::ToLocal(obj);
1392 : }
1393 :
1394 2988492 : Local<FunctionTemplate> FunctionTemplate::New(
1395 : Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1396 : v8::Local<Signature> signature, int length, ConstructorBehavior behavior) {
1397 2988492 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1398 : // Changes to the environment cannot be captured in the snapshot. Expect no
1399 : // function templates when the isolate is created for serialization.
1400 5976984 : LOG_API(i_isolate, FunctionTemplate, New);
1401 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1402 : auto templ =
1403 2988492 : FunctionTemplateNew(i_isolate, callback, data, signature, length, false);
1404 2988492 : if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
1405 5976984 : return templ;
1406 : }
1407 :
1408 10 : MaybeLocal<FunctionTemplate> FunctionTemplate::FromSnapshot(Isolate* isolate,
1409 : size_t index) {
1410 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1411 10 : i::FixedArray* templates = i_isolate->heap()->serialized_templates();
1412 10 : int int_index = static_cast<int>(index);
1413 10 : if (int_index < templates->length()) {
1414 : i::Object* info = templates->get(int_index);
1415 5 : if (info->IsFunctionTemplateInfo()) {
1416 : return Utils::ToLocal(i::Handle<i::FunctionTemplateInfo>(
1417 5 : i::FunctionTemplateInfo::cast(info)));
1418 : }
1419 : }
1420 5 : return Local<FunctionTemplate>();
1421 : }
1422 :
1423 23 : Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1424 : Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1425 : Local<Value> data, Local<Signature> signature, int length) {
1426 23 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1427 46 : LOG_API(i_isolate, FunctionTemplate, NewWithCache);
1428 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1429 : return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1430 46 : false, cache_property);
1431 : }
1432 :
1433 45713 : Local<Signature> Signature::New(Isolate* isolate,
1434 : Local<FunctionTemplate> receiver) {
1435 45713 : return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1436 : }
1437 :
1438 :
1439 18 : Local<AccessorSignature> AccessorSignature::New(
1440 : Isolate* isolate, Local<FunctionTemplate> receiver) {
1441 18 : return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1442 : }
1443 :
1444 :
1445 : #define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1446 : i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1447 : (obj)->setter(*foreign); \
1448 : } while (false)
1449 :
1450 2922062 : void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1451 : v8::Local<Value> data) {
1452 : auto info = Utils::OpenHandle(this);
1453 2922062 : EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
1454 : i::Isolate* isolate = info->GetIsolate();
1455 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1456 : i::HandleScope scope(isolate);
1457 : i::Handle<i::Struct> struct_obj =
1458 2922061 : isolate->factory()->NewStruct(i::TUPLE2_TYPE, i::TENURED);
1459 : i::Handle<i::CallHandlerInfo> obj =
1460 : i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1461 5844124 : SET_FIELD_WRAPPED(obj, set_callback, callback);
1462 2922062 : if (data.IsEmpty()) {
1463 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1464 : }
1465 2922062 : obj->set_data(*Utils::OpenHandle(*data));
1466 2922062 : info->set_call_code(*obj);
1467 2922062 : }
1468 :
1469 :
1470 53861 : static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1471 : i::Handle<i::AccessorInfo> obj, v8::Local<Name> name,
1472 : v8::AccessControl settings, v8::PropertyAttribute attributes,
1473 : v8::Local<AccessorSignature> signature) {
1474 53861 : obj->set_name(*Utils::OpenHandle(*name));
1475 53901 : if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1476 53877 : if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1477 53861 : obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
1478 53861 : if (!signature.IsEmpty()) {
1479 18 : obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1480 : }
1481 53861 : return obj;
1482 : }
1483 :
1484 : namespace {
1485 :
1486 : template <typename Getter, typename Setter>
1487 53861 : i::Handle<i::AccessorInfo> MakeAccessorInfo(
1488 : v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
1489 : v8::AccessControl settings, v8::PropertyAttribute attributes,
1490 : v8::Local<AccessorSignature> signature, bool is_special_data_property,
1491 : bool replace_on_access) {
1492 : i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1493 53861 : i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1494 107722 : SET_FIELD_WRAPPED(obj, set_getter, getter);
1495 : DCHECK_IMPLIES(replace_on_access,
1496 : is_special_data_property && setter == nullptr);
1497 53861 : if (is_special_data_property && setter == nullptr) {
1498 : setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1499 : }
1500 107722 : SET_FIELD_WRAPPED(obj, set_setter, setter);
1501 53861 : i::Address redirected = obj->redirected_getter();
1502 161537 : if (redirected != nullptr) SET_FIELD_WRAPPED(obj, set_js_getter, redirected);
1503 53861 : if (data.IsEmpty()) {
1504 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1505 : }
1506 53861 : obj->set_data(*Utils::OpenHandle(*data));
1507 107722 : obj->set_is_special_data_property(is_special_data_property);
1508 107722 : obj->set_replace_on_access(replace_on_access);
1509 53861 : return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1510 : }
1511 :
1512 : } // namespace
1513 :
1514 53082 : Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1515 : i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1516 106164 : if (!Utils::ApiCheck(!handle.is_null(),
1517 : "v8::FunctionTemplate::InstanceTemplate()",
1518 : "Reading from empty handle")) {
1519 0 : return Local<ObjectTemplate>();
1520 : }
1521 : i::Isolate* isolate = handle->GetIsolate();
1522 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1523 53082 : if (handle->instance_template()->IsUndefined(isolate)) {
1524 : Local<ObjectTemplate> templ =
1525 : ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1526 46712 : handle->set_instance_template(*Utils::OpenHandle(*templ));
1527 : }
1528 : i::Handle<i::ObjectTemplateInfo> result(
1529 : i::ObjectTemplateInfo::cast(handle->instance_template()));
1530 : return Utils::ToLocal(result);
1531 : }
1532 :
1533 :
1534 12 : void FunctionTemplate::SetLength(int length) {
1535 : auto info = Utils::OpenHandle(this);
1536 12 : EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
1537 : auto isolate = info->GetIsolate();
1538 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1539 : info->set_length(length);
1540 12 : }
1541 :
1542 :
1543 45733 : void FunctionTemplate::SetClassName(Local<String> name) {
1544 : auto info = Utils::OpenHandle(this);
1545 45733 : EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
1546 : auto isolate = info->GetIsolate();
1547 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1548 45733 : info->set_class_name(*Utils::OpenHandle(*name));
1549 45733 : }
1550 :
1551 :
1552 7 : void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1553 : auto info = Utils::OpenHandle(this);
1554 7 : EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1555 : auto isolate = info->GetIsolate();
1556 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1557 14 : info->set_accept_any_receiver(value);
1558 7 : }
1559 :
1560 :
1561 253 : void FunctionTemplate::SetHiddenPrototype(bool value) {
1562 : auto info = Utils::OpenHandle(this);
1563 253 : EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype");
1564 : auto isolate = info->GetIsolate();
1565 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1566 506 : info->set_hidden_prototype(value);
1567 253 : }
1568 :
1569 :
1570 1448545 : void FunctionTemplate::ReadOnlyPrototype() {
1571 : auto info = Utils::OpenHandle(this);
1572 1448545 : EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1573 : auto isolate = info->GetIsolate();
1574 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1575 1448545 : info->set_read_only_prototype(true);
1576 1448545 : }
1577 :
1578 :
1579 30378 : void FunctionTemplate::RemovePrototype() {
1580 : auto info = Utils::OpenHandle(this);
1581 30378 : EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
1582 : auto isolate = info->GetIsolate();
1583 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1584 30378 : info->set_remove_prototype(true);
1585 30378 : }
1586 :
1587 :
1588 : // --- O b j e c t T e m p l a t e ---
1589 :
1590 :
1591 238392 : Local<ObjectTemplate> ObjectTemplate::New(
1592 : Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1593 238392 : return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1594 : }
1595 :
1596 :
1597 0 : Local<ObjectTemplate> ObjectTemplate::New() {
1598 0 : return New(i::Isolate::Current(), Local<FunctionTemplate>());
1599 : }
1600 :
1601 378965 : static Local<ObjectTemplate> ObjectTemplateNew(
1602 378965 : i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1603 : bool do_not_cache) {
1604 757930 : LOG_API(isolate, ObjectTemplate, New);
1605 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1606 : i::Handle<i::Struct> struct_obj =
1607 378965 : isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE, i::TENURED);
1608 : i::Handle<i::ObjectTemplateInfo> obj =
1609 : i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1610 378965 : InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1611 : int next_serial_number = 0;
1612 378965 : if (!do_not_cache) {
1613 : next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1614 : }
1615 378965 : obj->set_serial_number(i::Smi::FromInt(next_serial_number));
1616 378965 : if (!constructor.IsEmpty())
1617 51956 : obj->set_constructor(*Utils::OpenHandle(*constructor));
1618 378965 : obj->set_data(i::Smi::kZero);
1619 378965 : return Utils::ToLocal(obj);
1620 : }
1621 :
1622 0 : Local<ObjectTemplate> ObjectTemplate::New(
1623 : i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1624 333059 : return ObjectTemplateNew(isolate, constructor, false);
1625 : }
1626 :
1627 10 : MaybeLocal<ObjectTemplate> ObjectTemplate::FromSnapshot(Isolate* isolate,
1628 : size_t index) {
1629 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1630 10 : i::FixedArray* templates = i_isolate->heap()->serialized_templates();
1631 10 : int int_index = static_cast<int>(index);
1632 10 : if (int_index < templates->length()) {
1633 : i::Object* info = templates->get(int_index);
1634 5 : if (info->IsObjectTemplateInfo()) {
1635 : return Utils::ToLocal(
1636 5 : i::Handle<i::ObjectTemplateInfo>(i::ObjectTemplateInfo::cast(info)));
1637 : }
1638 : }
1639 5 : return Local<ObjectTemplate>();
1640 : }
1641 :
1642 : // Ensure that the object template has a constructor. If no
1643 : // constructor is available we create one.
1644 143402 : static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1645 : i::Isolate* isolate,
1646 : ObjectTemplate* object_template) {
1647 : i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1648 143402 : if (!obj->IsUndefined(isolate)) {
1649 : i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1650 46932 : return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1651 : }
1652 : Local<FunctionTemplate> templ =
1653 96470 : FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1654 : i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1655 96470 : constructor->set_instance_template(*Utils::OpenHandle(object_template));
1656 96470 : Utils::OpenHandle(object_template)->set_constructor(*constructor);
1657 96470 : return constructor;
1658 : }
1659 :
1660 : template <typename Getter, typename Setter, typename Data, typename Template>
1661 46421 : static bool TemplateSetAccessor(Template* template_obj, v8::Local<Name> name,
1662 : Getter getter, Setter setter, Data data,
1663 : AccessControl settings,
1664 : PropertyAttribute attribute,
1665 : v8::Local<AccessorSignature> signature,
1666 : bool is_special_data_property,
1667 : bool replace_on_access) {
1668 : auto info = Utils::OpenHandle(template_obj);
1669 : auto isolate = info->GetIsolate();
1670 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1671 : i::HandleScope scope(isolate);
1672 : auto obj =
1673 : MakeAccessorInfo(name, getter, setter, data, settings, attribute,
1674 46421 : signature, is_special_data_property, replace_on_access);
1675 46421 : if (obj.is_null()) return false;
1676 46421 : i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
1677 46421 : return true;
1678 : }
1679 :
1680 :
1681 184 : void Template::SetNativeDataProperty(v8::Local<String> name,
1682 : AccessorGetterCallback getter,
1683 : AccessorSetterCallback setter,
1684 : v8::Local<Value> data,
1685 : PropertyAttribute attribute,
1686 : v8::Local<AccessorSignature> signature,
1687 : AccessControl settings) {
1688 : TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1689 184 : signature, true, false);
1690 184 : }
1691 :
1692 :
1693 0 : void Template::SetNativeDataProperty(v8::Local<Name> name,
1694 : AccessorNameGetterCallback getter,
1695 : AccessorNameSetterCallback setter,
1696 : v8::Local<Value> data,
1697 : PropertyAttribute attribute,
1698 : v8::Local<AccessorSignature> signature,
1699 : AccessControl settings) {
1700 : TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1701 0 : signature, true, false);
1702 0 : }
1703 :
1704 0 : void Template::SetLazyDataProperty(v8::Local<Name> name,
1705 : AccessorNameGetterCallback getter,
1706 : v8::Local<Value> data,
1707 : PropertyAttribute attribute) {
1708 : TemplateSetAccessor(
1709 : this, name, getter, static_cast<AccessorNameSetterCallback>(nullptr),
1710 0 : data, DEFAULT, attribute, Local<AccessorSignature>(), true, true);
1711 0 : }
1712 :
1713 55 : void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1714 : PropertyAttribute attribute) {
1715 : auto templ = Utils::OpenHandle(this);
1716 : i::Isolate* isolate = templ->GetIsolate();
1717 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1718 : i::HandleScope scope(isolate);
1719 : i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1720 : intrinsic,
1721 55 : static_cast<i::PropertyAttributes>(attribute));
1722 55 : }
1723 :
1724 :
1725 46153 : void ObjectTemplate::SetAccessor(v8::Local<String> name,
1726 : AccessorGetterCallback getter,
1727 : AccessorSetterCallback setter,
1728 : v8::Local<Value> data, AccessControl settings,
1729 : PropertyAttribute attribute,
1730 : v8::Local<AccessorSignature> signature) {
1731 : TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1732 92306 : signature, i::FLAG_disable_old_api_accessors, false);
1733 46153 : }
1734 :
1735 :
1736 84 : void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1737 : AccessorNameGetterCallback getter,
1738 : AccessorNameSetterCallback setter,
1739 : v8::Local<Value> data, AccessControl settings,
1740 : PropertyAttribute attribute,
1741 : v8::Local<AccessorSignature> signature) {
1742 : TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1743 84 : signature, i::FLAG_disable_old_api_accessors, false);
1744 84 : }
1745 :
1746 : template <typename Getter, typename Setter, typename Query, typename Descriptor,
1747 : typename Deleter, typename Enumerator, typename Definer>
1748 1227 : static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1749 : i::Isolate* isolate, Getter getter, Setter setter, Query query,
1750 : Descriptor descriptor, Deleter remover, Enumerator enumerator,
1751 : Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1752 : DCHECK(query == nullptr ||
1753 : descriptor == nullptr); // Either intercept attributes or descriptor.
1754 : DCHECK(query == nullptr ||
1755 : definer ==
1756 : nullptr); // Only use descriptor callback with definer callback.
1757 : auto obj = i::Handle<i::InterceptorInfo>::cast(
1758 1227 : isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE, i::TENURED));
1759 : obj->set_flags(0);
1760 :
1761 3303 : if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1762 2099 : if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1763 1641 : if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1764 1271 : if (descriptor != 0) SET_FIELD_WRAPPED(obj, set_descriptor, descriptor);
1765 1379 : if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1766 1573 : if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1767 1391 : if (definer != 0) SET_FIELD_WRAPPED(obj, set_definer, definer);
1768 1227 : obj->set_can_intercept_symbols(
1769 : !(static_cast<int>(flags) &
1770 1227 : static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1771 1227 : obj->set_all_can_read(static_cast<int>(flags) &
1772 1227 : static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1773 1227 : obj->set_non_masking(static_cast<int>(flags) &
1774 1227 : static_cast<int>(PropertyHandlerFlags::kNonMasking));
1775 :
1776 1227 : if (data.IsEmpty()) {
1777 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1778 : }
1779 1227 : obj->set_data(*Utils::OpenHandle(*data));
1780 1227 : return obj;
1781 : }
1782 :
1783 : template <typename Getter, typename Setter, typename Query, typename Descriptor,
1784 : typename Deleter, typename Enumerator, typename Definer>
1785 965 : static void ObjectTemplateSetNamedPropertyHandler(
1786 : ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1787 : Descriptor descriptor, Deleter remover, Enumerator enumerator,
1788 : Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1789 : i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1790 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1791 : i::HandleScope scope(isolate);
1792 965 : auto cons = EnsureConstructor(isolate, templ);
1793 965 : EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
1794 : auto obj = CreateInterceptorInfo(isolate, getter, setter, query, descriptor,
1795 965 : remover, enumerator, definer, data, flags);
1796 965 : cons->set_named_property_handler(*obj);
1797 965 : }
1798 :
1799 12 : void ObjectTemplate::SetNamedPropertyHandler(
1800 : NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
1801 : NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
1802 : NamedPropertyEnumeratorCallback enumerator, Local<Value> data) {
1803 : ObjectTemplateSetNamedPropertyHandler(
1804 : this, getter, setter, query, nullptr, remover, enumerator, nullptr, data,
1805 12 : PropertyHandlerFlags::kOnlyInterceptStrings);
1806 12 : }
1807 :
1808 953 : void ObjectTemplate::SetHandler(
1809 : const NamedPropertyHandlerConfiguration& config) {
1810 : ObjectTemplateSetNamedPropertyHandler(
1811 : this, config.getter, config.setter, config.query, config.descriptor,
1812 : config.deleter, config.enumerator, config.definer, config.data,
1813 953 : config.flags);
1814 953 : }
1815 :
1816 :
1817 154 : void ObjectTemplate::MarkAsUndetectable() {
1818 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1819 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1820 : i::HandleScope scope(isolate);
1821 154 : auto cons = EnsureConstructor(isolate, this);
1822 154 : EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1823 154 : cons->set_undetectable(true);
1824 154 : }
1825 :
1826 :
1827 151 : void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1828 : Local<Value> data) {
1829 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1830 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1831 : i::HandleScope scope(isolate);
1832 151 : auto cons = EnsureConstructor(isolate, this);
1833 151 : EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1834 :
1835 : i::Handle<i::Struct> struct_info =
1836 151 : isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE, i::TENURED);
1837 : i::Handle<i::AccessCheckInfo> info =
1838 : i::Handle<i::AccessCheckInfo>::cast(struct_info);
1839 :
1840 302 : SET_FIELD_WRAPPED(info, set_callback, callback);
1841 151 : info->set_named_interceptor(nullptr);
1842 151 : info->set_indexed_interceptor(nullptr);
1843 :
1844 151 : if (data.IsEmpty()) {
1845 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1846 : }
1847 151 : info->set_data(*Utils::OpenHandle(*data));
1848 :
1849 151 : cons->set_access_check_info(*info);
1850 151 : cons->set_needs_access_check(true);
1851 151 : }
1852 :
1853 36 : void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1854 : AccessCheckCallback callback,
1855 : const NamedPropertyHandlerConfiguration& named_handler,
1856 : const IndexedPropertyHandlerConfiguration& indexed_handler,
1857 : Local<Value> data) {
1858 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1859 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1860 : i::HandleScope scope(isolate);
1861 36 : auto cons = EnsureConstructor(isolate, this);
1862 : EnsureNotInstantiated(
1863 36 : cons, "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1864 :
1865 : i::Handle<i::Struct> struct_info =
1866 36 : isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE, i::TENURED);
1867 : i::Handle<i::AccessCheckInfo> info =
1868 : i::Handle<i::AccessCheckInfo>::cast(struct_info);
1869 :
1870 72 : SET_FIELD_WRAPPED(info, set_callback, callback);
1871 : auto named_interceptor = CreateInterceptorInfo(
1872 : isolate, named_handler.getter, named_handler.setter, named_handler.query,
1873 : named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1874 36 : named_handler.definer, named_handler.data, named_handler.flags);
1875 36 : info->set_named_interceptor(*named_interceptor);
1876 : auto indexed_interceptor = CreateInterceptorInfo(
1877 : isolate, indexed_handler.getter, indexed_handler.setter,
1878 : indexed_handler.query, indexed_handler.descriptor,
1879 : indexed_handler.deleter, indexed_handler.enumerator,
1880 36 : indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1881 36 : info->set_indexed_interceptor(*indexed_interceptor);
1882 :
1883 36 : if (data.IsEmpty()) {
1884 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1885 : }
1886 36 : info->set_data(*Utils::OpenHandle(*data));
1887 :
1888 36 : cons->set_access_check_info(*info);
1889 36 : cons->set_needs_access_check(true);
1890 36 : }
1891 :
1892 190 : void ObjectTemplate::SetHandler(
1893 : const IndexedPropertyHandlerConfiguration& config) {
1894 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1895 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1896 : i::HandleScope scope(isolate);
1897 190 : auto cons = EnsureConstructor(isolate, this);
1898 190 : EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
1899 : auto obj = CreateInterceptorInfo(isolate, config.getter, config.setter,
1900 : config.query, config.descriptor,
1901 : config.deleter, config.enumerator,
1902 190 : config.definer, config.data, config.flags);
1903 190 : cons->set_indexed_property_handler(*obj);
1904 190 : }
1905 :
1906 :
1907 206 : void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1908 : Local<Value> data) {
1909 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1910 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1911 : i::HandleScope scope(isolate);
1912 206 : auto cons = EnsureConstructor(isolate, this);
1913 206 : EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1914 : i::Handle<i::Struct> struct_obj =
1915 206 : isolate->factory()->NewStruct(i::TUPLE2_TYPE, i::TENURED);
1916 : i::Handle<i::CallHandlerInfo> obj =
1917 : i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1918 412 : SET_FIELD_WRAPPED(obj, set_callback, callback);
1919 206 : if (data.IsEmpty()) {
1920 : data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1921 : }
1922 206 : obj->set_data(*Utils::OpenHandle(*data));
1923 206 : cons->set_instance_call_handler(*obj);
1924 206 : }
1925 :
1926 47895 : int ObjectTemplate::InternalFieldCount() {
1927 47895 : return Utils::OpenHandle(this)->embedder_field_count();
1928 : }
1929 :
1930 93689 : void ObjectTemplate::SetInternalFieldCount(int value) {
1931 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1932 : if (!Utils::ApiCheck(i::Smi::IsValid(value),
1933 : "v8::ObjectTemplate::SetInternalFieldCount()",
1934 : "Invalid embedder field count")) {
1935 93689 : return;
1936 : }
1937 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1938 93689 : if (value > 0) {
1939 : // The embedder field count is set by the constructor function's
1940 : // construct code, so we ensure that there is a constructor
1941 : // function to do the setting.
1942 45760 : EnsureConstructor(isolate, this);
1943 : }
1944 93689 : Utils::OpenHandle(this)->set_embedder_field_count(value);
1945 : }
1946 :
1947 0 : bool ObjectTemplate::IsImmutableProto() {
1948 0 : return Utils::OpenHandle(this)->immutable_proto();
1949 : }
1950 :
1951 18 : void ObjectTemplate::SetImmutableProto() {
1952 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1953 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1954 18 : Utils::OpenHandle(this)->set_immutable_proto(true);
1955 18 : }
1956 :
1957 : // --- S c r i p t s ---
1958 :
1959 :
1960 : // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1961 : // JSFunction.
1962 :
1963 320 : ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1964 : BufferPolicy buffer_policy_)
1965 : : data(data_),
1966 : length(length_),
1967 : rejected(false),
1968 650 : buffer_policy(buffer_policy_) {}
1969 :
1970 :
1971 645 : ScriptCompiler::CachedData::~CachedData() {
1972 650 : if (buffer_policy == BufferOwned) {
1973 580 : delete[] data;
1974 : }
1975 645 : }
1976 :
1977 :
1978 0 : bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
1979 :
1980 :
1981 0 : void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
1982 :
1983 :
1984 110 : ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1985 : Encoding encoding)
1986 220 : : impl_(new i::StreamedSource(stream, encoding)) {}
1987 :
1988 :
1989 110 : ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1990 :
1991 :
1992 : const ScriptCompiler::CachedData*
1993 5 : ScriptCompiler::StreamedSource::GetCachedData() const {
1994 10 : return impl_->cached_data.get();
1995 : }
1996 :
1997 :
1998 217826 : Local<Script> UnboundScript::BindToCurrentContext() {
1999 : i::Handle<i::HeapObject> obj =
2000 : i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
2001 : i::Isolate* isolate = obj->GetIsolate();
2002 : i::Handle<i::SharedFunctionInfo> function_info(
2003 : i::SharedFunctionInfo::cast(*obj), isolate);
2004 : i::Handle<i::JSFunction> function =
2005 : isolate->factory()->NewFunctionFromSharedFunctionInfo(
2006 217826 : function_info, isolate->native_context());
2007 217826 : return ToApiHandle<Script>(function);
2008 : }
2009 :
2010 :
2011 296 : int UnboundScript::GetId() {
2012 : i::Handle<i::HeapObject> obj =
2013 : i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
2014 296 : i::Isolate* isolate = obj->GetIsolate();
2015 592 : LOG_API(isolate, UnboundScript, GetId);
2016 : i::HandleScope scope(isolate);
2017 : i::Handle<i::SharedFunctionInfo> function_info(
2018 : i::SharedFunctionInfo::cast(*obj));
2019 : i::Handle<i::Script> script(i::Script::cast(function_info->script()));
2020 296 : return script->id();
2021 : }
2022 :
2023 :
2024 5 : int UnboundScript::GetLineNumber(int code_pos) {
2025 : i::Handle<i::SharedFunctionInfo> obj =
2026 : i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2027 5 : i::Isolate* isolate = obj->GetIsolate();
2028 10 : LOG_API(isolate, UnboundScript, GetLineNumber);
2029 5 : if (obj->script()->IsScript()) {
2030 : i::Handle<i::Script> script(i::Script::cast(obj->script()));
2031 5 : return i::Script::GetLineNumber(script, code_pos);
2032 : } else {
2033 : return -1;
2034 : }
2035 : }
2036 :
2037 :
2038 5 : Local<Value> UnboundScript::GetScriptName() {
2039 : i::Handle<i::SharedFunctionInfo> obj =
2040 : i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2041 5 : i::Isolate* isolate = obj->GetIsolate();
2042 10 : LOG_API(isolate, UnboundScript, GetName);
2043 5 : if (obj->script()->IsScript()) {
2044 : i::Object* name = i::Script::cast(obj->script())->name();
2045 : return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2046 : } else {
2047 0 : return Local<String>();
2048 : }
2049 : }
2050 :
2051 :
2052 155 : Local<Value> UnboundScript::GetSourceURL() {
2053 : i::Handle<i::SharedFunctionInfo> obj =
2054 : i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2055 155 : i::Isolate* isolate = obj->GetIsolate();
2056 310 : LOG_API(isolate, UnboundScript, GetSourceURL);
2057 155 : if (obj->script()->IsScript()) {
2058 : i::Object* url = i::Script::cast(obj->script())->source_url();
2059 : return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2060 : } else {
2061 0 : return Local<String>();
2062 : }
2063 : }
2064 :
2065 :
2066 155 : Local<Value> UnboundScript::GetSourceMappingURL() {
2067 : i::Handle<i::SharedFunctionInfo> obj =
2068 : i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2069 155 : i::Isolate* isolate = obj->GetIsolate();
2070 310 : LOG_API(isolate, UnboundScript, GetSourceMappingURL);
2071 155 : if (obj->script()->IsScript()) {
2072 : i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
2073 : return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2074 : } else {
2075 0 : return Local<String>();
2076 : }
2077 : }
2078 :
2079 :
2080 228438 : MaybeLocal<Value> Script::Run(Local<Context> context) {
2081 228438 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2082 456876 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2083 913752 : ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2084 : InternalEscapableScope);
2085 228438 : i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2086 228438 : i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2087 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2088 : auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2089 :
2090 228438 : i::Handle<i::Object> receiver = isolate->global_proxy();
2091 : Local<Value> result;
2092 : has_pending_exception = !ToLocal<Value>(
2093 456876 : i::Execution::Call(isolate, fun, receiver, 0, nullptr), &result);
2094 :
2095 228438 : RETURN_ON_FAILED_EXECUTION(Value);
2096 446103 : RETURN_ESCAPED(result);
2097 : }
2098 :
2099 :
2100 0 : Local<Value> Script::Run() {
2101 : auto self = Utils::OpenHandle(this, true);
2102 : // If execution is terminating, Compile(..)->Run() requires this
2103 : // check.
2104 0 : if (self.is_null()) return Local<Value>();
2105 0 : auto context = ContextFromHeapObject(self);
2106 0 : RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
2107 : }
2108 :
2109 351 : Local<Value> ScriptOrModule::GetResourceName() {
2110 : i::Handle<i::Script> obj = Utils::OpenHandle(this);
2111 : i::Isolate* isolate = obj->GetIsolate();
2112 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2113 : i::Handle<i::Object> val(obj->name(), isolate);
2114 351 : return ToApiHandle<Value>(val);
2115 : }
2116 :
2117 5 : Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2118 : i::Handle<i::Script> obj = Utils::OpenHandle(this);
2119 : i::Isolate* isolate = obj->GetIsolate();
2120 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2121 : i::Handle<i::FixedArray> val(obj->host_defined_options(), isolate);
2122 5 : return ToApiHandle<PrimitiveArray>(val);
2123 : }
2124 :
2125 626 : Local<UnboundScript> Script::GetUnboundScript() {
2126 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
2127 : return ToApiHandle<UnboundScript>(
2128 626 : i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
2129 : }
2130 :
2131 : // static
2132 11 : Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2133 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2134 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2135 : Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2136 : "length must be equal or greater than zero");
2137 11 : i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2138 11 : return ToApiHandle<PrimitiveArray>(array);
2139 : }
2140 :
2141 5 : int PrimitiveArray::Length() const {
2142 : i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2143 : i::Isolate* isolate = array->GetIsolate();
2144 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2145 5 : return array->length();
2146 : }
2147 :
2148 31 : void PrimitiveArray::Set(int index, Local<Primitive> item) {
2149 : i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2150 : i::Isolate* isolate = array->GetIsolate();
2151 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2152 62 : Utils::ApiCheck(index >= 0 && index < array->length(),
2153 : "v8::PrimitiveArray::Set",
2154 : "index must be greater than or equal to 0 and less than the "
2155 : "array length");
2156 : i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2157 31 : array->set(index, *i_item);
2158 31 : }
2159 :
2160 117 : Local<Primitive> PrimitiveArray::Get(int index) {
2161 : i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2162 : i::Isolate* isolate = array->GetIsolate();
2163 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2164 234 : Utils::ApiCheck(index >= 0 && index < array->length(),
2165 : "v8::PrimitiveArray::Get",
2166 : "index must be greater than or equal to 0 and less than the "
2167 : "array length");
2168 : i::Handle<i::Object> i_item(array->get(index), isolate);
2169 117 : return ToApiHandle<Primitive>(i_item);
2170 : }
2171 :
2172 1065 : Module::Status Module::GetStatus() const {
2173 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2174 1065 : switch (self->status()) {
2175 : case i::Module::kUninstantiated:
2176 : case i::Module::kPreInstantiating:
2177 : return kUninstantiated;
2178 : case i::Module::kInstantiating:
2179 0 : return kInstantiating;
2180 : case i::Module::kInstantiated:
2181 210 : return kInstantiated;
2182 : case i::Module::kEvaluating:
2183 0 : return kEvaluating;
2184 : case i::Module::kEvaluated:
2185 591 : return kEvaluated;
2186 : case i::Module::kErrored:
2187 48 : return kErrored;
2188 : }
2189 0 : UNREACHABLE();
2190 : }
2191 :
2192 24 : Local<Value> Module::GetException() const {
2193 24 : Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2194 : "Module status must be kErrored");
2195 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2196 : i::Isolate* isolate = self->GetIsolate();
2197 48 : return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2198 : }
2199 :
2200 1160 : int Module::GetModuleRequestsLength() const {
2201 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2202 2320 : return self->info()->module_requests()->length();
2203 : }
2204 :
2205 815 : Local<String> Module::GetModuleRequest(int i) const {
2206 815 : CHECK_GE(i, 0);
2207 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2208 : i::Isolate* isolate = self->GetIsolate();
2209 : i::Handle<i::FixedArray> module_requests(self->info()->module_requests(),
2210 815 : isolate);
2211 815 : CHECK_LT(i, module_requests->length());
2212 815 : return ToApiHandle<String>(i::handle(module_requests->get(i), isolate));
2213 : }
2214 :
2215 12 : Location Module::GetModuleRequestLocation(int i) const {
2216 12 : CHECK_GE(i, 0);
2217 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2218 : i::HandleScope scope(isolate);
2219 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2220 : i::Handle<i::FixedArray> module_request_positions(
2221 12 : self->info()->module_request_positions(), isolate);
2222 12 : CHECK_LT(i, module_request_positions->length());
2223 : int position = i::Smi::ToInt(module_request_positions->get(i));
2224 : i::Handle<i::Script> script(self->script(), isolate);
2225 : i::Script::PositionInfo info;
2226 12 : i::Script::GetPositionInfo(script, position, &info, i::Script::WITH_OFFSET);
2227 24 : return v8::Location(info.line, info.column);
2228 : }
2229 :
2230 189 : Local<Value> Module::GetModuleNamespace() {
2231 : Utils::ApiCheck(
2232 189 : GetStatus() == kEvaluated, "v8::Module::GetModuleNamespace",
2233 : "v8::Module::GetModuleNamespace can only be used on a module with "
2234 : "status kEvaluated");
2235 189 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2236 : i::Handle<i::JSModuleNamespace> module_namespace =
2237 189 : i::Module::GetModuleNamespace(self);
2238 189 : return ToApiHandle<Value>(module_namespace);
2239 : }
2240 :
2241 3950 : int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2242 :
2243 0 : bool Module::Instantiate(Local<Context> context,
2244 : Module::ResolveCallback callback) {
2245 0 : return InstantiateModule(context, callback).FromMaybe(false);
2246 : }
2247 :
2248 1000 : Maybe<bool> Module::InstantiateModule(Local<Context> context,
2249 : Module::ResolveCallback callback) {
2250 1000 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2251 4000 : ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2252 : i::HandleScope);
2253 : has_pending_exception =
2254 1000 : !i::Module::Instantiate(Utils::OpenHandle(this), context, callback);
2255 1000 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2256 : return Just(true);
2257 : }
2258 :
2259 1156 : MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2260 1156 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2261 2312 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2262 4624 : ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2263 : InternalEscapableScope);
2264 1156 : i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2265 1156 : i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2266 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2267 :
2268 : i::Handle<i::Module> self = Utils::OpenHandle(this);
2269 : // It's an API error to call Evaluate before Instantiate.
2270 1156 : CHECK_GE(self->status(), i::Module::kInstantiated);
2271 :
2272 : Local<Value> result;
2273 1156 : has_pending_exception = !ToLocal(i::Module::Evaluate(self), &result);
2274 1156 : RETURN_ON_FAILED_EXECUTION(Value);
2275 2273 : RETURN_ESCAPED(result);
2276 : }
2277 :
2278 217851 : MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2279 : Isolate* v8_isolate, Source* source, CompileOptions options) {
2280 435690 : auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2281 435702 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2282 871386 : ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2283 : CompileUnbound, MaybeLocal<UnboundScript>(),
2284 : InternalEscapableScope);
2285 435690 : bool produce_cache = options == kProduceParserCache ||
2286 435690 : options == kProduceCodeCache ||
2287 : options == kProduceFullCodeCache;
2288 :
2289 : // Don't try to produce any kind of cache when the debugger is loaded.
2290 217845 : if (isolate->debug()->is_loaded() && produce_cache) {
2291 : options = kNoCompileOptions;
2292 : }
2293 :
2294 217845 : i::ScriptData* script_data = nullptr;
2295 217845 : if (options == kConsumeParserCache || options == kConsumeCodeCache) {
2296 : DCHECK(source->cached_data);
2297 : // ScriptData takes care of pointer-aligning the data.
2298 : script_data = new i::ScriptData(source->cached_data->data,
2299 340 : source->cached_data->length);
2300 : }
2301 :
2302 217845 : i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2303 : i::Handle<i::SharedFunctionInfo> result;
2304 : {
2305 217845 : i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
2306 652041 : TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2307 : i::MaybeHandle<i::Object> name_obj;
2308 : i::MaybeHandle<i::Object> source_map_url;
2309 : i::MaybeHandle<i::FixedArray> host_defined_options =
2310 : isolate->factory()->empty_fixed_array();
2311 : int line_offset = 0;
2312 : int column_offset = 0;
2313 217845 : if (!source->resource_name.IsEmpty()) {
2314 121285 : name_obj = Utils::OpenHandle(*(source->resource_name));
2315 : }
2316 217845 : if (!source->host_defined_options.IsEmpty()) {
2317 6 : host_defined_options = Utils::OpenHandle(*(source->host_defined_options));
2318 : }
2319 217845 : if (!source->resource_line_offset.IsEmpty()) {
2320 8905 : line_offset = static_cast<int>(source->resource_line_offset->Value());
2321 : }
2322 217845 : if (!source->resource_column_offset.IsEmpty()) {
2323 : column_offset =
2324 8859 : static_cast<int>(source->resource_column_offset->Value());
2325 : }
2326 217845 : if (!source->source_map_url.IsEmpty()) {
2327 6180 : source_map_url = Utils::OpenHandle(*(source->source_map_url));
2328 : }
2329 : i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info =
2330 : i::Compiler::GetSharedFunctionInfoForScript(
2331 : str, name_obj, line_offset, column_offset, source->resource_options,
2332 : source_map_url, isolate->native_context(), nullptr, &script_data,
2333 217845 : options, i::NOT_NATIVES_CODE, host_defined_options);
2334 217845 : has_pending_exception = !maybe_function_info.ToHandle(&result);
2335 218175 : if (has_pending_exception && script_data != nullptr) {
2336 : // This case won't happen during normal operation; we have compiled
2337 : // successfully and produced cached data, and but the second compilation
2338 : // of the same source code fails.
2339 0 : delete script_data;
2340 0 : script_data = nullptr;
2341 : }
2342 217845 : RETURN_ON_FAILED_EXECUTION(UnboundScript);
2343 :
2344 216351 : if (produce_cache && script_data != nullptr) {
2345 : // script_data now contains the data that was generated. source will
2346 : // take the ownership.
2347 : source->cached_data = new CachedData(
2348 660 : script_data->data(), script_data->length(), CachedData::BufferOwned);
2349 330 : script_data->ReleaseDataOwnership();
2350 216021 : } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
2351 680 : source->cached_data->rejected = script_data->rejected();
2352 : }
2353 217021 : delete script_data;
2354 : }
2355 434202 : RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2356 : }
2357 :
2358 :
2359 9807 : MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2360 : Isolate* v8_isolate, Source* source, CompileOptions options) {
2361 : Utils::ApiCheck(
2362 : !source->GetResourceOptions().IsModule(),
2363 : "v8::ScriptCompiler::CompileUnboundScript",
2364 : "v8::ScriptCompiler::CompileModule must be used to compile modules");
2365 9807 : return CompileUnboundInternal(v8_isolate, source, options);
2366 : }
2367 :
2368 :
2369 0 : Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
2370 : Source* source,
2371 : CompileOptions options) {
2372 : Utils::ApiCheck(
2373 : !source->GetResourceOptions().IsModule(),
2374 : "v8::ScriptCompiler::CompileUnbound",
2375 : "v8::ScriptCompiler::CompileModule must be used to compile modules");
2376 0 : RETURN_TO_LOCAL_UNCHECKED(CompileUnboundInternal(v8_isolate, source, options),
2377 : UnboundScript);
2378 : }
2379 :
2380 :
2381 206441 : MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2382 : Source* source,
2383 : CompileOptions options) {
2384 : Utils::ApiCheck(
2385 : !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2386 : "v8::ScriptCompiler::CompileModule must be used to compile modules");
2387 : auto isolate = context->GetIsolate();
2388 206441 : auto maybe = CompileUnboundInternal(isolate, source, options);
2389 : Local<UnboundScript> result;
2390 206441 : if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2391 : v8::Context::Scope scope(context);
2392 204993 : return result->BindToCurrentContext();
2393 : }
2394 :
2395 :
2396 0 : Local<Script> ScriptCompiler::Compile(
2397 : Isolate* v8_isolate,
2398 : Source* source,
2399 : CompileOptions options) {
2400 0 : auto context = v8_isolate->GetCurrentContext();
2401 0 : RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script);
2402 : }
2403 :
2404 1603 : MaybeLocal<Module> ScriptCompiler::CompileModule(Isolate* isolate,
2405 : Source* source) {
2406 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2407 :
2408 : Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2409 : "v8::ScriptCompiler::CompileModule",
2410 : "Invalid ScriptOrigin: is_module must be true");
2411 1603 : auto maybe = CompileUnboundInternal(isolate, source, kNoCompileOptions);
2412 : Local<UnboundScript> unbound;
2413 1603 : if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2414 :
2415 1561 : i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2416 1561 : return ToApiHandle<Module>(i_isolate->factory()->NewModule(shared));
2417 : }
2418 :
2419 :
2420 : class IsIdentifierHelper {
2421 : public:
2422 24 : IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
2423 :
2424 : bool Check(i::String* string) {
2425 24 : i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
2426 24 : if (cons_string == nullptr) return is_identifier_;
2427 : // We don't support cons strings here.
2428 : return false;
2429 : }
2430 24 : void VisitOneByteString(const uint8_t* chars, int length) {
2431 84 : for (int i = 0; i < length; ++i) {
2432 60 : if (first_char_) {
2433 24 : first_char_ = false;
2434 48 : is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
2435 : } else {
2436 72 : is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
2437 : }
2438 : }
2439 24 : }
2440 0 : void VisitTwoByteString(const uint16_t* chars, int length) {
2441 0 : for (int i = 0; i < length; ++i) {
2442 0 : if (first_char_) {
2443 0 : first_char_ = false;
2444 0 : is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
2445 : } else {
2446 0 : is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
2447 : }
2448 : }
2449 0 : }
2450 :
2451 : private:
2452 : bool is_identifier_;
2453 : bool first_char_;
2454 : i::UnicodeCache unicode_cache_;
2455 : DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
2456 : };
2457 :
2458 :
2459 48 : MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2460 : Local<Context> v8_context, Source* source, size_t arguments_count,
2461 : Local<String> arguments[], size_t context_extension_count,
2462 : Local<Object> context_extensions[]) {
2463 192 : PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2464 : Function);
2465 144 : TRACE_EVENT0("v8", "V8.ScriptCompiler");
2466 : i::Handle<i::String> source_string;
2467 : auto factory = isolate->factory();
2468 48 : if (arguments_count) {
2469 24 : source_string = factory->NewStringFromStaticChars("(function(");
2470 66 : for (size_t i = 0; i < arguments_count; ++i) {
2471 : IsIdentifierHelper helper;
2472 48 : if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) {
2473 6 : return Local<Function>();
2474 : }
2475 : has_pending_exception =
2476 : !factory->NewConsString(source_string,
2477 : Utils::OpenHandle(*arguments[i]))
2478 36 : .ToHandle(&source_string);
2479 18 : RETURN_ON_FAILED_EXECUTION(Function);
2480 36 : if (i + 1 == arguments_count) continue;
2481 : has_pending_exception =
2482 : !factory->NewConsString(source_string,
2483 : factory->LookupSingleCharacterStringFromCode(
2484 0 : ',')).ToHandle(&source_string);
2485 0 : RETURN_ON_FAILED_EXECUTION(Function);
2486 : }
2487 : i::Handle<i::String> brackets;
2488 18 : brackets = factory->NewStringFromStaticChars("){");
2489 : has_pending_exception = !factory->NewConsString(source_string, brackets)
2490 36 : .ToHandle(&source_string);
2491 18 : RETURN_ON_FAILED_EXECUTION(Function);
2492 : } else {
2493 24 : source_string = factory->NewStringFromStaticChars("(function(){");
2494 : }
2495 :
2496 : int scope_position = source_string->length();
2497 : has_pending_exception =
2498 : !factory->NewConsString(source_string,
2499 : Utils::OpenHandle(*source->source_string))
2500 84 : .ToHandle(&source_string);
2501 42 : RETURN_ON_FAILED_EXECUTION(Function);
2502 : // Include \n in case the source contains a line end comment.
2503 42 : auto brackets = factory->NewStringFromStaticChars("\n})");
2504 : has_pending_exception =
2505 84 : !factory->NewConsString(source_string, brackets).ToHandle(&source_string);
2506 42 : RETURN_ON_FAILED_EXECUTION(Function);
2507 :
2508 : i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2509 : i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
2510 : isolate);
2511 72 : for (size_t i = 0; i < context_extension_count; ++i) {
2512 : i::Handle<i::JSReceiver> extension =
2513 30 : Utils::OpenHandle(*context_extensions[i]);
2514 30 : if (!extension->IsJSObject()) return Local<Function>();
2515 : i::Handle<i::JSFunction> closure(context->closure(), isolate);
2516 : context = factory->NewWithContext(
2517 : closure, context,
2518 : i::ScopeInfo::CreateForWithScope(
2519 30 : isolate, context->IsNativeContext()
2520 : ? i::Handle<i::ScopeInfo>::null()
2521 : : i::Handle<i::ScopeInfo>(context->scope_info())),
2522 66 : extension);
2523 : }
2524 :
2525 : i::Handle<i::Object> name_obj;
2526 : int eval_scope_position = 0;
2527 : int eval_position = i::kNoSourcePosition;
2528 : int line_offset = 0;
2529 : int column_offset = 0;
2530 42 : if (!source->resource_name.IsEmpty()) {
2531 18 : name_obj = Utils::OpenHandle(*(source->resource_name));
2532 : }
2533 42 : if (!source->resource_line_offset.IsEmpty()) {
2534 18 : line_offset = static_cast<int>(source->resource_line_offset->Value());
2535 : }
2536 42 : if (!source->resource_column_offset.IsEmpty()) {
2537 18 : column_offset = static_cast<int>(source->resource_column_offset->Value());
2538 : }
2539 : i::Handle<i::JSFunction> fun;
2540 : has_pending_exception =
2541 : !i::Compiler::GetFunctionFromEval(
2542 : source_string, outer_info, context, i::LanguageMode::kSloppy,
2543 : i::ONLY_SINGLE_FUNCTION_LITERAL, i::kNoSourcePosition,
2544 : eval_scope_position, eval_position, line_offset,
2545 42 : column_offset - scope_position, name_obj, source->resource_options)
2546 84 : .ToHandle(&fun);
2547 42 : if (has_pending_exception) {
2548 0 : isolate->ReportPendingMessages();
2549 : }
2550 42 : RETURN_ON_FAILED_EXECUTION(Function);
2551 :
2552 : i::Handle<i::Object> result;
2553 : has_pending_exception =
2554 : !i::Execution::Call(isolate, fun,
2555 84 : Utils::OpenHandle(*v8_context->Global()), 0,
2556 84 : nullptr).ToHandle(&result);
2557 42 : RETURN_ON_FAILED_EXECUTION(Function);
2558 42 : RETURN_ESCAPED(
2559 : Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result)));
2560 : }
2561 :
2562 :
2563 0 : Local<Function> ScriptCompiler::CompileFunctionInContext(
2564 : Isolate* v8_isolate, Source* source, Local<Context> v8_context,
2565 : size_t arguments_count, Local<String> arguments[],
2566 : size_t context_extension_count, Local<Object> context_extensions[]) {
2567 0 : RETURN_TO_LOCAL_UNCHECKED(
2568 : CompileFunctionInContext(v8_context, source, arguments_count, arguments,
2569 : context_extension_count, context_extensions),
2570 : Function);
2571 : }
2572 :
2573 :
2574 110 : ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
2575 : Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
2576 110 : if (!i::FLAG_script_streaming) {
2577 : return nullptr;
2578 : }
2579 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2580 : return new i::BackgroundParsingTask(source->impl(), options,
2581 110 : i::FLAG_stack_size, isolate);
2582 : }
2583 :
2584 :
2585 105 : MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2586 : StreamedSource* v8_source,
2587 : Local<String> full_source_string,
2588 : const ScriptOrigin& origin) {
2589 420 : PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2590 315 : TRACE_EVENT0("v8", "V8.ScriptCompiler");
2591 : i::StreamedSource* source = v8_source->impl();
2592 : i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2593 105 : i::Handle<i::Script> script = isolate->factory()->NewScript(str);
2594 105 : if (!origin.ResourceName().IsEmpty()) {
2595 105 : script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
2596 : }
2597 105 : if (!origin.HostDefinedOptions().IsEmpty()) {
2598 : script->set_host_defined_options(
2599 0 : *Utils::OpenHandle(*(origin.HostDefinedOptions())));
2600 : }
2601 105 : if (!origin.ResourceLineOffset().IsEmpty()) {
2602 : script->set_line_offset(
2603 0 : static_cast<int>(origin.ResourceLineOffset()->Value()));
2604 : }
2605 105 : if (!origin.ResourceColumnOffset().IsEmpty()) {
2606 : script->set_column_offset(
2607 0 : static_cast<int>(origin.ResourceColumnOffset()->Value()));
2608 : }
2609 105 : script->set_origin_options(origin.Options());
2610 105 : if (!origin.SourceMapUrl().IsEmpty()) {
2611 : script->set_source_mapping_url(
2612 0 : *Utils::OpenHandle(*(origin.SourceMapUrl())));
2613 : }
2614 :
2615 : source->info->set_script(script);
2616 105 : if (source->info->literal() == nullptr) {
2617 10 : source->parser->ReportErrors(isolate, script);
2618 : }
2619 105 : source->parser->UpdateStatistics(isolate, script);
2620 105 : source->info->UpdateStatisticsAfterBackgroundParse(isolate);
2621 105 : source->parser->HandleSourceURLComments(isolate, script);
2622 :
2623 : i::Handle<i::SharedFunctionInfo> result;
2624 105 : if (source->info->literal() != nullptr) {
2625 : // Parsing has succeeded.
2626 : result = i::Compiler::GetSharedFunctionInfoForStreamedScript(
2627 95 : script, source->info.get(), str->length());
2628 : }
2629 : has_pending_exception = result.is_null();
2630 105 : if (has_pending_exception) isolate->ReportPendingMessages();
2631 :
2632 105 : source->Release();
2633 :
2634 105 : RETURN_ON_FAILED_EXECUTION(Script);
2635 :
2636 : Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
2637 95 : if (generic.IsEmpty()) return Local<Script>();
2638 95 : Local<Script> bound = generic->BindToCurrentContext();
2639 95 : if (bound.IsEmpty()) return Local<Script>();
2640 95 : RETURN_ESCAPED(bound);
2641 : }
2642 :
2643 :
2644 0 : Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
2645 : StreamedSource* v8_source,
2646 : Local<String> full_source_string,
2647 : const ScriptOrigin& origin) {
2648 0 : auto context = v8_isolate->GetCurrentContext();
2649 0 : RETURN_TO_LOCAL_UNCHECKED(
2650 : Compile(context, v8_source, full_source_string, origin), Script);
2651 : }
2652 :
2653 :
2654 0 : uint32_t ScriptCompiler::CachedDataVersionTag() {
2655 : return static_cast<uint32_t>(base::hash_combine(
2656 0 : internal::Version::Hash(), internal::FlagList::Hash(),
2657 0 : static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2658 : }
2659 :
2660 :
2661 92999 : MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2662 : ScriptOrigin* origin) {
2663 92999 : if (origin) {
2664 : ScriptCompiler::Source script_source(source, *origin);
2665 6170 : return ScriptCompiler::Compile(context, &script_source);
2666 : }
2667 : ScriptCompiler::Source script_source(source);
2668 86829 : return ScriptCompiler::Compile(context, &script_source);
2669 : }
2670 :
2671 :
2672 0 : Local<Script> Script::Compile(v8::Local<String> source,
2673 : v8::ScriptOrigin* origin) {
2674 : auto str = Utils::OpenHandle(*source);
2675 0 : auto context = ContextFromHeapObject(str);
2676 0 : RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script);
2677 : }
2678 :
2679 :
2680 0 : Local<Script> Script::Compile(v8::Local<String> source,
2681 : v8::Local<String> file_name) {
2682 : auto str = Utils::OpenHandle(*source);
2683 0 : auto context = ContextFromHeapObject(str);
2684 : ScriptOrigin origin(file_name);
2685 0 : return Compile(context, source, &origin).FromMaybe(Local<Script>());
2686 : }
2687 :
2688 :
2689 : // --- E x c e p t i o n s ---
2690 :
2691 :
2692 0 : v8::TryCatch::TryCatch()
2693 : : isolate_(i::Isolate::Current()),
2694 : next_(isolate_->try_catch_handler()),
2695 : is_verbose_(false),
2696 : can_continue_(true),
2697 : capture_message_(true),
2698 : rethrow_(false),
2699 0 : has_terminated_(false) {
2700 : ResetInternal();
2701 : // Special handling for simulators which have a separate JS stack.
2702 : js_stack_comparable_address_ =
2703 : reinterpret_cast<void*>(i::SimulatorStack::RegisterCTryCatch(
2704 0 : isolate_, i::GetCurrentStackPosition()));
2705 0 : isolate_->RegisterTryCatchHandler(this);
2706 0 : }
2707 :
2708 :
2709 16796015 : v8::TryCatch::TryCatch(v8::Isolate* isolate)
2710 : : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2711 : next_(isolate_->try_catch_handler()),
2712 : is_verbose_(false),
2713 : can_continue_(true),
2714 : capture_message_(true),
2715 : rethrow_(false),
2716 33592030 : has_terminated_(false) {
2717 : ResetInternal();
2718 : // Special handling for simulators which have a separate JS stack.
2719 : js_stack_comparable_address_ =
2720 : reinterpret_cast<void*>(i::SimulatorStack::RegisterCTryCatch(
2721 16796015 : isolate_, i::GetCurrentStackPosition()));
2722 16796015 : isolate_->RegisterTryCatchHandler(this);
2723 16796019 : }
2724 :
2725 :
2726 16796061 : v8::TryCatch::~TryCatch() {
2727 16796061 : if (rethrow_) {
2728 121 : v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2729 : v8::HandleScope scope(isolate);
2730 242 : v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2731 121 : if (HasCaught() && capture_message_) {
2732 : // If an exception was caught and rethrow_ is indicated, the saved
2733 : // message, script, and location need to be restored to Isolate TLS
2734 : // for reuse. capture_message_ needs to be disabled so that Throw()
2735 : // does not create a new message.
2736 121 : isolate_->thread_local_top()->rethrowing_message_ = true;
2737 121 : isolate_->RestorePendingMessageFromTryCatch(this);
2738 : }
2739 121 : isolate_->UnregisterTryCatchHandler(this);
2740 : i::SimulatorStack::UnregisterCTryCatch(isolate_);
2741 121 : reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2742 : DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2743 : } else {
2744 16807725 : if (HasCaught() && isolate_->has_scheduled_exception()) {
2745 : // If an exception was caught but is still scheduled because no API call
2746 : // promoted it, then it is canceled to prevent it from being propagated.
2747 : // Note that this will not cancel termination exceptions.
2748 143 : isolate_->CancelScheduledExceptionFromTryCatch(this);
2749 : }
2750 16795942 : isolate_->UnregisterTryCatchHandler(this);
2751 : i::SimulatorStack::UnregisterCTryCatch(isolate_);
2752 : }
2753 16796063 : }
2754 :
2755 0 : void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
2756 0 : void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
2757 0 : void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
2758 0 : void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2759 :
2760 17459482 : bool v8::TryCatch::HasCaught() const {
2761 34918971 : return !reinterpret_cast<i::Object*>(exception_)->IsTheHole(isolate_);
2762 : }
2763 :
2764 :
2765 60 : bool v8::TryCatch::CanContinue() const {
2766 60 : return can_continue_;
2767 : }
2768 :
2769 :
2770 51 : bool v8::TryCatch::HasTerminated() const {
2771 51 : return has_terminated_;
2772 : }
2773 :
2774 :
2775 121 : v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2776 121 : if (!HasCaught()) return v8::Local<v8::Value>();
2777 121 : rethrow_ = true;
2778 242 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2779 : }
2780 :
2781 :
2782 10734 : v8::Local<Value> v8::TryCatch::Exception() const {
2783 10734 : if (HasCaught()) {
2784 : // Check for out of memory exception.
2785 10734 : i::Object* exception = reinterpret_cast<i::Object*>(exception_);
2786 10734 : return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2787 : } else {
2788 0 : return v8::Local<Value>();
2789 : }
2790 : }
2791 :
2792 :
2793 7648 : MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2794 7648 : if (!HasCaught()) return v8::Local<Value>();
2795 7648 : i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
2796 7648 : if (!raw_obj->IsJSObject()) return v8::Local<Value>();
2797 5552 : PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2798 1388 : i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
2799 : i::Handle<i::String> name = isolate->factory()->stack_string();
2800 1388 : Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2801 1388 : has_pending_exception = !maybe.IsJust();
2802 1388 : RETURN_ON_FAILED_EXECUTION(Value);
2803 1388 : if (!maybe.FromJust()) return v8::Local<Value>();
2804 : Local<Value> result;
2805 : has_pending_exception =
2806 2776 : !ToLocal<Value>(i::JSReceiver::GetProperty(obj, name), &result);
2807 1388 : RETURN_ON_FAILED_EXECUTION(Value);
2808 1388 : RETURN_ESCAPED(result);
2809 : }
2810 :
2811 :
2812 0 : v8::Local<Value> v8::TryCatch::StackTrace() const {
2813 0 : auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
2814 0 : RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value);
2815 : }
2816 :
2817 :
2818 9266 : v8::Local<v8::Message> v8::TryCatch::Message() const {
2819 9266 : i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2820 : DCHECK(message->IsJSMessageObject() || message->IsTheHole(isolate_));
2821 18532 : if (HasCaught() && !message->IsTheHole(isolate_)) {
2822 9206 : return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2823 : } else {
2824 60 : return v8::Local<v8::Message>();
2825 : }
2826 : }
2827 :
2828 :
2829 738 : void v8::TryCatch::Reset() {
2830 1230 : if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2831 : // If an exception was caught but is still scheduled because no API call
2832 : // promoted it, then it is canceled to prevent it from being propagated.
2833 : // Note that this will not cancel termination exceptions.
2834 5 : isolate_->CancelScheduledExceptionFromTryCatch(this);
2835 : }
2836 : ResetInternal();
2837 738 : }
2838 :
2839 :
2840 0 : void v8::TryCatch::ResetInternal() {
2841 16796753 : i::Object* the_hole = isolate_->heap()->the_hole_value();
2842 16796753 : exception_ = the_hole;
2843 16796753 : message_obj_ = the_hole;
2844 0 : }
2845 :
2846 :
2847 941513 : void v8::TryCatch::SetVerbose(bool value) {
2848 941513 : is_verbose_ = value;
2849 941513 : }
2850 :
2851 0 : bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2852 :
2853 348743 : void v8::TryCatch::SetCaptureMessage(bool value) {
2854 348743 : capture_message_ = value;
2855 348743 : }
2856 :
2857 :
2858 : // --- M e s s a g e ---
2859 :
2860 :
2861 3117 : Local<String> Message::Get() const {
2862 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2863 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2864 3117 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2865 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
2866 3117 : i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
2867 : Local<String> result = Utils::ToLocal(raw_result);
2868 3117 : return scope.Escape(result);
2869 : }
2870 :
2871 :
2872 18592 : ScriptOrigin Message::GetScriptOrigin() const {
2873 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2874 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2875 : auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2876 : auto script_wraper = i::Handle<i::Object>(message->script(), isolate);
2877 : auto script_value = i::Handle<i::JSValue>::cast(script_wraper);
2878 : i::Handle<i::Script> script(i::Script::cast(script_value->value()));
2879 37184 : return GetScriptOriginForScript(isolate, script);
2880 : }
2881 :
2882 :
2883 0 : v8::Local<Value> Message::GetScriptResourceName() const {
2884 0 : return GetScriptOrigin().ResourceName();
2885 : }
2886 :
2887 :
2888 1370 : v8::Local<v8::StackTrace> Message::GetStackTrace() const {
2889 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2890 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2891 1370 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2892 : auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2893 : i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
2894 1370 : if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
2895 : auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
2896 : return scope.Escape(Utils::StackTraceToLocal(stackTrace));
2897 : }
2898 :
2899 :
2900 10633 : Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2901 : auto self = Utils::OpenHandle(this);
2902 : i::Isolate* isolate = self->GetIsolate();
2903 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2904 10633 : EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2905 : auto msg = i::Handle<i::JSMessageObject>::cast(self);
2906 21266 : return Just(msg->GetLineNumber());
2907 : }
2908 :
2909 :
2910 0 : int Message::GetLineNumber() const {
2911 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2912 0 : return GetLineNumber(context).FromMaybe(0);
2913 : }
2914 :
2915 :
2916 36 : int Message::GetStartPosition() const {
2917 : auto self = Utils::OpenHandle(this);
2918 36 : return self->start_position();
2919 : }
2920 :
2921 :
2922 18 : int Message::GetEndPosition() const {
2923 : auto self = Utils::OpenHandle(this);
2924 18 : return self->end_position();
2925 : }
2926 :
2927 31900 : int Message::ErrorLevel() const {
2928 : auto self = Utils::OpenHandle(this);
2929 31900 : return self->error_level();
2930 : }
2931 :
2932 9225 : Maybe<int> Message::GetStartColumn(Local<Context> context) const {
2933 : auto self = Utils::OpenHandle(this);
2934 : i::Isolate* isolate = self->GetIsolate();
2935 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2936 9225 : EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2937 : auto msg = i::Handle<i::JSMessageObject>::cast(self);
2938 18450 : return Just(msg->GetColumnNumber());
2939 : }
2940 :
2941 :
2942 0 : int Message::GetStartColumn() const {
2943 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2944 : const int default_value = kNoColumnInfo;
2945 0 : return GetStartColumn(context).FromMaybe(default_value);
2946 : }
2947 :
2948 :
2949 7655 : Maybe<int> Message::GetEndColumn(Local<Context> context) const {
2950 : auto self = Utils::OpenHandle(this);
2951 : i::Isolate* isolate = self->GetIsolate();
2952 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2953 7655 : EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2954 : auto msg = i::Handle<i::JSMessageObject>::cast(self);
2955 7655 : const int column_number = msg->GetColumnNumber();
2956 7655 : if (column_number == -1) return Just(-1);
2957 : const int start = self->start_position();
2958 : const int end = self->end_position();
2959 7655 : return Just(column_number + (end - start));
2960 : }
2961 :
2962 :
2963 0 : int Message::GetEndColumn() const {
2964 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2965 : const int default_value = kNoColumnInfo;
2966 0 : return GetEndColumn(context).FromMaybe(default_value);
2967 : }
2968 :
2969 :
2970 36 : bool Message::IsSharedCrossOrigin() const {
2971 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2972 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2973 : auto self = Utils::OpenHandle(this);
2974 : auto script = i::Handle<i::JSValue>::cast(
2975 : i::Handle<i::Object>(self->script(), isolate));
2976 : return i::Script::cast(script->value())
2977 : ->origin_options()
2978 36 : .IsSharedCrossOrigin();
2979 : }
2980 :
2981 0 : bool Message::IsOpaque() const {
2982 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2983 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2984 : auto self = Utils::OpenHandle(this);
2985 : auto script = i::Handle<i::JSValue>::cast(
2986 : i::Handle<i::Object>(self->script(), isolate));
2987 0 : return i::Script::cast(script->value())->origin_options().IsOpaque();
2988 : }
2989 :
2990 :
2991 7666 : MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
2992 : auto self = Utils::OpenHandle(this);
2993 : i::Isolate* isolate = self->GetIsolate();
2994 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2995 7666 : EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2996 : auto msg = i::Handle<i::JSMessageObject>::cast(self);
2997 22998 : RETURN_ESCAPED(Utils::ToLocal(msg->GetSourceLine()));
2998 : }
2999 :
3000 :
3001 0 : Local<String> Message::GetSourceLine() const {
3002 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3003 0 : RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String)
3004 : }
3005 :
3006 :
3007 0 : void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
3008 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3009 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3010 0 : i_isolate->PrintCurrentStackTrace(out);
3011 0 : }
3012 :
3013 :
3014 : // --- S t a c k T r a c e ---
3015 :
3016 70518 : Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
3017 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3018 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3019 70518 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3020 70518 : auto obj = handle(Utils::OpenHandle(this)->get(index), isolate);
3021 : auto info = i::Handle<i::StackFrameInfo>::cast(obj);
3022 70518 : return scope.Escape(Utils::StackFrameToLocal(info));
3023 : }
3024 :
3025 :
3026 106397 : int StackTrace::GetFrameCount() const {
3027 106397 : return Utils::OpenHandle(this)->length();
3028 : }
3029 :
3030 : namespace {
3031 0 : i::Handle<i::JSObject> NewFrameObject(i::Isolate* isolate,
3032 : i::Handle<i::StackFrameInfo> frame) {
3033 : i::Handle<i::JSObject> frame_obj =
3034 0 : isolate->factory()->NewJSObject(isolate->object_function());
3035 : i::JSObject::AddProperty(
3036 : frame_obj, handle(isolate->heap()->line_string()),
3037 0 : handle(i::Smi::FromInt(frame->line_number() + 1), isolate), i::NONE);
3038 : i::JSObject::AddProperty(
3039 : frame_obj, handle(isolate->heap()->column_string()),
3040 0 : handle(i::Smi::FromInt(frame->column_number() + 1), isolate), i::NONE);
3041 : i::JSObject::AddProperty(frame_obj,
3042 : isolate->factory()->InternalizeOneByteString(
3043 : STATIC_CHAR_VECTOR("scriptId")),
3044 : handle(i::Smi::FromInt(frame->script_id()), isolate),
3045 0 : i::NONE);
3046 : i::JSObject::AddProperty(frame_obj,
3047 : isolate->factory()->InternalizeOneByteString(
3048 : STATIC_CHAR_VECTOR("scriptName")),
3049 0 : handle(frame->script_name(), isolate), i::NONE);
3050 : i::JSObject::AddProperty(frame_obj,
3051 : isolate->factory()->InternalizeOneByteString(
3052 : STATIC_CHAR_VECTOR("scriptNameOrSourceURL")),
3053 : handle(frame->script_name_or_source_url(), isolate),
3054 0 : i::NONE);
3055 : i::JSObject::AddProperty(frame_obj,
3056 : isolate->factory()->InternalizeOneByteString(
3057 : STATIC_CHAR_VECTOR("functionName")),
3058 0 : handle(frame->function_name(), isolate), i::NONE);
3059 : i::JSObject::AddProperty(frame_obj,
3060 : isolate->factory()->InternalizeOneByteString(
3061 : STATIC_CHAR_VECTOR("isEval")),
3062 : isolate->factory()->ToBoolean(frame->is_eval()),
3063 0 : i::NONE);
3064 : i::JSObject::AddProperty(
3065 : frame_obj,
3066 : isolate->factory()->InternalizeOneByteString(
3067 : STATIC_CHAR_VECTOR("isConstructor")),
3068 0 : isolate->factory()->ToBoolean(frame->is_constructor()), i::NONE);
3069 0 : return frame_obj;
3070 : }
3071 : } // namespace
3072 :
3073 0 : Local<Array> StackTrace::AsArray() {
3074 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3075 : i::Handle<i::FixedArray> self = Utils::OpenHandle(this);
3076 : int frame_count = self->length();
3077 : i::Handle<i::FixedArray> frames =
3078 0 : isolate->factory()->NewFixedArray(frame_count);
3079 0 : for (int i = 0; i < frame_count; ++i) {
3080 : auto obj = handle(self->get(i), isolate);
3081 0 : auto frame = i::Handle<i::StackFrameInfo>::cast(obj);
3082 0 : i::Handle<i::JSObject> frame_obj = NewFrameObject(isolate, frame);
3083 0 : frames->set(i, *frame_obj);
3084 : }
3085 : return Utils::ToLocal(isolate->factory()->NewJSArrayWithElements(
3086 0 : frames, i::PACKED_ELEMENTS, frame_count));
3087 : }
3088 :
3089 :
3090 82441 : Local<StackTrace> StackTrace::CurrentStackTrace(
3091 : Isolate* isolate,
3092 : int frame_limit,
3093 : StackTraceOptions options) {
3094 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3095 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3096 : i::Handle<i::FixedArray> stackTrace =
3097 82441 : i_isolate->CaptureCurrentStackTrace(frame_limit, options);
3098 82441 : return Utils::StackTraceToLocal(stackTrace);
3099 : }
3100 :
3101 :
3102 : // --- S t a c k F r a m e ---
3103 :
3104 33216 : int StackFrame::GetLineNumber() const {
3105 : int v = Utils::OpenHandle(this)->line_number();
3106 33216 : return v ? v : Message::kNoLineNumberInfo;
3107 : }
3108 :
3109 :
3110 33181 : int StackFrame::GetColumn() const {
3111 : int v = Utils::OpenHandle(this)->column_number();
3112 33181 : return v ? v : Message::kNoLineNumberInfo;
3113 : }
3114 :
3115 :
3116 32902 : int StackFrame::GetScriptId() const {
3117 : int v = Utils::OpenHandle(this)->script_id();
3118 32902 : return v ? v : Message::kNoScriptIdInfo;
3119 : }
3120 :
3121 214 : Local<String> StackFrame::GetScriptName() const {
3122 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3123 214 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3124 : i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3125 : i::Handle<i::Object> obj(self->script_name(), isolate);
3126 : return obj->IsString()
3127 : ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
3128 548 : : Local<String>();
3129 : }
3130 :
3131 :
3132 32907 : Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3133 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3134 32907 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3135 : i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3136 : i::Handle<i::Object> obj(self->script_name_or_source_url(), isolate);
3137 : return obj->IsString()
3138 : ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
3139 98202 : : Local<String>();
3140 : }
3141 :
3142 :
3143 33145 : Local<String> StackFrame::GetFunctionName() const {
3144 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3145 33145 : EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3146 : i::Handle<i::StackFrameInfo> self = Utils::OpenHandle(this);
3147 : i::Handle<i::Object> obj(self->function_name(), isolate);
3148 : return obj->IsString()
3149 : ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
3150 99435 : : Local<String>();
3151 : }
3152 :
3153 200 : bool StackFrame::IsEval() const { return Utils::OpenHandle(this)->is_eval(); }
3154 :
3155 100 : bool StackFrame::IsConstructor() const {
3156 100 : return Utils::OpenHandle(this)->is_constructor();
3157 : }
3158 :
3159 65634 : bool StackFrame::IsWasm() const { return Utils::OpenHandle(this)->is_wasm(); }
3160 :
3161 : // --- N a t i v e W e a k M a p ---
3162 :
3163 5 : Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) {
3164 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3165 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3166 5 : i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
3167 5 : i::JSWeakCollection::Initialize(weakmap, isolate);
3168 5 : return Utils::NativeWeakMapToLocal(weakmap);
3169 : }
3170 :
3171 :
3172 20 : void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
3173 : i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3174 : i::Isolate* isolate = weak_collection->GetIsolate();
3175 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3176 : i::HandleScope scope(isolate);
3177 : i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3178 20 : i::Handle<i::Object> value = Utils::OpenHandle(*v8_value);
3179 25 : if (!key->IsJSReceiver() && !key->IsSymbol()) {
3180 : DCHECK(false);
3181 : return;
3182 : }
3183 : i::Handle<i::ObjectHashTable> table(
3184 : i::ObjectHashTable::cast(weak_collection->table()));
3185 20 : if (!table->IsKey(isolate, *key)) {
3186 : DCHECK(false);
3187 : return;
3188 : }
3189 20 : int32_t hash = key->GetOrCreateHash(isolate)->value();
3190 20 : i::JSWeakCollection::Set(weak_collection, key, value, hash);
3191 : }
3192 :
3193 60 : Local<Value> NativeWeakMap::Get(Local<Value> v8_key) const {
3194 : i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3195 : i::Isolate* isolate = weak_collection->GetIsolate();
3196 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3197 : i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3198 70 : if (!key->IsJSReceiver() && !key->IsSymbol()) {
3199 : DCHECK(false);
3200 0 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3201 : }
3202 : i::Handle<i::ObjectHashTable> table(
3203 : i::ObjectHashTable::cast(weak_collection->table()));
3204 60 : if (!table->IsKey(isolate, *key)) {
3205 : DCHECK(false);
3206 0 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3207 : }
3208 60 : i::Handle<i::Object> lookup(table->Lookup(key), isolate);
3209 60 : if (lookup->IsTheHole(isolate))
3210 10 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3211 : return Utils::ToLocal(lookup);
3212 : }
3213 :
3214 :
3215 35 : bool NativeWeakMap::Has(Local<Value> v8_key) {
3216 : i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3217 : i::Isolate* isolate = weak_collection->GetIsolate();
3218 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3219 : i::HandleScope scope(isolate);
3220 : i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3221 40 : if (!key->IsJSReceiver() && !key->IsSymbol()) {
3222 : DCHECK(false);
3223 : return false;
3224 : }
3225 : i::Handle<i::ObjectHashTable> table(
3226 : i::ObjectHashTable::cast(weak_collection->table()));
3227 35 : if (!table->IsKey(isolate, *key)) {
3228 : DCHECK(false);
3229 : return false;
3230 : }
3231 35 : i::Handle<i::Object> lookup(table->Lookup(key), isolate);
3232 35 : return !lookup->IsTheHole(isolate);
3233 : }
3234 :
3235 :
3236 5 : bool NativeWeakMap::Delete(Local<Value> v8_key) {
3237 : i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
3238 : i::Isolate* isolate = weak_collection->GetIsolate();
3239 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3240 : i::HandleScope scope(isolate);
3241 : i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
3242 5 : if (!key->IsJSReceiver() && !key->IsSymbol()) {
3243 : DCHECK(false);
3244 : return false;
3245 : }
3246 : i::Handle<i::ObjectHashTable> table(
3247 : i::ObjectHashTable::cast(weak_collection->table()));
3248 5 : if (!table->IsKey(isolate, *key)) {
3249 : DCHECK(false);
3250 : return false;
3251 : }
3252 5 : int32_t hash = key->GetOrCreateHash(isolate)->value();
3253 5 : return i::JSWeakCollection::Delete(weak_collection, key, hash);
3254 : }
3255 :
3256 :
3257 : // --- J S O N ---
3258 :
3259 0 : MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
3260 0 : PREPARE_FOR_EXECUTION(v8_isolate->GetCurrentContext(), JSON, Parse, Value);
3261 0 : i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3262 0 : i::Handle<i::String> source = i::String::Flatten(string);
3263 : i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3264 : auto maybe = source->IsSeqOneByteString()
3265 : ? i::JsonParser<true>::Parse(isolate, source, undefined)
3266 0 : : i::JsonParser<false>::Parse(isolate, source, undefined);
3267 : Local<Value> result;
3268 : has_pending_exception = !ToLocal<Value>(maybe, &result);
3269 0 : RETURN_ON_FAILED_EXECUTION(Value);
3270 0 : RETURN_ESCAPED(result);
3271 : }
3272 :
3273 70 : MaybeLocal<Value> JSON::Parse(Local<Context> context,
3274 : Local<String> json_string) {
3275 280 : PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3276 70 : i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3277 70 : i::Handle<i::String> source = i::String::Flatten(string);
3278 : i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3279 : auto maybe = source->IsSeqOneByteString()
3280 : ? i::JsonParser<true>::Parse(isolate, source, undefined)
3281 70 : : i::JsonParser<false>::Parse(isolate, source, undefined);
3282 : Local<Value> result;
3283 : has_pending_exception = !ToLocal<Value>(maybe, &result);
3284 70 : RETURN_ON_FAILED_EXECUTION(Value);
3285 69 : RETURN_ESCAPED(result);
3286 : }
3287 :
3288 0 : Local<Value> JSON::Parse(Local<String> json_string) {
3289 0 : RETURN_TO_LOCAL_UNCHECKED(Parse(Local<Context>(), json_string), Value);
3290 : }
3291 :
3292 14 : MaybeLocal<String> JSON::Stringify(Local<Context> context,
3293 : Local<Value> json_object,
3294 : Local<String> gap) {
3295 56 : PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3296 14 : i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3297 : i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3298 : i::Handle<i::String> gap_string = gap.IsEmpty()
3299 : ? isolate->factory()->empty_string()
3300 14 : : Utils::OpenHandle(*gap);
3301 : i::Handle<i::Object> maybe;
3302 : has_pending_exception = !i::JsonStringifier(isolate)
3303 28 : .Stringify(object, replacer, gap_string)
3304 28 : .ToHandle(&maybe);
3305 14 : RETURN_ON_FAILED_EXECUTION(String);
3306 : Local<String> result;
3307 : has_pending_exception =
3308 14 : !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3309 14 : RETURN_ON_FAILED_EXECUTION(String);
3310 14 : RETURN_ESCAPED(result);
3311 : }
3312 :
3313 : // --- V a l u e S e r i a l i z a t i o n ---
3314 :
3315 0 : Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3316 : Local<Object> object) {
3317 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3318 : isolate->ScheduleThrow(*isolate->factory()->NewError(
3319 : isolate->error_function(), i::MessageTemplate::kDataCloneError,
3320 0 : Utils::OpenHandle(*object)));
3321 0 : return Nothing<bool>();
3322 : }
3323 :
3324 0 : Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3325 : Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3326 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3327 : isolate->ScheduleThrow(*isolate->factory()->NewError(
3328 : isolate->error_function(), i::MessageTemplate::kDataCloneError,
3329 0 : Utils::OpenHandle(*shared_array_buffer)));
3330 0 : return Nothing<uint32_t>();
3331 : }
3332 :
3333 0 : Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3334 : Isolate* v8_isolate, Local<WasmCompiledModule> module) {
3335 0 : return Nothing<uint32_t>();
3336 : }
3337 :
3338 20 : void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3339 : size_t size,
3340 : size_t* actual_size) {
3341 20 : *actual_size = size;
3342 20 : return realloc(old_buffer, size);
3343 : }
3344 :
3345 1 : void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3346 1 : return free(buffer);
3347 : }
3348 :
3349 1008 : struct ValueSerializer::PrivateData {
3350 : explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3351 1008 : : isolate(i), serializer(i, delegate) {}
3352 : i::Isolate* isolate;
3353 : i::ValueSerializer serializer;
3354 : };
3355 :
3356 0 : ValueSerializer::ValueSerializer(Isolate* isolate)
3357 0 : : ValueSerializer(isolate, nullptr) {}
3358 :
3359 1007 : ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3360 : : private_(
3361 2015 : new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3362 :
3363 2016 : ValueSerializer::~ValueSerializer() { delete private_; }
3364 :
3365 853 : void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3366 :
3367 1 : void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3368 1 : private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3369 1 : }
3370 :
3371 852 : Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3372 : Local<Value> value) {
3373 853 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3374 3409 : ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3375 : i::HandleScope);
3376 853 : i::Handle<i::Object> object = Utils::OpenHandle(*value);
3377 853 : Maybe<bool> result = private_->serializer.WriteObject(object);
3378 852 : has_pending_exception = result.IsNothing();
3379 852 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3380 826 : return result;
3381 : }
3382 :
3383 0 : std::vector<uint8_t> ValueSerializer::ReleaseBuffer() {
3384 0 : return private_->serializer.ReleaseBuffer();
3385 : }
3386 :
3387 826 : std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3388 826 : return private_->serializer.Release();
3389 : }
3390 :
3391 22 : void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3392 : Local<ArrayBuffer> array_buffer) {
3393 : private_->serializer.TransferArrayBuffer(transfer_id,
3394 22 : Utils::OpenHandle(*array_buffer));
3395 22 : }
3396 :
3397 0 : void ValueSerializer::TransferSharedArrayBuffer(
3398 : uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3399 : private_->serializer.TransferArrayBuffer(
3400 0 : transfer_id, Utils::OpenHandle(*shared_array_buffer));
3401 0 : }
3402 :
3403 2 : void ValueSerializer::WriteUint32(uint32_t value) {
3404 2 : private_->serializer.WriteUint32(value);
3405 2 : }
3406 :
3407 2 : void ValueSerializer::WriteUint64(uint64_t value) {
3408 2 : private_->serializer.WriteUint64(value);
3409 2 : }
3410 :
3411 4 : void ValueSerializer::WriteDouble(double value) {
3412 4 : private_->serializer.WriteDouble(value);
3413 4 : }
3414 :
3415 12 : void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3416 12 : private_->serializer.WriteRawBytes(source, length);
3417 12 : }
3418 :
3419 0 : MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3420 : Isolate* v8_isolate) {
3421 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3422 : isolate->ScheduleThrow(*isolate->factory()->NewError(
3423 : isolate->error_function(),
3424 0 : i::MessageTemplate::kDataCloneDeserializationError));
3425 0 : return MaybeLocal<Object>();
3426 : }
3427 :
3428 1 : MaybeLocal<WasmCompiledModule> ValueDeserializer::Delegate::GetWasmModuleFromId(
3429 : Isolate* v8_isolate, uint32_t id) {
3430 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3431 : isolate->ScheduleThrow(*isolate->factory()->NewError(
3432 : isolate->error_function(),
3433 2 : i::MessageTemplate::kDataCloneDeserializationError));
3434 1 : return MaybeLocal<WasmCompiledModule>();
3435 : }
3436 :
3437 902 : struct ValueDeserializer::PrivateData {
3438 : PrivateData(i::Isolate* i, i::Vector<const uint8_t> data, Delegate* delegate)
3439 902 : : isolate(i), deserializer(i, data, delegate) {}
3440 : i::Isolate* isolate;
3441 : i::ValueDeserializer deserializer;
3442 : bool has_aborted = false;
3443 : bool supports_legacy_wire_format = false;
3444 : };
3445 :
3446 0 : ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3447 : size_t size)
3448 0 : : ValueDeserializer(isolate, data, size, nullptr) {}
3449 :
3450 902 : ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3451 : size_t size, Delegate* delegate) {
3452 902 : if (base::IsValueInRangeForNumericType<int>(size)) {
3453 : private_ = new PrivateData(
3454 : reinterpret_cast<i::Isolate*>(isolate),
3455 1804 : i::Vector<const uint8_t>(data, static_cast<int>(size)), delegate);
3456 : } else {
3457 : private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3458 0 : i::Vector<const uint8_t>(nullptr, 0), nullptr);
3459 0 : private_->has_aborted = true;
3460 : }
3461 902 : }
3462 :
3463 1804 : ValueDeserializer::~ValueDeserializer() { delete private_; }
3464 :
3465 902 : Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3466 902 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3467 3608 : ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3468 : Nothing<bool>(), i::HandleScope);
3469 :
3470 : // We could have aborted during the constructor.
3471 : // If so, ReadHeader is where we report it.
3472 902 : if (private_->has_aborted) {
3473 : isolate->Throw(*isolate->factory()->NewError(
3474 0 : i::MessageTemplate::kDataCloneDeserializationError));
3475 : has_pending_exception = true;
3476 0 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3477 : }
3478 :
3479 : bool read_header = false;
3480 1804 : has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3481 902 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3482 : DCHECK(read_header);
3483 :
3484 : static const uint32_t kMinimumNonLegacyVersion = 13;
3485 1023 : if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3486 123 : !private_->supports_legacy_wire_format) {
3487 : isolate->Throw(*isolate->factory()->NewError(
3488 0 : i::MessageTemplate::kDataCloneDeserializationVersionError));
3489 : has_pending_exception = true;
3490 0 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3491 : }
3492 :
3493 : return Just(true);
3494 : }
3495 :
3496 902 : void ValueDeserializer::SetSupportsLegacyWireFormat(
3497 : bool supports_legacy_wire_format) {
3498 902 : private_->supports_legacy_wire_format = supports_legacy_wire_format;
3499 902 : }
3500 :
3501 247 : void ValueDeserializer::SetExpectInlineWasm(bool expect_inline_wasm) {
3502 247 : private_->deserializer.set_expect_inline_wasm(expect_inline_wasm);
3503 247 : }
3504 :
3505 1808 : uint32_t ValueDeserializer::GetWireFormatVersion() const {
3506 1808 : CHECK(!private_->has_aborted);
3507 1808 : return private_->deserializer.GetWireFormatVersion();
3508 : }
3509 :
3510 900 : MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3511 900 : CHECK(!private_->has_aborted);
3512 3600 : PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3513 : i::MaybeHandle<i::Object> result;
3514 900 : if (GetWireFormatVersion() > 0) {
3515 888 : result = private_->deserializer.ReadObject();
3516 : } else {
3517 : result =
3518 12 : private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3519 : }
3520 : Local<Value> value;
3521 : has_pending_exception = !ToLocal(result, &value);
3522 900 : RETURN_ON_FAILED_EXECUTION(Value);
3523 874 : RETURN_ESCAPED(value);
3524 : }
3525 :
3526 22 : void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3527 : Local<ArrayBuffer> array_buffer) {
3528 22 : CHECK(!private_->has_aborted);
3529 : private_->deserializer.TransferArrayBuffer(transfer_id,
3530 22 : Utils::OpenHandle(*array_buffer));
3531 22 : }
3532 :
3533 210 : void ValueDeserializer::TransferSharedArrayBuffer(
3534 : uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3535 210 : CHECK(!private_->has_aborted);
3536 : private_->deserializer.TransferArrayBuffer(
3537 210 : transfer_id, Utils::OpenHandle(*shared_array_buffer));
3538 210 : }
3539 :
3540 2 : bool ValueDeserializer::ReadUint32(uint32_t* value) {
3541 2 : return private_->deserializer.ReadUint32(value);
3542 : }
3543 :
3544 2 : bool ValueDeserializer::ReadUint64(uint64_t* value) {
3545 2 : return private_->deserializer.ReadUint64(value);
3546 : }
3547 :
3548 4 : bool ValueDeserializer::ReadDouble(double* value) {
3549 4 : return private_->deserializer.ReadDouble(value);
3550 : }
3551 :
3552 13 : bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3553 13 : return private_->deserializer.ReadRawBytes(length, data);
3554 : }
3555 :
3556 : // --- D a t a ---
3557 :
3558 0 : bool Value::FullIsUndefined() const {
3559 : i::Handle<i::Object> object = Utils::OpenHandle(this);
3560 : bool result = false;
3561 0 : if (!object->IsSmi()) {
3562 : result = object->IsUndefined(i::HeapObject::cast(*object)->GetIsolate());
3563 : }
3564 : DCHECK_EQ(result, QuickIsUndefined());
3565 0 : return result;
3566 : }
3567 :
3568 :
3569 0 : bool Value::FullIsNull() const {
3570 : i::Handle<i::Object> object = Utils::OpenHandle(this);
3571 : bool result = false;
3572 0 : if (!object->IsSmi()) {
3573 : result = object->IsNull(i::HeapObject::cast(*object)->GetIsolate());
3574 : }
3575 : DCHECK_EQ(result, QuickIsNull());
3576 0 : return result;
3577 : }
3578 :
3579 :
3580 91339 : bool Value::IsTrue() const {
3581 : i::Handle<i::Object> object = Utils::OpenHandle(this);
3582 91339 : if (object->IsSmi()) return false;
3583 91339 : return object->IsTrue(i::HeapObject::cast(*object)->GetIsolate());
3584 : }
3585 :
3586 :
3587 118 : bool Value::IsFalse() const {
3588 : i::Handle<i::Object> object = Utils::OpenHandle(this);
3589 118 : if (object->IsSmi()) return false;
3590 118 : return object->IsFalse(i::HeapObject::cast(*object)->GetIsolate());
3591 : }
3592 :
3593 :
3594 775986 : bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3595 :
3596 :
3597 15685 : bool Value::IsName() const {
3598 15685 : return Utils::OpenHandle(this)->IsName();
3599 : }
3600 :
3601 :
3602 0 : bool Value::FullIsString() const {
3603 : bool result = Utils::OpenHandle(this)->IsString();
3604 : DCHECK_EQ(result, QuickIsString());
3605 0 : return result;
3606 : }
3607 :
3608 :
3609 2970939 : bool Value::IsSymbol() const {
3610 2970939 : return Utils::OpenHandle(this)->IsSymbol();
3611 : }
3612 :
3613 :
3614 12332343 : bool Value::IsArray() const {
3615 12332343 : return Utils::OpenHandle(this)->IsJSArray();
3616 : }
3617 :
3618 :
3619 7157809 : bool Value::IsArrayBuffer() const {
3620 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3621 7461830 : return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared();
3622 : }
3623 :
3624 :
3625 78 : bool Value::IsArrayBufferView() const {
3626 78 : return Utils::OpenHandle(this)->IsJSArrayBufferView();
3627 : }
3628 :
3629 :
3630 6878653 : bool Value::IsTypedArray() const {
3631 6878653 : return Utils::OpenHandle(this)->IsJSTypedArray();
3632 : }
3633 :
3634 :
3635 : #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
3636 : bool Value::Is##Type##Array() const { \
3637 : i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3638 : return obj->IsJSTypedArray() && \
3639 : i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \
3640 : }
3641 :
3642 :
3643 216 : TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3644 :
3645 : #undef VALUE_IS_TYPED_ARRAY
3646 :
3647 :
3648 6852936 : bool Value::IsDataView() const {
3649 6852936 : return Utils::OpenHandle(this)->IsJSDataView();
3650 : }
3651 :
3652 :
3653 6852979 : bool Value::IsSharedArrayBuffer() const {
3654 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3655 6853030 : return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared();
3656 : }
3657 :
3658 :
3659 43527792 : bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3660 :
3661 :
3662 18602718 : bool Value::IsNumber() const {
3663 18602718 : return Utils::OpenHandle(this)->IsNumber();
3664 : }
3665 :
3666 :
3667 13712458 : bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3668 :
3669 62 : bool Value::IsWebAssemblyCompiledModule() const {
3670 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3671 62 : if (!obj->IsJSObject()) return false;
3672 : i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
3673 124 : return js_obj->GetIsolate()->native_context()->wasm_module_constructor() ==
3674 62 : js_obj->map()->GetConstructor();
3675 : }
3676 :
3677 : #define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
3678 : bool Value::Is##Type() const { \
3679 : i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3680 : if (!obj->IsHeapObject()) return false; \
3681 : i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \
3682 : return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
3683 : }
3684 :
3685 20698428 : VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
3686 3159 : VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
3687 3027 : VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
3688 3075 : VALUE_IS_SPECIFIC_TYPE(StringObject, String)
3689 2964 : VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
3690 20633325 : VALUE_IS_SPECIFIC_TYPE(Date, Date)
3691 20835471 : VALUE_IS_SPECIFIC_TYPE(Map, Map)
3692 20834040 : VALUE_IS_SPECIFIC_TYPE(Set, Set)
3693 20633025 : VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
3694 20631585 : VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
3695 :
3696 : #undef VALUE_IS_SPECIFIC_TYPE
3697 :
3698 :
3699 28053479 : bool Value::IsBoolean() const {
3700 28053479 : return Utils::OpenHandle(this)->IsBoolean();
3701 : }
3702 :
3703 :
3704 17 : bool Value::IsExternal() const {
3705 17 : return Utils::OpenHandle(this)->IsExternal();
3706 : }
3707 :
3708 :
3709 525787 : bool Value::IsInt32() const {
3710 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3711 525787 : if (obj->IsSmi()) return true;
3712 36 : if (obj->IsNumber()) {
3713 36 : return i::IsInt32Double(obj->Number());
3714 : }
3715 : return false;
3716 : }
3717 :
3718 :
3719 219 : bool Value::IsUint32() const {
3720 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3721 325 : if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3722 113 : if (obj->IsNumber()) {
3723 : double value = obj->Number();
3724 107 : return !i::IsMinusZero(value) &&
3725 95 : value >= 0 &&
3726 202 : value <= i::kMaxUInt32 &&
3727 113 : value == i::FastUI2D(i::FastD2UI(value));
3728 : }
3729 : return false;
3730 : }
3731 :
3732 :
3733 6875705 : bool Value::IsNativeError() const {
3734 6875705 : return Utils::OpenHandle(this)->IsJSError();
3735 : }
3736 :
3737 :
3738 6877750 : bool Value::IsRegExp() const {
3739 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3740 6877750 : return obj->IsJSRegExp();
3741 : }
3742 :
3743 12 : bool Value::IsAsyncFunction() const {
3744 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3745 12 : if (!obj->IsJSFunction()) return false;
3746 : i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3747 12 : return i::IsAsyncFunction(func->shared()->kind());
3748 : }
3749 :
3750 60 : bool Value::IsGeneratorFunction() const {
3751 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3752 60 : if (!obj->IsJSFunction()) return false;
3753 : i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3754 43 : return i::IsGeneratorFunction(func->shared()->kind());
3755 : }
3756 :
3757 :
3758 6943627 : bool Value::IsGeneratorObject() const {
3759 6943627 : return Utils::OpenHandle(this)->IsJSGeneratorObject();
3760 : }
3761 :
3762 :
3763 6877012 : bool Value::IsMapIterator() const {
3764 6877012 : return Utils::OpenHandle(this)->IsJSMapIterator();
3765 : }
3766 :
3767 :
3768 6876516 : bool Value::IsSetIterator() const {
3769 6876516 : return Utils::OpenHandle(this)->IsJSSetIterator();
3770 : }
3771 :
3772 13715154 : bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3773 :
3774 39152576 : MaybeLocal<String> Value::ToString(Local<Context> context) const {
3775 : auto obj = Utils::OpenHandle(this);
3776 39152575 : if (obj->IsString()) return ToApiHandle<String>(obj);
3777 117420 : PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3778 : Local<String> result;
3779 : has_pending_exception =
3780 29355 : !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3781 29355 : RETURN_ON_FAILED_EXECUTION(String);
3782 29254 : RETURN_ESCAPED(result);
3783 : }
3784 :
3785 :
3786 0 : Local<String> Value::ToString(Isolate* isolate) const {
3787 0 : RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String);
3788 : }
3789 :
3790 :
3791 15 : MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3792 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
3793 15 : if (obj->IsString()) return ToApiHandle<String>(obj);
3794 60 : PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3795 : Local<String> result =
3796 15 : Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3797 : RETURN_ON_FAILED_EXECUTION(String);
3798 15 : RETURN_ESCAPED(result);
3799 : }
3800 :
3801 :
3802 0 : Local<String> Value::ToDetailString(Isolate* isolate) const {
3803 0 : RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()),
3804 : String);
3805 : }
3806 :
3807 :
3808 273 : MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3809 : auto obj = Utils::OpenHandle(this);
3810 273 : if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3811 24 : PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3812 : Local<Object> result;
3813 : has_pending_exception =
3814 6 : !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3815 6 : RETURN_ON_FAILED_EXECUTION(Object);
3816 0 : RETURN_ESCAPED(result);
3817 : }
3818 :
3819 :
3820 0 : Local<v8::Object> Value::ToObject(Isolate* isolate) const {
3821 0 : RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object);
3822 : }
3823 :
3824 :
3825 52 : MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const {
3826 : auto obj = Utils::OpenHandle(this);
3827 52 : if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj);
3828 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3829 20 : auto val = isolate->factory()->ToBoolean(obj->BooleanValue());
3830 20 : return ToApiHandle<Boolean>(val);
3831 : }
3832 :
3833 :
3834 0 : Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3835 0 : return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked();
3836 : }
3837 :
3838 :
3839 119 : MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3840 : auto obj = Utils::OpenHandle(this);
3841 119 : if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3842 24 : PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3843 : Local<Number> result;
3844 6 : has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
3845 6 : RETURN_ON_FAILED_EXECUTION(Number);
3846 0 : RETURN_ESCAPED(result);
3847 : }
3848 :
3849 :
3850 0 : Local<Number> Value::ToNumber(Isolate* isolate) const {
3851 0 : RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number);
3852 : }
3853 :
3854 :
3855 6 : MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3856 : auto obj = Utils::OpenHandle(this);
3857 6 : if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3858 24 : PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3859 : Local<Integer> result;
3860 : has_pending_exception =
3861 : !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3862 6 : RETURN_ON_FAILED_EXECUTION(Integer);
3863 0 : RETURN_ESCAPED(result);
3864 : }
3865 :
3866 :
3867 0 : Local<Integer> Value::ToInteger(Isolate* isolate) const {
3868 0 : RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer);
3869 : }
3870 :
3871 :
3872 126 : MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3873 : auto obj = Utils::OpenHandle(this);
3874 126 : if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3875 : Local<Int32> result;
3876 164 : PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3877 : has_pending_exception =
3878 : !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3879 41 : RETURN_ON_FAILED_EXECUTION(Int32);
3880 35 : RETURN_ESCAPED(result);
3881 : }
3882 :
3883 :
3884 0 : Local<Int32> Value::ToInt32(Isolate* isolate) const {
3885 0 : RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32);
3886 : }
3887 :
3888 :
3889 48 : MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3890 : auto obj = Utils::OpenHandle(this);
3891 48 : if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3892 : Local<Uint32> result;
3893 144 : PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3894 : has_pending_exception =
3895 36 : !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3896 36 : RETURN_ON_FAILED_EXECUTION(Uint32);
3897 30 : RETURN_ESCAPED(result);
3898 : }
3899 :
3900 :
3901 0 : Local<Uint32> Value::ToUint32(Isolate* isolate) const {
3902 0 : RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32);
3903 : }
3904 :
3905 :
3906 0 : void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3907 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3908 0 : Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3909 : "v8::internal::Internals::CheckInitialized",
3910 : "Isolate is not initialized or V8 has died");
3911 0 : }
3912 :
3913 :
3914 0 : void External::CheckCast(v8::Value* that) {
3915 : Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(), "v8::External::Cast",
3916 : "Could not convert to external");
3917 0 : }
3918 :
3919 :
3920 0 : void v8::Object::CheckCast(Value* that) {
3921 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3922 : Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3923 : "Could not convert to object");
3924 0 : }
3925 :
3926 :
3927 0 : void v8::Function::CheckCast(Value* that) {
3928 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3929 : Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3930 : "Could not convert to function");
3931 0 : }
3932 :
3933 :
3934 0 : void v8::Boolean::CheckCast(v8::Value* that) {
3935 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3936 : Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3937 : "Could not convert to boolean");
3938 0 : }
3939 :
3940 :
3941 0 : void v8::Name::CheckCast(v8::Value* that) {
3942 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3943 : Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Could not convert to name");
3944 0 : }
3945 :
3946 :
3947 0 : void v8::String::CheckCast(v8::Value* that) {
3948 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3949 : Utils::ApiCheck(obj->IsString(), "v8::String::Cast",
3950 : "Could not convert to string");
3951 0 : }
3952 :
3953 :
3954 0 : void v8::Symbol::CheckCast(v8::Value* that) {
3955 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3956 : Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast",
3957 : "Could not convert to symbol");
3958 0 : }
3959 :
3960 :
3961 0 : void v8::Number::CheckCast(v8::Value* that) {
3962 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3963 : Utils::ApiCheck(obj->IsNumber(),
3964 : "v8::Number::Cast()",
3965 : "Could not convert to number");
3966 0 : }
3967 :
3968 :
3969 0 : void v8::Integer::CheckCast(v8::Value* that) {
3970 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3971 : Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3972 : "Could not convert to number");
3973 0 : }
3974 :
3975 :
3976 0 : void v8::Int32::CheckCast(v8::Value* that) {
3977 0 : Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast",
3978 : "Could not convert to 32-bit signed integer");
3979 0 : }
3980 :
3981 :
3982 0 : void v8::Uint32::CheckCast(v8::Value* that) {
3983 0 : Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast",
3984 : "Could not convert to 32-bit unsigned integer");
3985 0 : }
3986 :
3987 :
3988 0 : void v8::Array::CheckCast(Value* that) {
3989 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3990 : Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast",
3991 : "Could not convert to array");
3992 0 : }
3993 :
3994 :
3995 0 : void v8::Map::CheckCast(Value* that) {
3996 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
3997 : Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Could not convert to Map");
3998 0 : }
3999 :
4000 :
4001 0 : void v8::Set::CheckCast(Value* that) {
4002 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4003 : Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Could not convert to Set");
4004 0 : }
4005 :
4006 :
4007 0 : void v8::Promise::CheckCast(Value* that) {
4008 0 : Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
4009 : "Could not convert to promise");
4010 0 : }
4011 :
4012 :
4013 0 : void v8::Promise::Resolver::CheckCast(Value* that) {
4014 0 : Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
4015 : "Could not convert to promise resolver");
4016 0 : }
4017 :
4018 :
4019 0 : void v8::Proxy::CheckCast(Value* that) {
4020 0 : Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast",
4021 : "Could not convert to proxy");
4022 0 : }
4023 :
4024 0 : void v8::WasmCompiledModule::CheckCast(Value* that) {
4025 0 : Utils::ApiCheck(that->IsWebAssemblyCompiledModule(),
4026 : "v8::WasmCompiledModule::Cast",
4027 : "Could not convert to wasm compiled module");
4028 0 : }
4029 :
4030 0 : void v8::ArrayBuffer::CheckCast(Value* that) {
4031 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4032 : Utils::ApiCheck(
4033 0 : obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(),
4034 : "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer");
4035 0 : }
4036 :
4037 :
4038 0 : void v8::ArrayBufferView::CheckCast(Value* that) {
4039 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4040 : Utils::ApiCheck(obj->IsJSArrayBufferView(),
4041 : "v8::ArrayBufferView::Cast()",
4042 : "Could not convert to ArrayBufferView");
4043 0 : }
4044 :
4045 :
4046 0 : void v8::TypedArray::CheckCast(Value* that) {
4047 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4048 : Utils::ApiCheck(obj->IsJSTypedArray(),
4049 : "v8::TypedArray::Cast()",
4050 : "Could not convert to TypedArray");
4051 0 : }
4052 :
4053 :
4054 : #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
4055 : void v8::Type##Array::CheckCast(Value* that) { \
4056 : i::Handle<i::Object> obj = Utils::OpenHandle(that); \
4057 : Utils::ApiCheck( \
4058 : obj->IsJSTypedArray() && \
4059 : i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \
4060 : "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \
4061 : }
4062 :
4063 :
4064 0 : TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
4065 :
4066 : #undef CHECK_TYPED_ARRAY_CAST
4067 :
4068 :
4069 0 : void v8::DataView::CheckCast(Value* that) {
4070 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4071 : Utils::ApiCheck(obj->IsJSDataView(),
4072 : "v8::DataView::Cast()",
4073 : "Could not convert to DataView");
4074 0 : }
4075 :
4076 :
4077 0 : void v8::SharedArrayBuffer::CheckCast(Value* that) {
4078 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4079 : Utils::ApiCheck(
4080 0 : obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(),
4081 : "v8::SharedArrayBuffer::Cast()",
4082 : "Could not convert to SharedArrayBuffer");
4083 0 : }
4084 :
4085 :
4086 0 : void v8::Date::CheckCast(v8::Value* that) {
4087 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4088 : i::Isolate* isolate = nullptr;
4089 0 : if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
4090 0 : Utils::ApiCheck(isolate != nullptr &&
4091 0 : obj->HasSpecificClassOf(isolate->heap()->Date_string()),
4092 : "v8::Date::Cast()", "Could not convert to date");
4093 0 : }
4094 :
4095 :
4096 0 : void v8::StringObject::CheckCast(v8::Value* that) {
4097 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4098 : i::Isolate* isolate = nullptr;
4099 0 : if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
4100 0 : Utils::ApiCheck(isolate != nullptr &&
4101 0 : obj->HasSpecificClassOf(isolate->heap()->String_string()),
4102 : "v8::StringObject::Cast()",
4103 : "Could not convert to StringObject");
4104 0 : }
4105 :
4106 :
4107 0 : void v8::SymbolObject::CheckCast(v8::Value* that) {
4108 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4109 : i::Isolate* isolate = nullptr;
4110 0 : if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
4111 0 : Utils::ApiCheck(isolate != nullptr &&
4112 0 : obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
4113 : "v8::SymbolObject::Cast()",
4114 : "Could not convert to SymbolObject");
4115 0 : }
4116 :
4117 :
4118 0 : void v8::NumberObject::CheckCast(v8::Value* that) {
4119 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4120 : i::Isolate* isolate = nullptr;
4121 0 : if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
4122 0 : Utils::ApiCheck(isolate != nullptr &&
4123 0 : obj->HasSpecificClassOf(isolate->heap()->Number_string()),
4124 : "v8::NumberObject::Cast()",
4125 : "Could not convert to NumberObject");
4126 0 : }
4127 :
4128 :
4129 0 : void v8::BooleanObject::CheckCast(v8::Value* that) {
4130 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4131 : i::Isolate* isolate = nullptr;
4132 0 : if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
4133 : Utils::ApiCheck(
4134 0 : isolate != nullptr &&
4135 0 : obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
4136 : "v8::BooleanObject::Cast()", "Could not convert to BooleanObject");
4137 0 : }
4138 :
4139 :
4140 0 : void v8::RegExp::CheckCast(v8::Value* that) {
4141 : i::Handle<i::Object> obj = Utils::OpenHandle(that);
4142 : Utils::ApiCheck(obj->IsJSRegExp(),
4143 : "v8::RegExp::Cast()",
4144 : "Could not convert to regular expression");
4145 0 : }
4146 :
4147 :
4148 13786 : Maybe<bool> Value::BooleanValue(Local<Context> context) const {
4149 27572 : return Just(Utils::OpenHandle(this)->BooleanValue());
4150 : }
4151 :
4152 :
4153 0 : bool Value::BooleanValue() const {
4154 0 : return Utils::OpenHandle(this)->BooleanValue();
4155 : }
4156 :
4157 :
4158 8459 : Maybe<double> Value::NumberValue(Local<Context> context) const {
4159 : auto obj = Utils::OpenHandle(this);
4160 8459 : if (obj->IsNumber()) return Just(obj->Number());
4161 187 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4162 748 : ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
4163 : i::HandleScope);
4164 : i::Handle<i::Object> num;
4165 374 : has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
4166 187 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
4167 : return Just(num->Number());
4168 : }
4169 :
4170 :
4171 0 : double Value::NumberValue() const {
4172 : auto obj = Utils::OpenHandle(this);
4173 0 : if (obj->IsNumber()) return obj->Number();
4174 : return NumberValue(ContextFromHeapObject(obj))
4175 0 : .FromMaybe(std::numeric_limits<double>::quiet_NaN());
4176 : }
4177 :
4178 :
4179 23898 : Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
4180 : auto obj = Utils::OpenHandle(this);
4181 23898 : if (obj->IsNumber()) {
4182 22796 : return Just(NumberToInt64(*obj));
4183 : }
4184 1102 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4185 4408 : ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
4186 : i::HandleScope);
4187 : i::Handle<i::Object> num;
4188 : has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
4189 1102 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
4190 976 : return Just(NumberToInt64(*num));
4191 : }
4192 :
4193 :
4194 0 : int64_t Value::IntegerValue() const {
4195 : auto obj = Utils::OpenHandle(this);
4196 0 : if (obj->IsNumber()) {
4197 0 : if (obj->IsSmi()) {
4198 0 : return i::Smi::ToInt(*obj);
4199 : } else {
4200 0 : return static_cast<int64_t>(obj->Number());
4201 : }
4202 : }
4203 0 : return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
4204 : }
4205 :
4206 :
4207 541715 : Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
4208 : auto obj = Utils::OpenHandle(this);
4209 1083406 : if (obj->IsNumber()) return Just(NumberToInt32(*obj));
4210 24 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4211 96 : ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
4212 : i::HandleScope);
4213 : i::Handle<i::Object> num;
4214 : has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
4215 24 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
4216 : return Just(num->IsSmi() ? i::Smi::ToInt(*num)
4217 18 : : static_cast<int32_t>(num->Number()));
4218 : }
4219 :
4220 :
4221 0 : int32_t Value::Int32Value() const {
4222 : auto obj = Utils::OpenHandle(this);
4223 0 : if (obj->IsNumber()) return NumberToInt32(*obj);
4224 0 : return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
4225 : }
4226 :
4227 :
4228 212 : Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
4229 : auto obj = Utils::OpenHandle(this);
4230 418 : if (obj->IsNumber()) return Just(NumberToUint32(*obj));
4231 6 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4232 24 : ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4233 : i::HandleScope);
4234 : i::Handle<i::Object> num;
4235 12 : has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4236 6 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4237 : return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4238 0 : : static_cast<uint32_t>(num->Number()));
4239 : }
4240 :
4241 :
4242 0 : uint32_t Value::Uint32Value() const {
4243 : auto obj = Utils::OpenHandle(this);
4244 0 : if (obj->IsNumber()) return NumberToUint32(*obj);
4245 0 : return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
4246 : }
4247 :
4248 :
4249 42 : MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4250 : auto self = Utils::OpenHandle(this);
4251 42 : if (self->IsSmi()) {
4252 12 : if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4253 6 : return Local<Uint32>();
4254 : }
4255 120 : PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4256 : i::Handle<i::Object> string_obj;
4257 : has_pending_exception =
4258 60 : !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4259 30 : RETURN_ON_FAILED_EXECUTION(Uint32);
4260 : i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4261 : uint32_t index;
4262 30 : if (str->AsArrayIndex(&index)) {
4263 : i::Handle<i::Object> value;
4264 12 : if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4265 : value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4266 : } else {
4267 6 : value = isolate->factory()->NewNumber(index);
4268 : }
4269 12 : RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4270 : }
4271 18 : return Local<Uint32>();
4272 : }
4273 :
4274 :
4275 0 : Local<Uint32> Value::ToArrayIndex() const {
4276 : auto self = Utils::OpenHandle(this);
4277 0 : if (self->IsSmi()) {
4278 0 : if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4279 0 : return Local<Uint32>();
4280 : }
4281 0 : auto context = ContextFromHeapObject(self);
4282 0 : RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32);
4283 : }
4284 :
4285 :
4286 169767 : Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4287 169767 : auto self = Utils::OpenHandle(this);
4288 169767 : auto other = Utils::OpenHandle(*that);
4289 169767 : return i::Object::Equals(self, other);
4290 : }
4291 :
4292 :
4293 0 : bool Value::Equals(Local<Value> that) const {
4294 0 : auto self = Utils::OpenHandle(this);
4295 0 : auto other = Utils::OpenHandle(*that);
4296 0 : if (self->IsSmi() && other->IsSmi()) {
4297 0 : return self->Number() == other->Number();
4298 : }
4299 0 : if (self->IsJSObject() && other->IsJSObject()) {
4300 0 : return *self == *other;
4301 : }
4302 0 : auto heap_object = self->IsSmi() ? other : self;
4303 : auto context = ContextFromHeapObject(heap_object);
4304 : return Equals(context, that).FromMaybe(false);
4305 : }
4306 :
4307 :
4308 604 : bool Value::StrictEquals(Local<Value> that) const {
4309 : auto self = Utils::OpenHandle(this);
4310 : auto other = Utils::OpenHandle(*that);
4311 604 : return self->StrictEquals(*other);
4312 : }
4313 :
4314 :
4315 309 : bool Value::SameValue(Local<Value> that) const {
4316 : auto self = Utils::OpenHandle(this);
4317 : auto other = Utils::OpenHandle(*that);
4318 309 : return self->SameValue(*other);
4319 : }
4320 :
4321 50 : Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4322 50 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4323 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4324 100 : LOG_API(isolate, Value, TypeOf);
4325 100 : return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4326 : }
4327 :
4328 72 : Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4329 : v8::Local<v8::Object> object) {
4330 72 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4331 288 : ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4332 : i::HandleScope);
4333 72 : auto left = Utils::OpenHandle(this);
4334 : auto right = Utils::OpenHandle(*object);
4335 : i::Handle<i::Object> result;
4336 : has_pending_exception =
4337 144 : !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4338 72 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4339 : return Just(result->IsTrue(isolate));
4340 : }
4341 :
4342 180361 : Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4343 : v8::Local<Value> key, v8::Local<Value> value) {
4344 180361 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4345 721444 : ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4346 : auto self = Utils::OpenHandle(this);
4347 180361 : auto key_obj = Utils::OpenHandle(*key);
4348 180361 : auto value_obj = Utils::OpenHandle(*value);
4349 : has_pending_exception =
4350 : i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4351 180361 : i::LanguageMode::kSloppy)
4352 360722 : .is_null();
4353 180361 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4354 : return Just(true);
4355 : }
4356 :
4357 :
4358 0 : bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
4359 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4360 0 : return Set(context, key, value).FromMaybe(false);
4361 : }
4362 :
4363 :
4364 10969 : Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4365 : v8::Local<Value> value) {
4366 10969 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4367 43876 : ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4368 : auto self = Utils::OpenHandle(this);
4369 10969 : auto value_obj = Utils::OpenHandle(*value);
4370 : has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4371 10969 : i::LanguageMode::kSloppy)
4372 21938 : .is_null();
4373 10969 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4374 : return Just(true);
4375 : }
4376 :
4377 :
4378 0 : bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
4379 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4380 0 : return Set(context, index, value).FromMaybe(false);
4381 : }
4382 :
4383 :
4384 59129 : Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4385 : v8::Local<Name> key,
4386 : v8::Local<Value> value) {
4387 59129 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4388 236516 : ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4389 : i::HandleScope);
4390 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4391 59129 : i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4392 59129 : i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4393 :
4394 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4395 59129 : isolate, self, key_obj, self, i::LookupIterator::OWN);
4396 : Maybe<bool> result =
4397 59129 : i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
4398 59129 : has_pending_exception = result.IsNothing();
4399 59129 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4400 59124 : return result;
4401 : }
4402 :
4403 :
4404 11466 : Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4405 : uint32_t index,
4406 : v8::Local<Value> value) {
4407 11466 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4408 45864 : ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4409 : i::HandleScope);
4410 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4411 11466 : i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4412 :
4413 : i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4414 : Maybe<bool> result =
4415 11466 : i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
4416 11466 : has_pending_exception = result.IsNothing();
4417 11466 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4418 11466 : return result;
4419 : }
4420 :
4421 : struct v8::PropertyDescriptor::PrivateData {
4422 : PrivateData() : desc() {}
4423 : i::PropertyDescriptor desc;
4424 : };
4425 :
4426 206 : v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4427 :
4428 : // DataDescriptor
4429 81 : v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4430 162 : : private_(new PrivateData()) {
4431 : private_->desc.set_value(Utils::OpenHandle(*value, true));
4432 81 : }
4433 :
4434 : // DataDescriptor with writable field
4435 26 : v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4436 : bool writable)
4437 52 : : private_(new PrivateData()) {
4438 : private_->desc.set_value(Utils::OpenHandle(*value, true));
4439 26 : private_->desc.set_writable(writable);
4440 26 : }
4441 :
4442 : // AccessorDescriptor
4443 65 : v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4444 : v8::Local<v8::Value> set)
4445 130 : : private_(new PrivateData()) {
4446 : DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4447 : DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4448 : private_->desc.set_get(Utils::OpenHandle(*get, true));
4449 65 : private_->desc.set_set(Utils::OpenHandle(*set, true));
4450 65 : }
4451 :
4452 275 : v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4453 :
4454 32 : v8::Local<Value> v8::PropertyDescriptor::value() const {
4455 : DCHECK(private_->desc.has_value());
4456 32 : return Utils::ToLocal(private_->desc.value());
4457 : }
4458 :
4459 22 : v8::Local<Value> v8::PropertyDescriptor::get() const {
4460 : DCHECK(private_->desc.has_get());
4461 22 : return Utils::ToLocal(private_->desc.get());
4462 : }
4463 :
4464 22 : v8::Local<Value> v8::PropertyDescriptor::set() const {
4465 : DCHECK(private_->desc.has_set());
4466 22 : return Utils::ToLocal(private_->desc.set());
4467 : }
4468 :
4469 69 : bool v8::PropertyDescriptor::has_value() const {
4470 138 : return private_->desc.has_value();
4471 : }
4472 69 : bool v8::PropertyDescriptor::has_get() const {
4473 138 : return private_->desc.has_get();
4474 : }
4475 69 : bool v8::PropertyDescriptor::has_set() const {
4476 138 : return private_->desc.has_set();
4477 : }
4478 :
4479 16 : bool v8::PropertyDescriptor::writable() const {
4480 : DCHECK(private_->desc.has_writable());
4481 32 : return private_->desc.writable();
4482 : }
4483 :
4484 69 : bool v8::PropertyDescriptor::has_writable() const {
4485 138 : return private_->desc.has_writable();
4486 : }
4487 :
4488 37 : void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4489 37 : private_->desc.set_enumerable(enumerable);
4490 37 : }
4491 :
4492 17 : bool v8::PropertyDescriptor::enumerable() const {
4493 : DCHECK(private_->desc.has_enumerable());
4494 34 : return private_->desc.enumerable();
4495 : }
4496 :
4497 63 : bool v8::PropertyDescriptor::has_enumerable() const {
4498 126 : return private_->desc.has_enumerable();
4499 : }
4500 :
4501 38 : void v8::PropertyDescriptor::set_configurable(bool configurable) {
4502 38 : private_->desc.set_configurable(configurable);
4503 38 : }
4504 :
4505 32 : bool v8::PropertyDescriptor::configurable() const {
4506 : DCHECK(private_->desc.has_configurable());
4507 64 : return private_->desc.configurable();
4508 : }
4509 :
4510 63 : bool v8::PropertyDescriptor::has_configurable() const {
4511 126 : return private_->desc.has_configurable();
4512 : }
4513 :
4514 3192 : Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4515 : v8::Local<Name> key,
4516 : v8::Local<Value> value,
4517 : v8::PropertyAttribute attributes) {
4518 3192 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4519 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4520 : i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4521 : i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4522 :
4523 : i::PropertyDescriptor desc;
4524 3192 : desc.set_writable(!(attributes & v8::ReadOnly));
4525 3192 : desc.set_enumerable(!(attributes & v8::DontEnum));
4526 3192 : desc.set_configurable(!(attributes & v8::DontDelete));
4527 : desc.set_value(value_obj);
4528 :
4529 3192 : if (self->IsJSProxy()) {
4530 0 : ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4531 : i::HandleScope);
4532 : Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4533 0 : isolate, self, key_obj, &desc, i::Object::DONT_THROW);
4534 : // Even though we said DONT_THROW, there might be accessors that do throw.
4535 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4536 0 : return success;
4537 : } else {
4538 : // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4539 : // a script.
4540 12768 : ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4541 : Nothing<bool>(), i::HandleScope);
4542 : Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4543 3192 : isolate, self, key_obj, &desc, i::Object::DONT_THROW);
4544 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4545 3192 : return success;
4546 : }
4547 : }
4548 :
4549 126 : Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4550 : v8::Local<Name> key,
4551 : PropertyDescriptor& descriptor) {
4552 126 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4553 504 : ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4554 : i::HandleScope);
4555 126 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4556 : i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4557 :
4558 : Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4559 : isolate, self, key_obj, &descriptor.get_private()->desc,
4560 252 : i::Object::DONT_THROW);
4561 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4562 126 : return success;
4563 : }
4564 :
4565 : MUST_USE_RESULT
4566 0 : static i::MaybeHandle<i::Object> DefineObjectProperty(
4567 : i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
4568 : i::Handle<i::Object> value, i::PropertyAttributes attrs) {
4569 : i::Isolate* isolate = js_object->GetIsolate();
4570 0 : bool success = false;
4571 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4572 0 : isolate, js_object, key, &success, i::LookupIterator::OWN);
4573 0 : if (!success) return i::MaybeHandle<i::Object>();
4574 :
4575 : return i::JSObject::DefineOwnPropertyIgnoreAttributes(
4576 0 : &it, value, attrs, i::JSObject::FORCE_FIELD);
4577 : }
4578 :
4579 :
4580 0 : Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
4581 : v8::Local<Value> key, v8::Local<Value> value,
4582 : v8::PropertyAttribute attribs) {
4583 0 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4584 0 : ENTER_V8_NO_SCRIPT(isolate, context, Object, ForceSet, Nothing<bool>(),
4585 : i::HandleScope);
4586 0 : auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4587 0 : auto key_obj = Utils::OpenHandle(*key);
4588 0 : auto value_obj = Utils::OpenHandle(*value);
4589 : has_pending_exception =
4590 : DefineObjectProperty(self, key_obj, value_obj,
4591 : static_cast<i::PropertyAttributes>(attribs))
4592 0 : .is_null();
4593 0 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4594 : return Just(true);
4595 : }
4596 :
4597 :
4598 254029 : Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4599 : Local<Value> value) {
4600 254029 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4601 1016116 : ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4602 : i::HandleScope);
4603 : auto self = Utils::OpenHandle(this);
4604 : auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4605 : auto value_obj = Utils::OpenHandle(*value);
4606 254029 : if (self->IsJSProxy()) {
4607 : i::PropertyDescriptor desc;
4608 : desc.set_writable(true);
4609 : desc.set_enumerable(false);
4610 : desc.set_configurable(true);
4611 : desc.set_value(value_obj);
4612 : return i::JSProxy::SetPrivateProperty(
4613 : isolate, i::Handle<i::JSProxy>::cast(self),
4614 18 : i::Handle<i::Symbol>::cast(key_obj), &desc, i::Object::DONT_THROW);
4615 : }
4616 : auto js_object = i::Handle<i::JSObject>::cast(self);
4617 254011 : i::LookupIterator it(js_object, key_obj, js_object);
4618 : has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4619 : &it, value_obj, i::DONT_ENUM)
4620 508022 : .is_null();
4621 254011 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4622 : return Just(true);
4623 : }
4624 :
4625 :
4626 30050743 : MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4627 : Local<Value> key) {
4628 120202972 : PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4629 : auto self = Utils::OpenHandle(this);
4630 30050743 : auto key_obj = Utils::OpenHandle(*key);
4631 : i::Handle<i::Object> result;
4632 : has_pending_exception =
4633 60101486 : !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4634 30050743 : RETURN_ON_FAILED_EXECUTION(Value);
4635 30050132 : RETURN_ESCAPED(Utils::ToLocal(result));
4636 : }
4637 :
4638 :
4639 0 : Local<Value> v8::Object::Get(v8::Local<Value> key) {
4640 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4641 0 : RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value);
4642 : }
4643 :
4644 :
4645 44755116 : MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4646 179020464 : PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4647 44755116 : auto self = Utils::OpenHandle(this);
4648 : i::Handle<i::Object> result;
4649 : has_pending_exception =
4650 89510232 : !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4651 44755116 : RETURN_ON_FAILED_EXECUTION(Value);
4652 44755106 : RETURN_ESCAPED(Utils::ToLocal(result));
4653 : }
4654 :
4655 :
4656 0 : Local<Value> v8::Object::Get(uint32_t index) {
4657 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4658 0 : RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value);
4659 : }
4660 :
4661 :
4662 2541641 : MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4663 : Local<Private> key) {
4664 2541641 : return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4665 : }
4666 :
4667 :
4668 58 : Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4669 : Local<Context> context, Local<Value> key) {
4670 58 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4671 232 : ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4672 : Nothing<PropertyAttribute>(), i::HandleScope);
4673 58 : auto self = Utils::OpenHandle(this);
4674 : auto key_obj = Utils::OpenHandle(*key);
4675 58 : if (!key_obj->IsName()) {
4676 : has_pending_exception =
4677 24 : !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4678 12 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4679 : }
4680 52 : auto key_name = i::Handle<i::Name>::cast(key_obj);
4681 52 : auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4682 52 : has_pending_exception = result.IsNothing();
4683 52 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4684 52 : if (result.FromJust() == i::ABSENT) {
4685 : return Just(static_cast<PropertyAttribute>(i::NONE));
4686 : }
4687 : return Just(static_cast<PropertyAttribute>(result.FromJust()));
4688 : }
4689 :
4690 :
4691 0 : PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
4692 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4693 : return GetPropertyAttributes(context, key)
4694 0 : .FromMaybe(static_cast<PropertyAttribute>(i::NONE));
4695 : }
4696 :
4697 7305 : MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4698 : Local<Name> key) {
4699 29220 : PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4700 7305 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4701 : i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4702 :
4703 : i::PropertyDescriptor desc;
4704 : Maybe<bool> found =
4705 7305 : i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4706 7305 : has_pending_exception = found.IsNothing();
4707 7305 : RETURN_ON_FAILED_EXECUTION(Value);
4708 7305 : if (!found.FromJust()) {
4709 5 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4710 : }
4711 14600 : RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4712 : }
4713 :
4714 0 : Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<Name> key) {
4715 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4716 0 : RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value);
4717 : }
4718 :
4719 :
4720 185442 : Local<Value> v8::Object::GetPrototype() {
4721 : auto isolate = Utils::OpenHandle(this)->GetIsolate();
4722 185442 : auto self = Utils::OpenHandle(this);
4723 185442 : i::PrototypeIterator iter(isolate, self);
4724 185442 : return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4725 : }
4726 :
4727 :
4728 2455398 : Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4729 : Local<Value> value) {
4730 2455398 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4731 9821592 : ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4732 : i::HandleScope);
4733 2455398 : auto self = Utils::OpenHandle(this);
4734 2455398 : auto value_obj = Utils::OpenHandle(*value);
4735 : // We do not allow exceptions thrown while setting the prototype
4736 : // to propagate outside.
4737 4910796 : TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4738 : auto result = i::JSReceiver::SetPrototype(self, value_obj, false,
4739 2455398 : i::Object::THROW_ON_ERROR);
4740 2455398 : has_pending_exception = result.IsNothing();
4741 2455398 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4742 : return Just(true);
4743 : }
4744 :
4745 :
4746 0 : bool v8::Object::SetPrototype(Local<Value> value) {
4747 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4748 0 : return SetPrototype(context, value).FromMaybe(false);
4749 : }
4750 :
4751 54 : Local<Object> v8::Object::FindInstanceInPrototypeChain(
4752 : v8::Local<FunctionTemplate> tmpl) {
4753 : auto self = Utils::OpenHandle(this);
4754 : auto isolate = self->GetIsolate();
4755 : i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4756 : auto tmpl_info = *Utils::OpenHandle(*tmpl);
4757 162 : while (!tmpl_info->IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4758 72 : iter.Advance();
4759 72 : if (iter.IsAtEnd()) return Local<Object>();
4760 108 : if (!iter.GetCurrent()->IsJSObject()) return Local<Object>();
4761 : }
4762 : // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4763 36 : return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4764 : }
4765 :
4766 5229154 : MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4767 : return GetPropertyNames(
4768 : context, v8::KeyCollectionMode::kIncludePrototypes,
4769 : static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4770 5229154 : v8::IndexFilter::kIncludeIndices);
4771 : }
4772 :
4773 5229744 : MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context,
4774 : KeyCollectionMode mode,
4775 : PropertyFilter property_filter,
4776 : IndexFilter index_filter) {
4777 20918976 : PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4778 5229744 : auto self = Utils::OpenHandle(this);
4779 : i::Handle<i::FixedArray> value;
4780 : i::KeyAccumulator accumulator(
4781 : isolate, static_cast<i::KeyCollectionMode>(mode),
4782 5229744 : static_cast<i::PropertyFilter>(property_filter));
4783 5229744 : accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4784 5229744 : has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4785 5229744 : RETURN_ON_FAILED_EXECUTION(Array);
4786 5229744 : value = accumulator.GetKeys(i::GetKeysConversion::kKeepNumbers);
4787 : DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
4788 : self->map()->EnumLength() == 0 ||
4789 : self->map()->instance_descriptors()->GetEnumCache()->keys() != *value);
4790 : auto result = isolate->factory()->NewJSArrayWithElements(value);
4791 5229744 : RETURN_ESCAPED(Utils::ToLocal(result));
4792 : }
4793 :
4794 :
4795 0 : Local<Array> v8::Object::GetPropertyNames() {
4796 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4797 0 : RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
4798 : }
4799 :
4800 524 : MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4801 : return GetOwnPropertyNames(
4802 524 : context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4803 : }
4804 :
4805 0 : Local<Array> v8::Object::GetOwnPropertyNames() {
4806 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4807 0 : RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
4808 : }
4809 :
4810 18 : MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context,
4811 : PropertyFilter filter) {
4812 : return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4813 542 : v8::IndexFilter::kIncludeIndices);
4814 : }
4815 :
4816 428 : MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4817 1712 : PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4818 : auto self = Utils::OpenHandle(this);
4819 : Local<Value> result;
4820 : has_pending_exception =
4821 : !ToLocal<Value>(i::Execution::Call(isolate, isolate->object_to_string(),
4822 : self, 0, nullptr),
4823 1284 : &result);
4824 428 : RETURN_ON_FAILED_EXECUTION(String);
4825 413 : RETURN_ESCAPED(Local<String>::Cast(result));
4826 : }
4827 :
4828 :
4829 0 : Local<String> v8::Object::ObjectProtoToString() {
4830 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4831 0 : RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String);
4832 : }
4833 :
4834 :
4835 5053948 : Local<String> v8::Object::GetConstructorName() {
4836 5053948 : auto self = Utils::OpenHandle(this);
4837 5053948 : i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
4838 5053948 : return Utils::ToLocal(name);
4839 : }
4840 :
4841 6 : Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4842 : IntegrityLevel level) {
4843 6 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4844 24 : ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4845 : i::HandleScope);
4846 6 : auto self = Utils::OpenHandle(this);
4847 : i::JSReceiver::IntegrityLevel i_level =
4848 6 : level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4849 : Maybe<bool> result = i::JSReceiver::SetIntegrityLevel(
4850 6 : self, i_level, i::Object::THROW_ON_ERROR);
4851 6 : has_pending_exception = result.IsNothing();
4852 6 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4853 5 : return result;
4854 : }
4855 :
4856 7566 : Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4857 7566 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4858 : auto self = Utils::OpenHandle(this);
4859 7566 : auto key_obj = Utils::OpenHandle(*key);
4860 7566 : if (self->IsJSProxy()) {
4861 0 : ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4862 : Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4863 0 : isolate, self, key_obj, i::LanguageMode::kSloppy);
4864 0 : has_pending_exception = result.IsNothing();
4865 0 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4866 0 : return result;
4867 : } else {
4868 : // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4869 : // a script.
4870 30264 : ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4871 : i::HandleScope);
4872 : Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4873 7566 : isolate, self, key_obj, i::LanguageMode::kSloppy);
4874 7566 : has_pending_exception = result.IsNothing();
4875 7566 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4876 7566 : return result;
4877 : }
4878 : }
4879 :
4880 0 : bool v8::Object::Delete(v8::Local<Value> key) {
4881 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4882 0 : return Delete(context, key).FromMaybe(false);
4883 : }
4884 :
4885 42 : Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4886 : Local<Private> key) {
4887 42 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4888 : // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4889 : // any author script.
4890 168 : ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4891 : i::HandleScope);
4892 42 : auto self = Utils::OpenHandle(this);
4893 42 : auto key_obj = Utils::OpenHandle(*key);
4894 : Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4895 42 : isolate, self, key_obj, i::LanguageMode::kSloppy);
4896 42 : has_pending_exception = result.IsNothing();
4897 42 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4898 42 : return result;
4899 : }
4900 :
4901 11639 : Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4902 11639 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4903 46556 : ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4904 11639 : auto self = Utils::OpenHandle(this);
4905 : auto key_obj = Utils::OpenHandle(*key);
4906 : Maybe<bool> maybe = Nothing<bool>();
4907 : // Check if the given key is an array index.
4908 11639 : uint32_t index = 0;
4909 11639 : if (key_obj->ToArrayIndex(&index)) {
4910 0 : maybe = i::JSReceiver::HasElement(self, index);
4911 : } else {
4912 : // Convert the key to a name - possibly by calling back into JavaScript.
4913 : i::Handle<i::Name> name;
4914 23278 : if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4915 11639 : maybe = i::JSReceiver::HasProperty(self, name);
4916 : }
4917 : }
4918 11639 : has_pending_exception = maybe.IsNothing();
4919 11639 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4920 11639 : return maybe;
4921 : }
4922 :
4923 :
4924 0 : bool v8::Object::Has(v8::Local<Value> key) {
4925 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4926 0 : return Has(context, key).FromMaybe(false);
4927 : }
4928 :
4929 :
4930 6910798 : Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4931 6910798 : return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4932 : }
4933 :
4934 :
4935 10 : Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4936 10 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4937 40 : ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4938 10 : auto self = Utils::OpenHandle(this);
4939 10 : Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4940 10 : has_pending_exception = result.IsNothing();
4941 10 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4942 5 : return result;
4943 : }
4944 :
4945 :
4946 0 : bool v8::Object::Delete(uint32_t index) {
4947 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4948 0 : return Delete(context, index).FromMaybe(false);
4949 : }
4950 :
4951 :
4952 30 : Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4953 30 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4954 120 : ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4955 30 : auto self = Utils::OpenHandle(this);
4956 30 : auto maybe = i::JSReceiver::HasElement(self, index);
4957 30 : has_pending_exception = maybe.IsNothing();
4958 30 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4959 30 : return maybe;
4960 : }
4961 :
4962 :
4963 0 : bool v8::Object::Has(uint32_t index) {
4964 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4965 0 : return Has(context, index).FromMaybe(false);
4966 : }
4967 :
4968 : template <typename Getter, typename Setter, typename Data>
4969 7440 : static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
4970 : Local<Name> name, Getter getter,
4971 : Setter setter, Data data,
4972 : AccessControl settings,
4973 : PropertyAttribute attributes,
4974 : bool is_special_data_property) {
4975 7440 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4976 29760 : ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4977 : i::HandleScope);
4978 7440 : if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4979 : i::Handle<i::JSObject> obj =
4980 : i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4981 : v8::Local<AccessorSignature> signature;
4982 : auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes,
4983 7440 : signature, is_special_data_property, false);
4984 7440 : if (info.is_null()) return Nothing<bool>();
4985 7440 : bool fast = obj->HasFastProperties();
4986 : i::Handle<i::Object> result;
4987 : has_pending_exception =
4988 14880 : !i::JSObject::SetAccessor(obj, info).ToHandle(&result);
4989 7440 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4990 7435 : if (result->IsUndefined(obj->GetIsolate())) return Just(false);
4991 7410 : if (fast) {
4992 7398 : i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4993 : }
4994 : return Just(true);
4995 : }
4996 :
4997 :
4998 7434 : Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4999 : AccessorNameGetterCallback getter,
5000 : AccessorNameSetterCallback setter,
5001 : MaybeLocal<Value> data, AccessControl settings,
5002 : PropertyAttribute attribute) {
5003 : return ObjectSetAccessor(context, this, name, getter, setter,
5004 : data.FromMaybe(Local<Value>()), settings, attribute,
5005 14868 : i::FLAG_disable_old_api_accessors);
5006 : }
5007 :
5008 :
5009 0 : bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
5010 : AccessorSetterCallback setter, v8::Local<Value> data,
5011 : AccessControl settings, PropertyAttribute attributes) {
5012 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5013 : return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
5014 0 : attributes, i::FLAG_disable_old_api_accessors)
5015 0 : .FromMaybe(false);
5016 : }
5017 :
5018 :
5019 0 : bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
5020 : AccessorNameSetterCallback setter,
5021 : v8::Local<Value> data, AccessControl settings,
5022 : PropertyAttribute attributes) {
5023 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5024 : return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
5025 0 : attributes, i::FLAG_disable_old_api_accessors)
5026 0 : .FromMaybe(false);
5027 : }
5028 :
5029 :
5030 248520 : void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
5031 : Local<Function> setter,
5032 : PropertyAttribute attribute,
5033 : AccessControl settings) {
5034 : // TODO(verwaest): Remove |settings|.
5035 : DCHECK_EQ(v8::DEFAULT, settings);
5036 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5037 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5038 : i::HandleScope scope(isolate);
5039 : auto self = Utils::OpenHandle(this);
5040 497040 : if (!self->IsJSObject()) return;
5041 : i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
5042 : i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
5043 248520 : if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
5044 : i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
5045 : v8::Utils::OpenHandle(*name), getter_i, setter_i,
5046 248520 : static_cast<i::PropertyAttributes>(attribute));
5047 : }
5048 :
5049 6 : Maybe<bool> Object::SetNativeDataProperty(v8::Local<v8::Context> context,
5050 : v8::Local<Name> name,
5051 : AccessorNameGetterCallback getter,
5052 : AccessorNameSetterCallback setter,
5053 : v8::Local<Value> data,
5054 : PropertyAttribute attributes) {
5055 : return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
5056 6 : attributes, true);
5057 : }
5058 :
5059 6910953 : Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
5060 : Local<Name> key) {
5061 6910953 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5062 27643812 : ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
5063 : i::HandleScope);
5064 6910953 : auto self = Utils::OpenHandle(this);
5065 6910953 : auto key_val = Utils::OpenHandle(*key);
5066 6910953 : auto result = i::JSReceiver::HasOwnProperty(self, key_val);
5067 6910953 : has_pending_exception = result.IsNothing();
5068 6910953 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5069 6910948 : return result;
5070 : }
5071 :
5072 25 : Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
5073 25 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5074 100 : ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
5075 : i::HandleScope);
5076 25 : auto self = Utils::OpenHandle(this);
5077 25 : auto result = i::JSReceiver::HasOwnProperty(self, index);
5078 25 : has_pending_exception = result.IsNothing();
5079 25 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5080 25 : return result;
5081 : }
5082 :
5083 0 : bool v8::Object::HasOwnProperty(Local<String> key) {
5084 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5085 0 : return HasOwnProperty(context, key).FromMaybe(false);
5086 : }
5087 :
5088 :
5089 42330545 : Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
5090 : Local<Name> key) {
5091 42330545 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5092 169322180 : ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
5093 : Nothing<bool>(), i::HandleScope);
5094 : auto self = Utils::OpenHandle(this);
5095 42330545 : if (!self->IsJSObject()) return Just(false);
5096 42330545 : auto key_val = Utils::OpenHandle(*key);
5097 : auto result = i::JSObject::HasRealNamedProperty(
5098 42330545 : i::Handle<i::JSObject>::cast(self), key_val);
5099 42330545 : has_pending_exception = result.IsNothing();
5100 42330545 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5101 42330540 : return result;
5102 : }
5103 :
5104 :
5105 0 : bool v8::Object::HasRealNamedProperty(Local<String> key) {
5106 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5107 0 : return HasRealNamedProperty(context, key).FromMaybe(false);
5108 : }
5109 :
5110 :
5111 17 : Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
5112 : uint32_t index) {
5113 17 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5114 68 : ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
5115 : Nothing<bool>(), i::HandleScope);
5116 : auto self = Utils::OpenHandle(this);
5117 17 : if (!self->IsJSObject()) return Just(false);
5118 : auto result = i::JSObject::HasRealElementProperty(
5119 17 : i::Handle<i::JSObject>::cast(self), index);
5120 17 : has_pending_exception = result.IsNothing();
5121 17 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5122 12 : return result;
5123 : }
5124 :
5125 :
5126 0 : bool v8::Object::HasRealIndexedProperty(uint32_t index) {
5127 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5128 0 : return HasRealIndexedProperty(context, index).FromMaybe(false);
5129 : }
5130 :
5131 :
5132 5 : Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
5133 : Local<Name> key) {
5134 5 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5135 20 : ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
5136 : Nothing<bool>(), i::HandleScope);
5137 : auto self = Utils::OpenHandle(this);
5138 5 : if (!self->IsJSObject()) return Just(false);
5139 5 : auto key_val = Utils::OpenHandle(*key);
5140 : auto result = i::JSObject::HasRealNamedCallbackProperty(
5141 5 : i::Handle<i::JSObject>::cast(self), key_val);
5142 5 : has_pending_exception = result.IsNothing();
5143 5 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
5144 0 : return result;
5145 : }
5146 :
5147 :
5148 0 : bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) {
5149 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5150 0 : return HasRealNamedCallbackProperty(context, key).FromMaybe(false);
5151 : }
5152 :
5153 :
5154 0 : bool v8::Object::HasNamedLookupInterceptor() {
5155 : auto self = Utils::OpenHandle(this);
5156 0 : return self->IsJSObject() &&
5157 0 : i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
5158 : }
5159 :
5160 :
5161 0 : bool v8::Object::HasIndexedLookupInterceptor() {
5162 : auto self = Utils::OpenHandle(this);
5163 0 : return self->IsJSObject() &&
5164 0 : i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
5165 : }
5166 :
5167 :
5168 6 : MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
5169 : Local<Context> context, Local<Name> key) {
5170 24 : PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
5171 : Value);
5172 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5173 6 : if (!self->IsJSObject()) return MaybeLocal<Value>();
5174 6 : i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5175 6 : i::PrototypeIterator iter(isolate, self);
5176 6 : if (iter.IsAtEnd()) return MaybeLocal<Value>();
5177 : i::Handle<i::JSReceiver> proto =
5178 6 : i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5179 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
5180 : isolate, self, key_obj, proto,
5181 6 : i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5182 : Local<Value> result;
5183 6 : has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5184 6 : RETURN_ON_FAILED_EXECUTION(Value);
5185 0 : if (!it.IsFound()) return MaybeLocal<Value>();
5186 0 : RETURN_ESCAPED(result);
5187 : }
5188 :
5189 :
5190 0 : Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
5191 : Local<String> key) {
5192 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5193 0 : RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key),
5194 : Value);
5195 : }
5196 :
5197 :
5198 : Maybe<PropertyAttribute>
5199 6 : v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
5200 : Local<Context> context, Local<Name> key) {
5201 6 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5202 24 : ENTER_V8_NO_SCRIPT(isolate, context, Object,
5203 : GetRealNamedPropertyAttributesInPrototypeChain,
5204 : Nothing<PropertyAttribute>(), i::HandleScope);
5205 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5206 6 : if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
5207 6 : i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
5208 6 : i::PrototypeIterator iter(isolate, self);
5209 6 : if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
5210 : i::Handle<i::JSReceiver> proto =
5211 6 : i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
5212 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
5213 : isolate, self, key_obj, proto,
5214 6 : i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5215 : Maybe<i::PropertyAttributes> result =
5216 6 : i::JSReceiver::GetPropertyAttributes(&it);
5217 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5218 6 : if (!it.IsFound()) return Nothing<PropertyAttribute>();
5219 6 : if (result.FromJust() == i::ABSENT) return Just(None);
5220 : return Just(static_cast<PropertyAttribute>(result.FromJust()));
5221 : }
5222 :
5223 :
5224 : Maybe<PropertyAttribute>
5225 0 : v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
5226 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5227 0 : return GetRealNamedPropertyAttributesInPrototypeChain(context, key);
5228 : }
5229 :
5230 :
5231 68 : MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
5232 : Local<Name> key) {
5233 272 : PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
5234 : auto self = Utils::OpenHandle(this);
5235 68 : auto key_obj = Utils::OpenHandle(*key);
5236 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
5237 : isolate, self, key_obj, self,
5238 68 : i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5239 : Local<Value> result;
5240 68 : has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
5241 68 : RETURN_ON_FAILED_EXECUTION(Value);
5242 50 : if (!it.IsFound()) return MaybeLocal<Value>();
5243 38 : RETURN_ESCAPED(result);
5244 : }
5245 :
5246 :
5247 0 : Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
5248 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5249 0 : RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value);
5250 : }
5251 :
5252 :
5253 18 : Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5254 : Local<Context> context, Local<Name> key) {
5255 18 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5256 72 : ENTER_V8_NO_SCRIPT(isolate, context, Object, GetRealNamedPropertyAttributes,
5257 : Nothing<PropertyAttribute>(), i::HandleScope);
5258 : auto self = Utils::OpenHandle(this);
5259 18 : auto key_obj = Utils::OpenHandle(*key);
5260 : i::LookupIterator it = i::LookupIterator::PropertyOrElement(
5261 : isolate, self, key_obj, self,
5262 18 : i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
5263 18 : auto result = i::JSReceiver::GetPropertyAttributes(&it);
5264 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
5265 18 : if (!it.IsFound()) return Nothing<PropertyAttribute>();
5266 18 : if (result.FromJust() == i::ABSENT) {
5267 : return Just(static_cast<PropertyAttribute>(i::NONE));
5268 : }
5269 : return Just<PropertyAttribute>(
5270 : static_cast<PropertyAttribute>(result.FromJust()));
5271 : }
5272 :
5273 :
5274 0 : Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
5275 : Local<String> key) {
5276 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5277 0 : return GetRealNamedPropertyAttributes(context, key);
5278 : }
5279 :
5280 :
5281 16 : Local<v8::Object> v8::Object::Clone() {
5282 : auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
5283 : auto isolate = self->GetIsolate();
5284 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5285 16 : auto result = isolate->factory()->CopyJSObject(self);
5286 16 : CHECK(!result.is_null());
5287 16 : return Utils::ToLocal(result);
5288 : }
5289 :
5290 :
5291 221768 : Local<v8::Context> v8::Object::CreationContext() {
5292 : auto self = Utils::OpenHandle(this);
5293 221768 : return Utils::ToLocal(self->GetCreationContext());
5294 : }
5295 :
5296 :
5297 106 : int v8::Object::GetIdentityHash() {
5298 : i::DisallowHeapAllocation no_gc;
5299 : auto isolate = Utils::OpenHandle(this)->GetIsolate();
5300 : i::HandleScope scope(isolate);
5301 : auto self = Utils::OpenHandle(this);
5302 212 : return self->GetOrCreateIdentityHash(isolate)->value();
5303 : }
5304 :
5305 :
5306 24 : bool v8::Object::IsCallable() {
5307 : auto self = Utils::OpenHandle(this);
5308 24 : return self->IsCallable();
5309 : }
5310 :
5311 6 : bool v8::Object::IsConstructor() {
5312 : auto self = Utils::OpenHandle(this);
5313 6 : return self->IsConstructor();
5314 : }
5315 :
5316 108 : MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
5317 : Local<Value> recv, int argc,
5318 : Local<Value> argv[]) {
5319 108 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5320 216 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5321 432 : ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
5322 : InternalEscapableScope);
5323 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5324 : auto self = Utils::OpenHandle(this);
5325 108 : auto recv_obj = Utils::OpenHandle(*recv);
5326 : STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5327 : i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5328 : Local<Value> result;
5329 : has_pending_exception = !ToLocal<Value>(
5330 216 : i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5331 108 : RETURN_ON_FAILED_EXECUTION(Value);
5332 204 : RETURN_ESCAPED(result);
5333 : }
5334 :
5335 :
5336 0 : Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
5337 : v8::Local<v8::Value> argv[]) {
5338 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5339 : Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
5340 0 : RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast),
5341 : Value);
5342 : }
5343 :
5344 :
5345 66 : MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
5346 : Local<Value> argv[]) {
5347 66 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5348 132 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5349 264 : ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
5350 : InternalEscapableScope);
5351 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5352 : auto self = Utils::OpenHandle(this);
5353 : STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5354 : i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5355 : Local<Value> result;
5356 : has_pending_exception = !ToLocal<Value>(
5357 132 : i::Execution::New(isolate, self, self, argc, args), &result);
5358 66 : RETURN_ON_FAILED_EXECUTION(Value);
5359 120 : RETURN_ESCAPED(result);
5360 : }
5361 :
5362 :
5363 0 : Local<v8::Value> Object::CallAsConstructor(int argc,
5364 : v8::Local<v8::Value> argv[]) {
5365 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5366 : Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
5367 0 : RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
5368 : }
5369 :
5370 31531 : MaybeLocal<Function> Function::New(Local<Context> context,
5371 : FunctionCallback callback, Local<Value> data,
5372 : int length, ConstructorBehavior behavior) {
5373 31531 : i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
5374 63062 : LOG_API(isolate, Function, New);
5375 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5376 : auto templ = FunctionTemplateNew(isolate, callback, data, Local<Signature>(),
5377 31531 : length, true);
5378 31531 : if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
5379 63062 : return templ->GetFunction(context);
5380 : }
5381 :
5382 :
5383 0 : Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
5384 : Local<Value> data, int length) {
5385 : return Function::New(v8_isolate->GetCurrentContext(), callback, data, length,
5386 0 : ConstructorBehavior::kAllow)
5387 0 : .FromMaybe(Local<Function>());
5388 : }
5389 :
5390 :
5391 0 : Local<v8::Object> Function::NewInstance() const {
5392 0 : return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, nullptr)
5393 0 : .FromMaybe(Local<Object>());
5394 : }
5395 :
5396 :
5397 803 : MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
5398 : v8::Local<v8::Value> argv[]) const {
5399 803 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5400 1606 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5401 3212 : ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
5402 : InternalEscapableScope);
5403 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5404 : auto self = Utils::OpenHandle(this);
5405 : STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5406 : i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5407 : Local<Object> result;
5408 : has_pending_exception = !ToLocal<Object>(
5409 1606 : i::Execution::New(isolate, self, self, argc, args), &result);
5410 803 : RETURN_ON_FAILED_EXECUTION(Object);
5411 1600 : RETURN_ESCAPED(result);
5412 : }
5413 :
5414 :
5415 0 : Local<v8::Object> Function::NewInstance(int argc,
5416 : v8::Local<v8::Value> argv[]) const {
5417 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5418 0 : RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object);
5419 : }
5420 :
5421 :
5422 833545 : MaybeLocal<v8::Value> Function::Call(Local<Context> context,
5423 : v8::Local<v8::Value> recv, int argc,
5424 : v8::Local<v8::Value> argv[]) {
5425 833523 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
5426 1667090 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
5427 3334148 : ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
5428 : InternalEscapableScope);
5429 : i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
5430 : auto self = Utils::OpenHandle(this);
5431 833521 : i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
5432 : STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
5433 : i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
5434 : Local<Value> result;
5435 : has_pending_exception = !ToLocal<Value>(
5436 1667086 : i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
5437 833565 : RETURN_ON_FAILED_EXECUTION(Value);
5438 1666704 : RETURN_ESCAPED(result);
5439 : }
5440 :
5441 :
5442 0 : Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc,
5443 : v8::Local<v8::Value> argv[]) {
5444 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5445 0 : RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value);
5446 : }
5447 :
5448 :
5449 27131 : void Function::SetName(v8::Local<v8::String> name) {
5450 : auto self = Utils::OpenHandle(this);
5451 54262 : if (!self->IsJSFunction()) return;
5452 : auto func = i::Handle<i::JSFunction>::cast(self);
5453 : func->shared()->set_name(*Utils::OpenHandle(*name));
5454 : }
5455 :
5456 :
5457 37 : Local<Value> Function::GetName() const {
5458 : auto self = Utils::OpenHandle(this);
5459 : i::Isolate* isolate = self->GetIsolate();
5460 37 : if (self->IsJSBoundFunction()) {
5461 0 : auto func = i::Handle<i::JSBoundFunction>::cast(self);
5462 : i::Handle<i::Object> name;
5463 0 : ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5464 : i::JSBoundFunction::GetName(isolate, func),
5465 : Local<Value>());
5466 : return Utils::ToLocal(name);
5467 : }
5468 37 : if (self->IsJSFunction()) {
5469 : auto func = i::Handle<i::JSFunction>::cast(self);
5470 37 : return Utils::ToLocal(handle(func->shared()->name(), isolate));
5471 : }
5472 0 : return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5473 : }
5474 :
5475 :
5476 6 : Local<Value> Function::GetInferredName() const {
5477 : auto self = Utils::OpenHandle(this);
5478 6 : if (!self->IsJSFunction()) {
5479 : return ToApiHandle<Primitive>(
5480 0 : self->GetIsolate()->factory()->undefined_value());
5481 : }
5482 : auto func = i::Handle<i::JSFunction>::cast(self);
5483 6 : return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
5484 : func->GetIsolate()));
5485 : }
5486 :
5487 :
5488 88335 : Local<Value> Function::GetDebugName() const {
5489 : auto self = Utils::OpenHandle(this);
5490 88335 : if (!self->IsJSFunction()) {
5491 : return ToApiHandle<Primitive>(
5492 0 : self->GetIsolate()->factory()->undefined_value());
5493 : }
5494 88335 : auto func = i::Handle<i::JSFunction>::cast(self);
5495 88335 : i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5496 : return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate()));
5497 : }
5498 :
5499 :
5500 42 : Local<Value> Function::GetDisplayName() const {
5501 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5502 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5503 : auto self = Utils::OpenHandle(this);
5504 42 : if (!self->IsJSFunction()) {
5505 0 : return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5506 : }
5507 : auto func = i::Handle<i::JSFunction>::cast(self);
5508 : i::Handle<i::String> property_name =
5509 42 : isolate->factory()->NewStringFromStaticChars("displayName");
5510 : i::Handle<i::Object> value =
5511 42 : i::JSReceiver::GetDataProperty(func, property_name);
5512 42 : if (value->IsString()) {
5513 : i::Handle<i::String> name = i::Handle<i::String>::cast(value);
5514 18 : if (name->length() > 0) return Utils::ToLocal(name);
5515 : }
5516 24 : return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5517 : }
5518 :
5519 :
5520 12 : ScriptOrigin Function::GetScriptOrigin() const {
5521 : auto self = Utils::OpenHandle(this);
5522 12 : if (!self->IsJSFunction()) {
5523 : return v8::ScriptOrigin(Local<Value>());
5524 : }
5525 : auto func = i::Handle<i::JSFunction>::cast(self);
5526 12 : if (func->shared()->script()->IsScript()) {
5527 : i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5528 12 : return GetScriptOriginForScript(func->GetIsolate(), script);
5529 : }
5530 : return v8::ScriptOrigin(Local<Value>());
5531 : }
5532 :
5533 :
5534 : const int Function::kLineOffsetNotFound = -1;
5535 :
5536 :
5537 130851 : int Function::GetScriptLineNumber() const {
5538 : auto self = Utils::OpenHandle(this);
5539 130851 : if (!self->IsJSFunction()) {
5540 : return kLineOffsetNotFound;
5541 : }
5542 : auto func = i::Handle<i::JSFunction>::cast(self);
5543 130846 : if (func->shared()->script()->IsScript()) {
5544 : i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5545 130846 : return i::Script::GetLineNumber(script, func->shared()->start_position());
5546 : }
5547 : return kLineOffsetNotFound;
5548 : }
5549 :
5550 :
5551 124851 : int Function::GetScriptColumnNumber() const {
5552 : auto self = Utils::OpenHandle(this);
5553 124851 : if (!self->IsJSFunction()) {
5554 : return kLineOffsetNotFound;
5555 : }
5556 : auto func = i::Handle<i::JSFunction>::cast(self);
5557 124846 : if (func->shared()->script()->IsScript()) {
5558 : i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5559 124846 : return i::Script::GetColumnNumber(script, func->shared()->start_position());
5560 : }
5561 : return kLineOffsetNotFound;
5562 : }
5563 :
5564 :
5565 0 : bool Function::IsBuiltin() const {
5566 : auto self = Utils::OpenHandle(this);
5567 0 : if (!self->IsJSFunction()) {
5568 : return false;
5569 : }
5570 : auto func = i::Handle<i::JSFunction>::cast(self);
5571 0 : return !func->shared()->IsUserJavaScript();
5572 : }
5573 :
5574 :
5575 231562 : int Function::ScriptId() const {
5576 : auto self = Utils::OpenHandle(this);
5577 231562 : if (!self->IsJSFunction()) {
5578 : return v8::UnboundScript::kNoScriptId;
5579 : }
5580 : auto func = i::Handle<i::JSFunction>::cast(self);
5581 231557 : if (!func->shared()->script()->IsScript()) {
5582 : return v8::UnboundScript::kNoScriptId;
5583 : }
5584 : i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
5585 231437 : return script->id();
5586 : }
5587 :
5588 :
5589 237 : Local<v8::Value> Function::GetBoundFunction() const {
5590 : auto self = Utils::OpenHandle(this);
5591 237 : if (self->IsJSBoundFunction()) {
5592 : auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5593 : auto bound_target_function = i::handle(
5594 : bound_function->bound_target_function(), bound_function->GetIsolate());
5595 107 : return Utils::CallableToLocal(bound_target_function);
5596 : }
5597 130 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5598 : }
5599 :
5600 50 : int Name::GetIdentityHash() {
5601 : auto self = Utils::OpenHandle(this);
5602 50 : return static_cast<int>(self->Hash());
5603 : }
5604 :
5605 :
5606 123656538 : int String::Length() const {
5607 : i::Handle<i::String> str = Utils::OpenHandle(this);
5608 123656538 : return str->length();
5609 : }
5610 :
5611 :
5612 67 : bool String::IsOneByte() const {
5613 : i::Handle<i::String> str = Utils::OpenHandle(this);
5614 67 : return str->HasOnlyOneByteChars();
5615 : }
5616 :
5617 :
5618 : // Helpers for ContainsOnlyOneByteHelper
5619 : template<size_t size> struct OneByteMask;
5620 : template<> struct OneByteMask<4> {
5621 : static const uint32_t value = 0xFF00FF00;
5622 : };
5623 : template<> struct OneByteMask<8> {
5624 : static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
5625 : };
5626 : static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5627 : static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
5628 : static inline bool Unaligned(const uint16_t* chars) {
5629 45915 : return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5630 : }
5631 :
5632 :
5633 : static inline const uint16_t* Align(const uint16_t* chars) {
5634 : return reinterpret_cast<uint16_t*>(
5635 17885 : reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
5636 : }
5637 :
5638 : class ContainsOnlyOneByteHelper {
5639 : public:
5640 17885 : ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
5641 17885 : bool Check(i::String* string) {
5642 17885 : i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
5643 17885 : if (cons_string == nullptr) return is_one_byte_;
5644 30 : return CheckCons(cons_string);
5645 : }
5646 : void VisitOneByteString(const uint8_t* chars, int length) {
5647 : // Nothing to do.
5648 : }
5649 17885 : void VisitTwoByteString(const uint16_t* chars, int length) {
5650 : // Accumulated bits.
5651 : uintptr_t acc = 0;
5652 : // Align to uintptr_t.
5653 17885 : const uint16_t* end = chars + length;
5654 63800 : while (Unaligned(chars) && chars != end) {
5655 28030 : acc |= *chars++;
5656 : }
5657 : // Read word aligned in blocks,
5658 : // checking the return value at the end of each block.
5659 : const uint16_t* aligned_end = Align(end);
5660 : const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
5661 : const int inner_loops = 16;
5662 51475 : while (chars + inner_loops*increment < aligned_end) {
5663 396400 : for (int i = 0; i < inner_loops; i++) {
5664 396400 : acc |= *reinterpret_cast<const uintptr_t*>(chars);
5665 396400 : chars += increment;
5666 : }
5667 : // Check for early return.
5668 24775 : if ((acc & kOneByteMask) != 0) {
5669 9070 : is_one_byte_ = false;
5670 26955 : return;
5671 : }
5672 : }
5673 : // Read the rest.
5674 468120 : while (chars != end) {
5675 459305 : acc |= *chars++;
5676 : }
5677 : // Check result.
5678 8815 : if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5679 : }
5680 :
5681 : private:
5682 40 : bool CheckCons(i::ConsString* cons_string) {
5683 : while (true) {
5684 : // Check left side if flat.
5685 : i::String* left = cons_string->first();
5686 : i::ConsString* left_as_cons =
5687 39610 : i::String::VisitFlat(this, left, 0);
5688 39610 : if (!is_one_byte_) return false;
5689 : // Check right side if flat.
5690 : i::String* right = cons_string->second();
5691 : i::ConsString* right_as_cons =
5692 39610 : i::String::VisitFlat(this, right, 0);
5693 39610 : if (!is_one_byte_) return false;
5694 : // Standard recurse/iterate trick.
5695 39610 : if (left_as_cons != nullptr && right_as_cons != nullptr) {
5696 10 : if (left->length() < right->length()) {
5697 0 : CheckCons(left_as_cons);
5698 : cons_string = right_as_cons;
5699 : } else {
5700 10 : CheckCons(right_as_cons);
5701 : cons_string = left_as_cons;
5702 : }
5703 : // Check fast return.
5704 10 : if (!is_one_byte_) return false;
5705 : continue;
5706 : }
5707 : // Descend left in place.
5708 39600 : if (left_as_cons != nullptr) {
5709 : cons_string = left_as_cons;
5710 : continue;
5711 : }
5712 : // Descend right in place.
5713 19815 : if (right_as_cons != nullptr) {
5714 : cons_string = right_as_cons;
5715 : continue;
5716 : }
5717 : // Terminate.
5718 : break;
5719 : }
5720 : return is_one_byte_;
5721 : }
5722 : bool is_one_byte_;
5723 : DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
5724 : };
5725 :
5726 :
5727 17905 : bool String::ContainsOnlyOneByte() const {
5728 : i::Handle<i::String> str = Utils::OpenHandle(this);
5729 17905 : if (str->HasOnlyOneByteChars()) return true;
5730 : ContainsOnlyOneByteHelper helper;
5731 17885 : return helper.Check(*str);
5732 : }
5733 :
5734 :
5735 : class Utf8LengthHelper : public i::AllStatic {
5736 : public:
5737 : enum State {
5738 : kEndsWithLeadingSurrogate = 1 << 0,
5739 : kStartsWithTrailingSurrogate = 1 << 1,
5740 : kLeftmostEdgeIsCalculated = 1 << 2,
5741 : kRightmostEdgeIsCalculated = 1 << 3,
5742 : kLeftmostEdgeIsSurrogate = 1 << 4,
5743 : kRightmostEdgeIsSurrogate = 1 << 5
5744 : };
5745 :
5746 : static const uint8_t kInitialState = 0;
5747 :
5748 : static inline bool EndsWithSurrogate(uint8_t state) {
5749 1374657 : return state & kEndsWithLeadingSurrogate;
5750 : }
5751 :
5752 : static inline bool StartsWithSurrogate(uint8_t state) {
5753 931871 : return state & kStartsWithTrailingSurrogate;
5754 : }
5755 :
5756 : class Visitor {
5757 : public:
5758 10574371 : Visitor() : utf8_length_(0), state_(kInitialState) {}
5759 :
5760 : void VisitOneByteString(const uint8_t* chars, int length) {
5761 : int utf8_length = 0;
5762 : // Add in length 1 for each non-Latin1 character.
5763 81854103 : for (int i = 0; i < length; i++) {
5764 81854103 : utf8_length += *chars++ >> 7;
5765 : }
5766 : // Add in length 1 for each character.
5767 9438518 : utf8_length_ = utf8_length + length;
5768 9438518 : state_ = kInitialState;
5769 : }
5770 :
5771 369254 : void VisitTwoByteString(const uint16_t* chars, int length) {
5772 : int utf8_length = 0;
5773 : int last_character = unibrow::Utf16::kNoPreviousCharacter;
5774 3461258 : for (int i = 0; i < length; i++) {
5775 3092004 : uint16_t c = chars[i];
5776 3092004 : utf8_length += unibrow::Utf8::Length(c, last_character);
5777 3092004 : last_character = c;
5778 : }
5779 369254 : utf8_length_ = utf8_length;
5780 : uint8_t state = 0;
5781 738508 : if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
5782 : state |= kStartsWithTrailingSurrogate;
5783 : }
5784 738508 : if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
5785 408 : state |= kEndsWithLeadingSurrogate;
5786 : }
5787 369254 : state_ = state;
5788 369254 : }
5789 :
5790 : static i::ConsString* VisitFlat(i::String* string,
5791 : int* length,
5792 : uint8_t* state) {
5793 : Visitor visitor;
5794 10574371 : i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
5795 10574371 : *length = visitor.utf8_length_;
5796 1533198 : *state = visitor.state_;
5797 : return cons_string;
5798 : }
5799 :
5800 : private:
5801 : int utf8_length_;
5802 : uint8_t state_;
5803 : DISALLOW_COPY_AND_ASSIGN(Visitor);
5804 : };
5805 :
5806 442948 : static inline void MergeLeafLeft(int* length,
5807 : uint8_t* state,
5808 : uint8_t leaf_state) {
5809 : bool edge_surrogate = StartsWithSurrogate(leaf_state);
5810 442948 : if (!(*state & kLeftmostEdgeIsCalculated)) {
5811 : DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
5812 : *state |= kLeftmostEdgeIsCalculated
5813 165110 : | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
5814 277838 : } else if (EndsWithSurrogate(*state) && edge_surrogate) {
5815 12 : *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5816 : }
5817 442948 : if (EndsWithSurrogate(leaf_state)) {
5818 180 : *state |= kEndsWithLeadingSurrogate;
5819 : } else {
5820 442768 : *state &= ~kEndsWithLeadingSurrogate;
5821 : }
5822 442948 : }
5823 :
5824 488761 : static inline void MergeLeafRight(int* length,
5825 : uint8_t* state,
5826 : uint8_t leaf_state) {
5827 : bool edge_surrogate = EndsWithSurrogate(leaf_state);
5828 488761 : if (!(*state & kRightmostEdgeIsCalculated)) {
5829 : DCHECK(!(*state & kRightmostEdgeIsSurrogate));
5830 : *state |= (kRightmostEdgeIsCalculated
5831 165110 : | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
5832 323699 : } else if (edge_surrogate && StartsWithSurrogate(*state)) {
5833 18 : *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5834 : }
5835 488761 : if (StartsWithSurrogate(leaf_state)) {
5836 204 : *state |= kStartsWithTrailingSurrogate;
5837 : } else {
5838 488557 : *state &= ~kStartsWithTrailingSurrogate;
5839 : }
5840 488761 : }
5841 :
5842 165110 : static inline void MergeTerminal(int* length,
5843 : uint8_t state,
5844 : uint8_t* state_out) {
5845 : DCHECK((state & kLeftmostEdgeIsCalculated) &&
5846 : (state & kRightmostEdgeIsCalculated));
5847 165224 : if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
5848 0 : *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
5849 : }
5850 : *state_out = kInitialState |
5851 165110 : (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
5852 165110 : (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
5853 165110 : }
5854 :
5855 165110 : static int Calculate(i::ConsString* current, uint8_t* state_out) {
5856 : using internal::ConsString;
5857 165110 : int total_length = 0;
5858 165110 : uint8_t state = kInitialState;
5859 : while (true) {
5860 : i::String* left = current->first();
5861 : i::String* right = current->second();
5862 : uint8_t right_leaf_state;
5863 : uint8_t left_leaf_state;
5864 : int leaf_length;
5865 : ConsString* left_as_cons =
5866 : Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
5867 766599 : if (left_as_cons == nullptr) {
5868 440094 : total_length += leaf_length;
5869 440094 : MergeLeafLeft(&total_length, &state, left_leaf_state);
5870 : }
5871 : ConsString* right_as_cons =
5872 : Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
5873 766599 : if (right_as_cons == nullptr) {
5874 487435 : total_length += leaf_length;
5875 487435 : MergeLeafRight(&total_length, &state, right_leaf_state);
5876 487435 : if (left_as_cons != nullptr) {
5877 : // 1 Leaf node. Descend in place.
5878 : current = left_as_cons;
5879 597309 : continue;
5880 : } else {
5881 : // Terminal node.
5882 165110 : MergeTerminal(&total_length, state, state_out);
5883 165110 : return total_length;
5884 : }
5885 279164 : } else if (left_as_cons == nullptr) {
5886 : // 1 Leaf node. Descend in place.
5887 : current = right_as_cons;
5888 : continue;
5889 : }
5890 : // Both strings are ConsStrings.
5891 : // Recurse on smallest.
5892 4180 : if (left->length() < right->length()) {
5893 2854 : total_length += Calculate(left_as_cons, &left_leaf_state);
5894 2854 : MergeLeafLeft(&total_length, &state, left_leaf_state);
5895 : current = right_as_cons;
5896 : } else {
5897 1326 : total_length += Calculate(right_as_cons, &right_leaf_state);
5898 1326 : MergeLeafRight(&total_length, &state, right_leaf_state);
5899 : current = left_as_cons;
5900 : }
5901 : }
5902 : UNREACHABLE();
5903 : }
5904 :
5905 : static inline int Calculate(i::ConsString* current) {
5906 160930 : uint8_t state = kInitialState;
5907 160930 : return Calculate(current, &state);
5908 : }
5909 :
5910 : private:
5911 : DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
5912 : };
5913 :
5914 :
5915 9047684 : static int Utf8Length(i::String* str, i::Isolate* isolate) {
5916 : int length = str->length();
5917 9047684 : if (length == 0) return 0;
5918 : uint8_t state;
5919 : i::ConsString* cons_string =
5920 : Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
5921 9041173 : if (cons_string == nullptr) return length;
5922 : return Utf8LengthHelper::Calculate(cons_string);
5923 : }
5924 :
5925 :
5926 574 : int String::Utf8Length() const {
5927 : i::Handle<i::String> str = Utils::OpenHandle(this);
5928 : i::Isolate* isolate = str->GetIsolate();
5929 574 : return v8::Utf8Length(*str, isolate);
5930 : }
5931 :
5932 :
5933 : class Utf8WriterVisitor {
5934 : public:
5935 : Utf8WriterVisitor(
5936 : char* buffer,
5937 : int capacity,
5938 : bool skip_capacity_check,
5939 : bool replace_invalid_utf8)
5940 : : early_termination_(false),
5941 : last_character_(unibrow::Utf16::kNoPreviousCharacter),
5942 : buffer_(buffer),
5943 : start_(buffer),
5944 : capacity_(capacity),
5945 104 : skip_capacity_check_(capacity == -1 || skip_capacity_check),
5946 : replace_invalid_utf8_(replace_invalid_utf8),
5947 9047373 : utf16_chars_read_(0) {
5948 : }
5949 :
5950 220 : static int WriteEndCharacter(uint16_t character,
5951 : int last_character,
5952 : int remaining,
5953 : char* const buffer,
5954 : bool replace_invalid_utf8) {
5955 : DCHECK_GT(remaining, 0);
5956 : // We can't use a local buffer here because Encode needs to modify
5957 : // previous characters in the stream. We know, however, that
5958 : // exactly one character will be advanced.
5959 440 : if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
5960 : int written = unibrow::Utf8::Encode(buffer, character, last_character,
5961 0 : replace_invalid_utf8);
5962 : DCHECK_EQ(written, 1);
5963 0 : return written;
5964 : }
5965 : // Use a scratch buffer to check the required characters.
5966 : char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5967 : // Can't encode using last_character as gcc has array bounds issues.
5968 : int written = unibrow::Utf8::Encode(temp_buffer, character,
5969 : unibrow::Utf16::kNoPreviousCharacter,
5970 220 : replace_invalid_utf8);
5971 : // Won't fit.
5972 220 : if (written > remaining) return 0;
5973 : // Copy over the character from temp_buffer.
5974 245 : for (int j = 0; j < written; j++) {
5975 245 : buffer[j] = temp_buffer[j];
5976 : }
5977 : return written;
5978 : }
5979 :
5980 : // Visit writes out a group of code units (chars) of a v8::String to the
5981 : // internal buffer_. This is done in two phases. The first phase calculates a
5982 : // pesimistic estimate (writable_length) on how many code units can be safely
5983 : // written without exceeding the buffer capacity and without writing the last
5984 : // code unit (it could be a lead surrogate). The estimated number of code
5985 : // units is then written out in one go, and the reported byte usage is used
5986 : // to correct the estimate. This is repeated until the estimate becomes <= 0
5987 : // or all code units have been written out. The second phase writes out code
5988 : // units until the buffer capacity is reached, would be exceeded by the next
5989 : // unit, or all units have been written out.
5990 : template<typename Char>
5991 9564286 : void Visit(const Char* chars, const int length) {
5992 : DCHECK(!early_termination_);
5993 9564286 : if (length == 0) return;
5994 : // Copy state to stack.
5995 9556327 : char* buffer = buffer_;
5996 : int last_character = sizeof(Char) == 1
5997 : ? unibrow::Utf16::kNoPreviousCharacter
5998 120838 : : last_character_;
5999 : int i = 0;
6000 : // Do a fast loop where there is no exit capacity check.
6001 : while (true) {
6002 : int fast_length;
6003 9556375 : if (skip_capacity_check_) {
6004 : fast_length = length;
6005 : } else {
6006 146 : int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
6007 : // Need enough space to write everything but one character.
6008 : STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
6009 : 3);
6010 : int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
6011 : int writable_length =
6012 146 : (remaining_capacity - max_size_per_char)/max_size_per_char;
6013 : // Need to drop into slow loop.
6014 146 : if (writable_length <= 0) break;
6015 48 : fast_length = i + writable_length;
6016 48 : if (fast_length > length) fast_length = length;
6017 : }
6018 : // Write the characters to the stream.
6019 : if (sizeof(Char) == 1) {
6020 81839401 : for (; i < fast_length; i++) {
6021 81839401 : buffer += unibrow::Utf8::EncodeOneByte(
6022 81839401 : buffer, static_cast<uint8_t>(*chars++));
6023 : DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
6024 : }
6025 : } else {
6026 2925869 : for (; i < fast_length; i++) {
6027 2925869 : uint16_t character = *chars++;
6028 2925869 : buffer += unibrow::Utf8::Encode(buffer, character, last_character,
6029 2925869 : replace_invalid_utf8_);
6030 2925869 : last_character = character;
6031 : DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
6032 : }
6033 : }
6034 : // Array is fully written. Exit.
6035 9556277 : if (fast_length == length) {
6036 : // Write state back out to object.
6037 9556229 : last_character_ = last_character;
6038 9556229 : buffer_ = buffer;
6039 9556229 : utf16_chars_read_ += length;
6040 9556229 : return;
6041 : }
6042 : }
6043 : DCHECK(!skip_capacity_check_);
6044 : // Slow loop. Must check capacity on each iteration.
6045 : int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
6046 : DCHECK_GE(remaining_capacity, 0);
6047 177 : for (; i < length && remaining_capacity > 0; i++) {
6048 226 : uint16_t character = *chars++;
6049 : // remaining_capacity is <= 3 bytes at this point, so we do not write out
6050 : // an umatched lead surrogate.
6051 232 : if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
6052 6 : early_termination_ = true;
6053 6 : break;
6054 : }
6055 : int written = WriteEndCharacter(character,
6056 : last_character,
6057 : remaining_capacity,
6058 : buffer,
6059 220 : replace_invalid_utf8_);
6060 220 : if (written == 0) {
6061 43 : early_termination_ = true;
6062 43 : break;
6063 : }
6064 177 : buffer += written;
6065 177 : remaining_capacity -= written;
6066 : last_character = character;
6067 : }
6068 : // Write state back out to object.
6069 98 : last_character_ = last_character;
6070 98 : buffer_ = buffer;
6071 98 : utf16_chars_read_ += i;
6072 : }
6073 :
6074 : inline bool IsDone() {
6075 : return early_termination_;
6076 : }
6077 :
6078 : inline void VisitOneByteString(const uint8_t* chars, int length) {
6079 9443448 : Visit(chars, length);
6080 : }
6081 :
6082 : inline void VisitTwoByteString(const uint16_t* chars, int length) {
6083 120838 : Visit(chars, length);
6084 : }
6085 :
6086 9047263 : int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
6087 : // Write out number of utf16 characters written to the stream.
6088 9047263 : if (utf16_chars_read_out != nullptr) {
6089 168 : *utf16_chars_read_out = utf16_chars_read_;
6090 : }
6091 : // Only null terminate if all of the string was written and there's space.
6092 18094485 : if (write_null &&
6093 18094395 : !early_termination_ &&
6094 9047246 : (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
6095 9047130 : *buffer_++ = '\0';
6096 : }
6097 9047263 : return static_cast<int>(buffer_ - start_);
6098 : }
6099 :
6100 : private:
6101 : bool early_termination_;
6102 : int last_character_;
6103 : char* buffer_;
6104 : char* const start_;
6105 : int capacity_;
6106 : bool const skip_capacity_check_;
6107 : bool const replace_invalid_utf8_;
6108 : int utf16_chars_read_;
6109 : DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
6110 : };
6111 :
6112 :
6113 9564788 : static bool RecursivelySerializeToUtf8(i::String* current,
6114 10081811 : Utf8WriterVisitor* writer,
6115 : int recursion_budget) {
6116 19646599 : while (!writer->IsDone()) {
6117 10081811 : i::ConsString* cons_string = i::String::VisitFlat(writer, current);
6118 10081811 : if (cons_string == nullptr) return true; // Leaf node.
6119 517629 : if (recursion_budget <= 0) return false;
6120 : // Must write the left branch first.
6121 : i::String* first = cons_string->first();
6122 : bool success = RecursivelySerializeToUtf8(first,
6123 : writer,
6124 517623 : recursion_budget - 1);
6125 517623 : if (!success) return false;
6126 : // Inline tail recurse for right branch.
6127 : current = cons_string->second();
6128 : }
6129 : return true;
6130 : }
6131 :
6132 :
6133 9047291 : int String::WriteUtf8(char* buffer,
6134 : int capacity,
6135 : int* nchars_ref,
6136 : int options) const {
6137 : i::Handle<i::String> str = Utils::OpenHandle(this);
6138 9047291 : i::Isolate* isolate = str->GetIsolate();
6139 18094582 : LOG_API(isolate, String, WriteUtf8);
6140 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6141 9047291 : if (options & HINT_MANY_WRITES_EXPECTED) {
6142 0 : str = i::String::Flatten(str); // Flatten the string for efficiency.
6143 : }
6144 : const int string_length = str->length();
6145 9047291 : bool write_null = !(options & NO_NULL_TERMINATION);
6146 9047291 : bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
6147 : int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
6148 : // First check if we can just write the string without checking capacity.
6149 9047291 : if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
6150 : Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
6151 : const int kMaxRecursion = 100;
6152 9047165 : bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
6153 9047165 : if (success) return writer.CompleteWrite(write_null, nchars_ref);
6154 126 : } else if (capacity >= string_length) {
6155 : // First check that the buffer is large enough.
6156 77 : int utf8_bytes = v8::Utf8Length(*str, isolate);
6157 77 : if (utf8_bytes <= capacity) {
6158 : // one-byte fast path.
6159 28 : if (utf8_bytes == string_length) {
6160 : WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
6161 0 : if (nchars_ref != nullptr) *nchars_ref = string_length;
6162 0 : if (write_null && (utf8_bytes+1 <= capacity)) {
6163 0 : return string_length + 1;
6164 : }
6165 : return string_length;
6166 : }
6167 28 : if (write_null && (utf8_bytes+1 > capacity)) {
6168 23 : options |= NO_NULL_TERMINATION;
6169 : }
6170 : // Recurse once without a capacity limit.
6171 : // This will get into the first branch above.
6172 : // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
6173 28 : return WriteUtf8(buffer, -1, nchars_ref, options);
6174 : }
6175 : }
6176 : // Recursive slow path can potentially be unreasonable slow. Flatten.
6177 104 : str = i::String::Flatten(str);
6178 : Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
6179 104 : i::String::VisitFlat(&writer, *str);
6180 104 : return writer.CompleteWrite(write_null, nchars_ref);
6181 : }
6182 :
6183 :
6184 : template<typename CharType>
6185 41301478 : static inline int WriteHelper(const String* string,
6186 : CharType* buffer,
6187 : int start,
6188 : int length,
6189 : int options) {
6190 41301478 : i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
6191 82602956 : LOG_API(isolate, String, Write);
6192 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6193 : DCHECK(start >= 0 && length >= -1);
6194 : i::Handle<i::String> str = Utils::OpenHandle(string);
6195 41301478 : if (options & String::HINT_MANY_WRITES_EXPECTED) {
6196 : // Flatten the string for efficiency. This applies whether we are
6197 : // using StringCharacterStream or Get(i) to access the characters.
6198 0 : str = i::String::Flatten(str);
6199 : }
6200 41301478 : int end = start + length;
6201 82602849 : if ((length == -1) || (length > str->length() - start) )
6202 : end = str->length();
6203 41301478 : if (end < 0) return 0;
6204 41301478 : i::String::WriteToFlat(*str, buffer, start, end);
6205 41301479 : if (!(options & String::NO_NULL_TERMINATION) &&
6206 : (length == -1 || end - start < length)) {
6207 71 : buffer[end - start] = '\0';
6208 : }
6209 41301479 : return end - start;
6210 : }
6211 :
6212 :
6213 103 : int String::WriteOneByte(uint8_t* buffer,
6214 : int start,
6215 : int length,
6216 : int options) const {
6217 115 : return WriteHelper(this, buffer, start, length, options);
6218 : }
6219 :
6220 :
6221 41301357 : int String::Write(uint16_t* buffer,
6222 : int start,
6223 : int length,
6224 : int options) const {
6225 41301363 : return WriteHelper(this, buffer, start, length, options);
6226 : }
6227 :
6228 :
6229 107 : bool v8::String::IsExternal() const {
6230 : i::Handle<i::String> str = Utils::OpenHandle(this);
6231 107 : return i::StringShape(*str).IsExternalTwoByte();
6232 : }
6233 :
6234 :
6235 67 : bool v8::String::IsExternalOneByte() const {
6236 : i::Handle<i::String> str = Utils::OpenHandle(this);
6237 67 : return i::StringShape(*str).IsExternalOneByte();
6238 : }
6239 :
6240 :
6241 0 : void v8::String::VerifyExternalStringResource(
6242 : v8::String::ExternalStringResource* value) const {
6243 : i::Handle<i::String> str = Utils::OpenHandle(this);
6244 : const v8::String::ExternalStringResource* expected;
6245 0 : if (i::StringShape(*str).IsExternalTwoByte()) {
6246 : const void* resource =
6247 : i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
6248 : expected = reinterpret_cast<const ExternalStringResource*>(resource);
6249 : } else {
6250 : expected = nullptr;
6251 : }
6252 0 : CHECK_EQ(expected, value);
6253 0 : }
6254 :
6255 0 : void v8::String::VerifyExternalStringResourceBase(
6256 : v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
6257 : i::Handle<i::String> str = Utils::OpenHandle(this);
6258 : const v8::String::ExternalStringResourceBase* expected;
6259 : Encoding expectedEncoding;
6260 0 : if (i::StringShape(*str).IsExternalOneByte()) {
6261 : const void* resource =
6262 : i::Handle<i::ExternalOneByteString>::cast(str)->resource();
6263 : expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
6264 : expectedEncoding = ONE_BYTE_ENCODING;
6265 0 : } else if (i::StringShape(*str).IsExternalTwoByte()) {
6266 : const void* resource =
6267 : i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
6268 : expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
6269 : expectedEncoding = TWO_BYTE_ENCODING;
6270 : } else {
6271 : expected = nullptr;
6272 : expectedEncoding =
6273 0 : str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
6274 : }
6275 0 : CHECK_EQ(expected, value);
6276 0 : CHECK_EQ(expectedEncoding, encoding);
6277 0 : }
6278 :
6279 : const v8::String::ExternalOneByteStringResource*
6280 11 : v8::String::GetExternalOneByteStringResource() const {
6281 : i::Handle<i::String> str = Utils::OpenHandle(this);
6282 11 : if (i::StringShape(*str).IsExternalOneByte()) {
6283 : const void* resource =
6284 : i::Handle<i::ExternalOneByteString>::cast(str)->resource();
6285 11 : return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
6286 : } else {
6287 : return nullptr;
6288 : }
6289 : }
6290 :
6291 :
6292 184 : Local<Value> Symbol::Name() const {
6293 : i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
6294 : i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
6295 184 : return Utils::ToLocal(name);
6296 : }
6297 :
6298 :
6299 12 : Local<Value> Private::Name() const {
6300 12 : return reinterpret_cast<const Symbol*>(this)->Name();
6301 : }
6302 :
6303 :
6304 143737 : double Number::Value() const {
6305 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
6306 143737 : return obj->Number();
6307 : }
6308 :
6309 :
6310 9468999 : bool Boolean::Value() const {
6311 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
6312 9468999 : return obj->IsTrue(i::HeapObject::cast(*obj)->GetIsolate());
6313 : }
6314 :
6315 :
6316 1342 : int64_t Integer::Value() const {
6317 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
6318 19142 : if (obj->IsSmi()) {
6319 19118 : return i::Smi::ToInt(*obj);
6320 : } else {
6321 24 : return static_cast<int64_t>(obj->Number());
6322 : }
6323 : }
6324 :
6325 :
6326 24195 : int32_t Int32::Value() const {
6327 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
6328 24195 : if (obj->IsSmi()) {
6329 24195 : return i::Smi::ToInt(*obj);
6330 : } else {
6331 0 : return static_cast<int32_t>(obj->Number());
6332 : }
6333 : }
6334 :
6335 :
6336 42 : uint32_t Uint32::Value() const {
6337 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
6338 42 : if (obj->IsSmi()) {
6339 24 : return i::Smi::ToInt(*obj);
6340 : } else {
6341 18 : return static_cast<uint32_t>(obj->Number());
6342 : }
6343 : }
6344 :
6345 2343 : int v8::Object::InternalFieldCount() {
6346 : i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
6347 2343 : if (!self->IsJSObject()) return 0;
6348 2343 : return i::Handle<i::JSObject>::cast(self)->GetEmbedderFieldCount();
6349 : }
6350 :
6351 1997 : static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
6352 : const char* location) {
6353 : return Utils::ApiCheck(
6354 3994 : obj->IsJSObject() &&
6355 1997 : (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
6356 1997 : location, "Internal field out of bounds");
6357 : }
6358 :
6359 564 : Local<Value> v8::Object::SlowGetInternalField(int index) {
6360 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6361 : const char* location = "v8::Object::GetInternalField()";
6362 564 : if (!InternalFieldOK(obj, index, location)) return Local<Value>();
6363 : i::Handle<i::Object> value(
6364 : i::Handle<i::JSObject>::cast(obj)->GetEmbedderField(index),
6365 : obj->GetIsolate());
6366 : return Utils::ToLocal(value);
6367 : }
6368 :
6369 93 : void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
6370 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6371 : const char* location = "v8::Object::SetInternalField()";
6372 186 : if (!InternalFieldOK(obj, index, location)) return;
6373 : i::Handle<i::Object> val = Utils::OpenHandle(*value);
6374 93 : i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
6375 : }
6376 :
6377 220 : void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
6378 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6379 : const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
6380 220 : if (!InternalFieldOK(obj, index, location)) return nullptr;
6381 : return DecodeSmiToAligned(
6382 : i::Handle<i::JSObject>::cast(obj)->GetEmbedderField(index), location);
6383 : }
6384 :
6385 1120 : void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
6386 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6387 : const char* location = "v8::Object::SetAlignedPointerInInternalField()";
6388 2240 : if (!InternalFieldOK(obj, index, location)) return;
6389 : i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(
6390 1120 : index, EncodeAlignedAsSmi(value, location));
6391 : DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6392 : }
6393 :
6394 12 : void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
6395 : void* values[]) {
6396 : i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
6397 : const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
6398 : i::DisallowHeapAllocation no_gc;
6399 : i::JSObject* object = i::JSObject::cast(*obj);
6400 12 : int nof_embedder_fields = object->GetEmbedderFieldCount();
6401 36 : for (int i = 0; i < argc; i++) {
6402 24 : int index = indices[i];
6403 24 : if (!Utils::ApiCheck(index < nof_embedder_fields, location,
6404 24 : "Internal field out of bounds")) {
6405 12 : return;
6406 : }
6407 24 : void* value = values[i];
6408 24 : object->SetEmbedderField(index, EncodeAlignedAsSmi(value, location));
6409 : DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
6410 : }
6411 : }
6412 :
6413 11266170 : static void* ExternalValue(i::Object* obj) {
6414 : // Obscure semantics for undefined, but somehow checked in our unit tests...
6415 22532340 : if (!obj->IsSmi() &&
6416 : obj->IsUndefined(i::HeapObject::cast(obj)->GetIsolate())) {
6417 : return nullptr;
6418 : }
6419 : i::Object* foreign = i::JSObject::cast(obj)->GetEmbedderField(0);
6420 11266171 : return i::Foreign::cast(foreign)->foreign_address();
6421 : }
6422 :
6423 :
6424 : // --- E n v i r o n m e n t ---
6425 :
6426 :
6427 53977 : void v8::V8::InitializePlatform(Platform* platform) {
6428 53977 : i::V8::InitializePlatform(platform);
6429 53977 : }
6430 :
6431 :
6432 53151 : void v8::V8::ShutdownPlatform() {
6433 53151 : i::V8::ShutdownPlatform();
6434 53151 : }
6435 :
6436 :
6437 54331 : bool v8::V8::Initialize() {
6438 54331 : i::V8::Initialize();
6439 : #ifdef V8_USE_EXTERNAL_STARTUP_DATA
6440 54331 : i::ReadNatives();
6441 : #endif
6442 54331 : return true;
6443 : }
6444 :
6445 : #if V8_OS_POSIX
6446 0 : bool V8::TryHandleSignal(int signum, void* info, void* context) {
6447 : #if V8_OS_LINUX && V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
6448 : return v8::internal::trap_handler::TryHandleSignal(
6449 0 : signum, static_cast<siginfo_t*>(info), static_cast<ucontext_t*>(context));
6450 : #else // V8_OS_LINUX && V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
6451 : return false;
6452 : #endif
6453 : }
6454 : #endif
6455 :
6456 5131 : bool V8::RegisterDefaultSignalHandler() {
6457 5131 : return v8::internal::trap_handler::RegisterDefaultSignalHandler();
6458 : }
6459 :
6460 0 : void v8::V8::SetEntropySource(EntropySource entropy_source) {
6461 0 : base::RandomNumberGenerator::SetEntropySource(entropy_source);
6462 0 : }
6463 :
6464 :
6465 0 : void v8::V8::SetReturnAddressLocationResolver(
6466 : ReturnAddressLocationResolver return_address_resolver) {
6467 0 : i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
6468 0 : }
6469 :
6470 :
6471 29500 : bool v8::V8::Dispose() {
6472 29500 : i::V8::TearDown();
6473 : #ifdef V8_USE_EXTERNAL_STARTUP_DATA
6474 29500 : i::DisposeNatives();
6475 : #endif
6476 29500 : return true;
6477 : }
6478 :
6479 6 : HeapStatistics::HeapStatistics()
6480 : : total_heap_size_(0),
6481 : total_heap_size_executable_(0),
6482 : total_physical_size_(0),
6483 : total_available_size_(0),
6484 : used_heap_size_(0),
6485 : heap_size_limit_(0),
6486 : malloced_memory_(0),
6487 : peak_malloced_memory_(0),
6488 6 : does_zap_garbage_(0) {}
6489 :
6490 0 : HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
6491 : space_size_(0),
6492 : space_used_size_(0),
6493 : space_available_size_(0),
6494 0 : physical_space_size_(0) { }
6495 :
6496 :
6497 0 : HeapObjectStatistics::HeapObjectStatistics()
6498 : : object_type_(nullptr),
6499 : object_sub_type_(nullptr),
6500 : object_count_(0),
6501 0 : object_size_(0) {}
6502 :
6503 0 : HeapCodeStatistics::HeapCodeStatistics()
6504 0 : : code_and_metadata_size_(0), bytecode_and_metadata_size_(0) {}
6505 :
6506 0 : bool v8::V8::InitializeICU(const char* icu_data_file) {
6507 0 : return i::InitializeICU(icu_data_file);
6508 : }
6509 :
6510 51352 : bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
6511 : const char* icu_data_file) {
6512 51352 : return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
6513 : }
6514 :
6515 53983 : void v8::V8::InitializeExternalStartupData(const char* directory_path) {
6516 53983 : i::InitializeExternalStartupData(directory_path);
6517 53983 : }
6518 :
6519 :
6520 0 : void v8::V8::InitializeExternalStartupData(const char* natives_blob,
6521 : const char* snapshot_blob) {
6522 0 : i::InitializeExternalStartupData(natives_blob, snapshot_blob);
6523 0 : }
6524 :
6525 :
6526 36 : const char* v8::V8::GetVersion() {
6527 36 : return i::Version::GetVersion();
6528 : }
6529 :
6530 : template <typename ObjectType>
6531 : struct InvokeBootstrapper;
6532 :
6533 : template <>
6534 : struct InvokeBootstrapper<i::Context> {
6535 : i::Handle<i::Context> Invoke(
6536 78854 : i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6537 : v8::Local<v8::ObjectTemplate> global_proxy_template,
6538 : v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6539 : v8::DeserializeInternalFieldsCallback embedder_fields_deserializer) {
6540 : return isolate->bootstrapper()->CreateEnvironment(
6541 : maybe_global_proxy, global_proxy_template, extensions,
6542 78854 : context_snapshot_index, embedder_fields_deserializer);
6543 : }
6544 : };
6545 :
6546 : template <>
6547 : struct InvokeBootstrapper<i::JSGlobalProxy> {
6548 : i::Handle<i::JSGlobalProxy> Invoke(
6549 21 : i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
6550 : v8::Local<v8::ObjectTemplate> global_proxy_template,
6551 : v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
6552 : v8::DeserializeInternalFieldsCallback embedder_fields_deserializer) {
6553 : USE(extensions);
6554 : USE(context_snapshot_index);
6555 : return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
6556 21 : global_proxy_template);
6557 : }
6558 : };
6559 :
6560 : template <typename ObjectType>
6561 78875 : static i::Handle<ObjectType> CreateEnvironment(
6562 : i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
6563 : v8::MaybeLocal<ObjectTemplate> maybe_global_template,
6564 : v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
6565 : v8::DeserializeInternalFieldsCallback embedder_fields_deserializer) {
6566 : i::Handle<ObjectType> result;
6567 :
6568 : {
6569 : ENTER_V8_FOR_NEW_CONTEXT(isolate);
6570 : v8::Local<ObjectTemplate> proxy_template;
6571 : i::Handle<i::FunctionTemplateInfo> proxy_constructor;
6572 : i::Handle<i::FunctionTemplateInfo> global_constructor;
6573 : i::Handle<i::Object> named_interceptor(
6574 : isolate->factory()->undefined_value());
6575 : i::Handle<i::Object> indexed_interceptor(
6576 : isolate->factory()->undefined_value());
6577 :
6578 78875 : if (!maybe_global_template.IsEmpty()) {
6579 : v8::Local<v8::ObjectTemplate> global_template =
6580 : maybe_global_template.ToLocalChecked();
6581 : // Make sure that the global_template has a constructor.
6582 47955 : global_constructor = EnsureConstructor(isolate, *global_template);
6583 :
6584 : // Create a fresh template for the global proxy object.
6585 : proxy_template = ObjectTemplate::New(
6586 : reinterpret_cast<v8::Isolate*>(isolate));
6587 47955 : proxy_constructor = EnsureConstructor(isolate, *proxy_template);
6588 :
6589 : // Set the global template to be the prototype template of
6590 : // global proxy template.
6591 47955 : proxy_constructor->set_prototype_template(
6592 : *Utils::OpenHandle(*global_template));
6593 :
6594 47955 : proxy_template->SetInternalFieldCount(
6595 : global_template->InternalFieldCount());
6596 :
6597 : // Migrate security handlers from global_template to
6598 : // proxy_template. Temporarily removing access check
6599 : // information from the global template.
6600 47955 : if (!global_constructor->access_check_info()->IsUndefined(isolate)) {
6601 154 : proxy_constructor->set_access_check_info(
6602 : global_constructor->access_check_info());
6603 154 : proxy_constructor->set_needs_access_check(
6604 154 : global_constructor->needs_access_check());
6605 154 : global_constructor->set_needs_access_check(false);
6606 154 : global_constructor->set_access_check_info(
6607 154 : isolate->heap()->undefined_value());
6608 : }
6609 :
6610 : // Same for other interceptors. If the global constructor has
6611 : // interceptors, we need to replace them temporarily with noop
6612 : // interceptors, so the map is correctly marked as having interceptors,
6613 : // but we don't invoke any.
6614 47955 : if (!global_constructor->named_property_handler()->IsUndefined(isolate)) {
6615 : named_interceptor =
6616 : handle(global_constructor->named_property_handler(), isolate);
6617 144 : global_constructor->set_named_property_handler(
6618 144 : isolate->heap()->noop_interceptor_info());
6619 : }
6620 47955 : if (!global_constructor->indexed_property_handler()->IsUndefined(
6621 : isolate)) {
6622 : indexed_interceptor =
6623 : handle(global_constructor->indexed_property_handler(), isolate);
6624 0 : global_constructor->set_indexed_property_handler(
6625 0 : isolate->heap()->noop_interceptor_info());
6626 : }
6627 : }
6628 :
6629 : i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6630 78875 : if (!maybe_global_proxy.IsEmpty()) {
6631 : maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6632 : Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6633 : }
6634 : // Create the environment.
6635 : InvokeBootstrapper<ObjectType> invoke;
6636 : result =
6637 : invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6638 : context_snapshot_index, embedder_fields_deserializer);
6639 :
6640 : // Restore the access check info and interceptors on the global template.
6641 78875 : if (!maybe_global_template.IsEmpty()) {
6642 : DCHECK(!global_constructor.is_null());
6643 : DCHECK(!proxy_constructor.is_null());
6644 47955 : global_constructor->set_access_check_info(
6645 : proxy_constructor->access_check_info());
6646 47955 : global_constructor->set_needs_access_check(
6647 47955 : proxy_constructor->needs_access_check());
6648 47955 : global_constructor->set_named_property_handler(*named_interceptor);
6649 47955 : global_constructor->set_indexed_property_handler(*indexed_interceptor);
6650 : }
6651 : }
6652 : // Leave V8.
6653 :
6654 78875 : return result;
6655 : }
6656 :
6657 78854 : Local<Context> NewContext(
6658 : v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6659 : v8::MaybeLocal<ObjectTemplate> global_template,
6660 : v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6661 : v8::DeserializeInternalFieldsCallback embedder_fields_deserializer) {
6662 78854 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6663 : // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6664 : // fail.
6665 : // Sanity-check that the isolate is initialized and usable.
6666 78854 : CHECK(isolate->builtins()->builtin(i::Builtins::kIllegal)->IsCode());
6667 :
6668 157708 : TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6669 157708 : LOG_API(isolate, Context, New);
6670 : i::HandleScope scope(isolate);
6671 : ExtensionConfiguration no_extensions;
6672 78854 : if (extensions == nullptr) extensions = &no_extensions;
6673 : i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6674 : isolate, extensions, global_template, global_object,
6675 78854 : context_snapshot_index, embedder_fields_deserializer);
6676 78854 : if (env.is_null()) {
6677 60 : if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6678 60 : return Local<Context>();
6679 : }
6680 157648 : return Utils::ToLocal(scope.CloseAndEscape(env));
6681 : }
6682 :
6683 78758 : Local<Context> v8::Context::New(
6684 : v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6685 : v8::MaybeLocal<ObjectTemplate> global_template,
6686 : v8::MaybeLocal<Value> global_object,
6687 : DeserializeInternalFieldsCallback internal_fields_deserializer) {
6688 : return NewContext(external_isolate, extensions, global_template,
6689 78829 : global_object, 0, internal_fields_deserializer);
6690 : }
6691 :
6692 30 : MaybeLocal<Context> v8::Context::FromSnapshot(
6693 : v8::Isolate* external_isolate, size_t context_snapshot_index,
6694 : v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6695 : v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object) {
6696 30 : size_t index_including_default_context = context_snapshot_index + 1;
6697 30 : if (!i::Snapshot::HasContextSnapshot(
6698 : reinterpret_cast<i::Isolate*>(external_isolate),
6699 30 : index_including_default_context)) {
6700 5 : return MaybeLocal<Context>();
6701 : }
6702 : return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6703 : global_object, index_including_default_context,
6704 25 : embedder_fields_deserializer);
6705 : }
6706 :
6707 21 : MaybeLocal<Object> v8::Context::NewRemoteContext(
6708 : v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6709 : v8::MaybeLocal<v8::Value> global_object) {
6710 21 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6711 42 : LOG_API(isolate, Context, NewRemoteContext);
6712 : i::HandleScope scope(isolate);
6713 : i::Handle<i::FunctionTemplateInfo> global_constructor =
6714 21 : EnsureConstructor(isolate, *global_template);
6715 : Utils::ApiCheck(global_constructor->needs_access_check(),
6716 : "v8::Context::NewRemoteContext",
6717 : "Global template needs to have access checks enabled.");
6718 : i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6719 : i::AccessCheckInfo::cast(global_constructor->access_check_info()),
6720 : isolate);
6721 : Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
6722 : "v8::Context::NewRemoteContext",
6723 : "Global template needs to have access check handlers.");
6724 : i::Handle<i::JSGlobalProxy> global_proxy =
6725 : CreateEnvironment<i::JSGlobalProxy>(isolate, nullptr, global_template,
6726 : global_object, 0,
6727 21 : DeserializeInternalFieldsCallback());
6728 21 : if (global_proxy.is_null()) {
6729 0 : if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6730 0 : return MaybeLocal<Object>();
6731 : }
6732 : return Utils::ToLocal(
6733 21 : scope.CloseAndEscape(i::Handle<i::JSObject>::cast(global_proxy)));
6734 : }
6735 :
6736 257 : void v8::Context::SetSecurityToken(Local<Value> token) {
6737 : i::Handle<i::Context> env = Utils::OpenHandle(this);
6738 : i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6739 : env->set_security_token(*token_handle);
6740 257 : }
6741 :
6742 :
6743 0 : void v8::Context::UseDefaultSecurityToken() {
6744 : i::Handle<i::Context> env = Utils::OpenHandle(this);
6745 0 : env->set_security_token(env->global_object());
6746 0 : }
6747 :
6748 :
6749 10 : Local<Value> v8::Context::GetSecurityToken() {
6750 : i::Handle<i::Context> env = Utils::OpenHandle(this);
6751 : i::Isolate* isolate = env->GetIsolate();
6752 : i::Object* security_token = env->security_token();
6753 : i::Handle<i::Object> token_handle(security_token, isolate);
6754 10 : return Utils::ToLocal(token_handle);
6755 : }
6756 :
6757 :
6758 11078309 : v8::Isolate* Context::GetIsolate() {
6759 : i::Handle<i::Context> env = Utils::OpenHandle(this);
6760 11078309 : return reinterpret_cast<Isolate*>(env->GetIsolate());
6761 : }
6762 :
6763 356172 : v8::Local<v8::Object> Context::Global() {
6764 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6765 : i::Isolate* isolate = context->GetIsolate();
6766 356172 : i::Handle<i::Object> global(context->global_proxy(), isolate);
6767 : // TODO(dcarney): This should always return the global proxy
6768 : // but can't presently as calls to GetProtoype will return the wrong result.
6769 356172 : if (i::Handle<i::JSGlobalProxy>::cast(
6770 356172 : global)->IsDetachedFrom(context->global_object())) {
6771 65 : global = i::Handle<i::Object>(context->global_object(), isolate);
6772 : }
6773 356172 : return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6774 : }
6775 :
6776 :
6777 55 : void Context::DetachGlobal() {
6778 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6779 55 : i::Isolate* isolate = context->GetIsolate();
6780 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6781 55 : isolate->bootstrapper()->DetachGlobal(context);
6782 55 : }
6783 :
6784 :
6785 20 : Local<v8::Object> Context::GetExtrasBindingObject() {
6786 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6787 : i::Isolate* isolate = context->GetIsolate();
6788 : i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6789 20 : return Utils::ToLocal(binding);
6790 : }
6791 :
6792 :
6793 38 : void Context::AllowCodeGenerationFromStrings(bool allow) {
6794 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6795 : i::Isolate* isolate = context->GetIsolate();
6796 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6797 : context->set_allow_code_gen_from_strings(
6798 38 : allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
6799 38 : }
6800 :
6801 :
6802 5438 : bool Context::IsCodeGenerationFromStringsAllowed() {
6803 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6804 : return !context->allow_code_gen_from_strings()->IsFalse(
6805 5438 : context->GetIsolate());
6806 : }
6807 :
6808 :
6809 5 : void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6810 : i::Handle<i::Context> context = Utils::OpenHandle(this);
6811 : i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6812 : context->set_error_message_for_code_gen_from_strings(*error_handle);
6813 5 : }
6814 :
6815 0 : size_t Context::EstimatedSize() { return 0; }
6816 :
6817 2395 : MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6818 9580 : PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6819 2395 : auto self = Utils::OpenHandle(this);
6820 : Local<Object> result;
6821 : has_pending_exception =
6822 4790 : !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result);
6823 2395 : RETURN_ON_FAILED_EXECUTION(Object);
6824 2395 : RETURN_ESCAPED(result);
6825 : }
6826 :
6827 :
6828 0 : Local<v8::Object> ObjectTemplate::NewInstance() {
6829 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6830 0 : RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
6831 : }
6832 :
6833 :
6834 38367 : MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6835 153468 : PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6836 38367 : auto self = Utils::OpenHandle(this);
6837 : Local<Function> result;
6838 : has_pending_exception =
6839 76734 : !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6840 38367 : RETURN_ON_FAILED_EXECUTION(Function);
6841 38367 : RETURN_ESCAPED(result);
6842 : }
6843 :
6844 :
6845 0 : Local<v8::Function> FunctionTemplate::GetFunction() {
6846 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6847 0 : RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
6848 : }
6849 :
6850 9 : MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6851 : auto self = Utils::OpenHandle(this);
6852 9 : i::Isolate* isolate = self->GetIsolate();
6853 18 : LOG_API(isolate, FunctionTemplate, NewRemoteInstance);
6854 : i::HandleScope scope(isolate);
6855 : i::Handle<i::FunctionTemplateInfo> constructor =
6856 18 : EnsureConstructor(isolate, *InstanceTemplate());
6857 : Utils::ApiCheck(constructor->needs_access_check(),
6858 : "v8::FunctionTemplate::NewRemoteInstance",
6859 : "InstanceTemplate needs to have access checks enabled.");
6860 : i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6861 : i::AccessCheckInfo::cast(constructor->access_check_info()), isolate);
6862 : Utils::ApiCheck(access_check_info->named_interceptor() != nullptr,
6863 : "v8::FunctionTemplate::NewRemoteInstance",
6864 : "InstanceTemplate needs to have access check handlers.");
6865 : i::Handle<i::JSObject> object;
6866 9 : if (!i::ApiNatives::InstantiateRemoteObject(
6867 18 : Utils::OpenHandle(*InstanceTemplate()))
6868 18 : .ToHandle(&object)) {
6869 0 : if (isolate->has_pending_exception()) {
6870 0 : isolate->OptionalRescheduleException(true);
6871 : }
6872 0 : return MaybeLocal<Object>();
6873 : }
6874 9 : return Utils::ToLocal(scope.CloseAndEscape(object));
6875 : }
6876 :
6877 44 : bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6878 : auto self = Utils::OpenHandle(this);
6879 : auto obj = Utils::OpenHandle(*value);
6880 88 : if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6881 : return true;
6882 : }
6883 20 : if (obj->IsJSGlobalProxy()) {
6884 : // If it's a global proxy, then test with the global object. Note that the
6885 : // inner global object may not necessarily be a JSGlobalObject.
6886 2 : i::PrototypeIterator iter(i::JSObject::cast(*obj)->map());
6887 : // The global proxy should always have a prototype, as it is a bug to call
6888 : // this on a detached JSGlobalProxy.
6889 : DCHECK(!iter.IsAtEnd());
6890 4 : return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6891 : }
6892 : return false;
6893 : }
6894 :
6895 :
6896 9029 : Local<External> v8::External::New(Isolate* isolate, void* value) {
6897 : STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6898 9029 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6899 18058 : LOG_API(i_isolate, External, New);
6900 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6901 9029 : i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6902 9029 : return Utils::ExternalToLocal(external);
6903 : }
6904 :
6905 :
6906 11266170 : void* External::Value() const {
6907 11266170 : return ExternalValue(*Utils::OpenHandle(this));
6908 : }
6909 :
6910 :
6911 : // anonymous namespace for string creation helper functions
6912 : namespace {
6913 :
6914 : inline int StringLength(const char* string) {
6915 : return i::StrLength(string);
6916 : }
6917 :
6918 :
6919 : inline int StringLength(const uint8_t* string) {
6920 : return i::StrLength(reinterpret_cast<const char*>(string));
6921 : }
6922 :
6923 :
6924 : inline int StringLength(const uint16_t* string) {
6925 : int length = 0;
6926 4033 : while (string[length] != '\0')
6927 3985 : length++;
6928 : return length;
6929 : }
6930 :
6931 :
6932 : MUST_USE_RESULT
6933 18531684 : inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6934 : v8::NewStringType type,
6935 : i::Vector<const char> string) {
6936 18531684 : if (type == v8::NewStringType::kInternalized) {
6937 9634182 : return factory->InternalizeUtf8String(string);
6938 : }
6939 8897502 : return factory->NewStringFromUtf8(string);
6940 : }
6941 :
6942 :
6943 : MUST_USE_RESULT
6944 3252 : inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6945 : v8::NewStringType type,
6946 : i::Vector<const uint8_t> string) {
6947 3252 : if (type == v8::NewStringType::kInternalized) {
6948 280 : return factory->InternalizeOneByteString(string);
6949 : }
6950 2972 : return factory->NewStringFromOneByte(string);
6951 : }
6952 :
6953 :
6954 : MUST_USE_RESULT
6955 1376578 : inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6956 : v8::NewStringType type,
6957 : i::Vector<const uint16_t> string) {
6958 1376578 : if (type == v8::NewStringType::kInternalized) {
6959 0 : return factory->InternalizeTwoByteString(string);
6960 : }
6961 1376578 : return factory->NewStringFromTwoByte(string);
6962 : }
6963 :
6964 :
6965 : STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6966 :
6967 : } // anonymous namespace
6968 :
6969 : // TODO(dcarney): throw a context free exception.
6970 : #define NEW_STRING(isolate, class_name, function_name, Char, data, type, \
6971 : length) \
6972 : MaybeLocal<String> result; \
6973 : if (length == 0) { \
6974 : result = String::Empty(isolate); \
6975 : } else if (length > i::String::kMaxLength) { \
6976 : result = MaybeLocal<String>(); \
6977 : } else { \
6978 : i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6979 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); \
6980 : LOG_API(i_isolate, class_name, function_name); \
6981 : if (length < 0) length = StringLength(data); \
6982 : i::Handle<i::String> handle_result = \
6983 : NewString(i_isolate->factory(), type, \
6984 : i::Vector<const Char>(data, length)) \
6985 : .ToHandleChecked(); \
6986 : result = Utils::ToLocal(handle_result); \
6987 : }
6988 :
6989 0 : Local<String> String::NewFromUtf8(Isolate* isolate,
6990 : const char* data,
6991 : NewStringType type,
6992 : int length) {
6993 0 : NEW_STRING(isolate, String, NewFromUtf8, char, data,
6994 : static_cast<v8::NewStringType>(type), length);
6995 0 : RETURN_TO_LOCAL_UNCHECKED(result, String);
6996 : }
6997 :
6998 :
6999 18531694 : MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
7000 : v8::NewStringType type, int length) {
7001 111190119 : NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
7002 18531694 : return result;
7003 : }
7004 :
7005 :
7006 0 : Local<String> String::NewFromOneByte(Isolate* isolate,
7007 : const uint8_t* data,
7008 : NewStringType type,
7009 : int length) {
7010 0 : NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data,
7011 : static_cast<v8::NewStringType>(type), length);
7012 0 : RETURN_TO_LOCAL_UNCHECKED(result, String);
7013 : }
7014 :
7015 :
7016 3267 : MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
7017 : v8::NewStringType type, int length) {
7018 19532 : NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
7019 3267 : return result;
7020 : }
7021 :
7022 :
7023 0 : Local<String> String::NewFromTwoByte(Isolate* isolate,
7024 : const uint16_t* data,
7025 : NewStringType type,
7026 : int length) {
7027 0 : NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data,
7028 : static_cast<v8::NewStringType>(type), length);
7029 0 : RETURN_TO_LOCAL_UNCHECKED(result, String);
7030 : }
7031 :
7032 :
7033 1379069 : MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
7034 : const uint16_t* data,
7035 : v8::NewStringType type, int length) {
7036 8261964 : NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
7037 1379072 : return result;
7038 : }
7039 :
7040 :
7041 140539 : Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
7042 : i::Handle<i::String> left_string = Utils::OpenHandle(*left);
7043 140539 : i::Isolate* isolate = left_string->GetIsolate();
7044 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7045 281078 : LOG_API(isolate, String, Concat);
7046 : i::Handle<i::String> right_string = Utils::OpenHandle(*right);
7047 : // If we are steering towards a range error, do not wait for the error to be
7048 : // thrown, and return the null handle instead.
7049 140539 : if (left_string->length() + right_string->length() > i::String::kMaxLength) {
7050 5 : return Local<String>();
7051 : }
7052 : i::Handle<i::String> result = isolate->factory()->NewConsString(
7053 281068 : left_string, right_string).ToHandleChecked();
7054 : return Utils::ToLocal(result);
7055 : }
7056 :
7057 :
7058 18906 : MaybeLocal<String> v8::String::NewExternalTwoByte(
7059 : Isolate* isolate, v8::String::ExternalStringResource* resource) {
7060 18906 : CHECK(resource && resource->data());
7061 : // TODO(dcarney): throw a context free exception.
7062 18906 : if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
7063 6 : return MaybeLocal<String>();
7064 : }
7065 18900 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7066 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7067 37800 : LOG_API(i_isolate, String, NewExternalTwoByte);
7068 18900 : if (resource->length() > 0) {
7069 : i::Handle<i::String> string = i_isolate->factory()
7070 : ->NewExternalStringFromTwoByte(resource)
7071 37780 : .ToHandleChecked();
7072 : i_isolate->heap()->RegisterExternalString(*string);
7073 18890 : return Utils::ToLocal(string);
7074 : } else {
7075 : // The resource isn't going to be used, free it immediately.
7076 10 : resource->Dispose();
7077 10 : return Utils::ToLocal(i_isolate->factory()->empty_string());
7078 : }
7079 : }
7080 :
7081 :
7082 0 : Local<String> v8::String::NewExternal(
7083 : Isolate* isolate, v8::String::ExternalStringResource* resource) {
7084 0 : RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
7085 : }
7086 :
7087 :
7088 1255 : MaybeLocal<String> v8::String::NewExternalOneByte(
7089 : Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
7090 1255 : CHECK(resource && resource->data());
7091 : // TODO(dcarney): throw a context free exception.
7092 1255 : if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
7093 6 : return MaybeLocal<String>();
7094 : }
7095 1249 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7096 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7097 2498 : LOG_API(i_isolate, String, NewExternalOneByte);
7098 1249 : if (resource->length() > 0) {
7099 : i::Handle<i::String> string = i_isolate->factory()
7100 : ->NewExternalStringFromOneByte(resource)
7101 2488 : .ToHandleChecked();
7102 : i_isolate->heap()->RegisterExternalString(*string);
7103 1244 : return Utils::ToLocal(string);
7104 : } else {
7105 : // The resource isn't going to be used, free it immediately.
7106 5 : resource->Dispose();
7107 5 : return Utils::ToLocal(i_isolate->factory()->empty_string());
7108 : }
7109 : }
7110 :
7111 :
7112 0 : Local<String> v8::String::NewExternal(
7113 : Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
7114 0 : RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
7115 : }
7116 :
7117 :
7118 26 : bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
7119 : i::Handle<i::String> obj = Utils::OpenHandle(this);
7120 : i::Isolate* isolate = obj->GetIsolate();
7121 26 : if (i::StringShape(*obj).IsExternal()) {
7122 : return false; // Already an external string.
7123 : }
7124 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7125 26 : if (isolate->heap()->IsInGCPostProcessing()) {
7126 : return false;
7127 : }
7128 26 : CHECK(resource && resource->data());
7129 :
7130 26 : bool result = obj->MakeExternal(resource);
7131 : // Assert that if CanMakeExternal(), then externalizing actually succeeds.
7132 : DCHECK(!CanMakeExternal() || result);
7133 26 : if (result) {
7134 : DCHECK(obj->IsExternalString());
7135 : isolate->heap()->RegisterExternalString(*obj);
7136 : }
7137 26 : return result;
7138 : }
7139 :
7140 :
7141 31 : bool v8::String::MakeExternal(
7142 : v8::String::ExternalOneByteStringResource* resource) {
7143 : i::Handle<i::String> obj = Utils::OpenHandle(this);
7144 : i::Isolate* isolate = obj->GetIsolate();
7145 31 : if (i::StringShape(*obj).IsExternal()) {
7146 : return false; // Already an external string.
7147 : }
7148 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7149 31 : if (isolate->heap()->IsInGCPostProcessing()) {
7150 : return false;
7151 : }
7152 31 : CHECK(resource && resource->data());
7153 :
7154 31 : bool result = obj->MakeExternal(resource);
7155 : // Assert that if CanMakeExternal(), then externalizing actually succeeds.
7156 : DCHECK(!CanMakeExternal() || result);
7157 31 : if (result) {
7158 : DCHECK(obj->IsExternalString());
7159 : isolate->heap()->RegisterExternalString(*obj);
7160 : }
7161 31 : return result;
7162 : }
7163 :
7164 :
7165 20 : bool v8::String::CanMakeExternal() {
7166 : i::Handle<i::String> obj = Utils::OpenHandle(this);
7167 20 : if (obj->IsExternalString()) return false;
7168 :
7169 : // Old space strings should be externalized.
7170 : i::Isolate* isolate = obj->GetIsolate();
7171 20 : return !isolate->heap()->new_space()->Contains(*obj);
7172 : }
7173 :
7174 :
7175 0 : Isolate* v8::Object::GetIsolate() {
7176 : i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
7177 0 : return reinterpret_cast<Isolate*>(i_isolate);
7178 : }
7179 :
7180 :
7181 69414 : Local<v8::Object> v8::Object::New(Isolate* isolate) {
7182 69414 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7183 138828 : LOG_API(i_isolate, Object, New);
7184 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7185 : i::Handle<i::JSObject> obj =
7186 69414 : i_isolate->factory()->NewJSObject(i_isolate->object_function());
7187 69414 : return Utils::ToLocal(obj);
7188 : }
7189 :
7190 :
7191 6 : Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
7192 6 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7193 12 : LOG_API(i_isolate, NumberObject, New);
7194 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7195 6 : i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
7196 : i::Handle<i::Object> obj =
7197 12 : i::Object::ToObject(i_isolate, number).ToHandleChecked();
7198 6 : return Utils::ToLocal(obj);
7199 : }
7200 :
7201 :
7202 29 : double v8::NumberObject::ValueOf() const {
7203 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
7204 : i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
7205 29 : i::Isolate* isolate = jsvalue->GetIsolate();
7206 58 : LOG_API(isolate, NumberObject, NumberValue);
7207 29 : return jsvalue->value()->Number();
7208 : }
7209 :
7210 :
7211 24 : Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
7212 24 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7213 48 : LOG_API(i_isolate, BooleanObject, New);
7214 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7215 12 : i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
7216 12 : : i_isolate->heap()->false_value(),
7217 24 : i_isolate);
7218 : i::Handle<i::Object> obj =
7219 48 : i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
7220 24 : return Utils::ToLocal(obj);
7221 : }
7222 :
7223 :
7224 0 : Local<v8::Value> v8::BooleanObject::New(bool value) {
7225 0 : return New(Isolate::GetCurrent(), value);
7226 : }
7227 :
7228 :
7229 47 : bool v8::BooleanObject::ValueOf() const {
7230 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
7231 : i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
7232 47 : i::Isolate* isolate = jsvalue->GetIsolate();
7233 94 : LOG_API(isolate, BooleanObject, BooleanValue);
7234 47 : return jsvalue->value()->IsTrue(isolate);
7235 : }
7236 :
7237 :
7238 12 : Local<v8::Value> v8::StringObject::New(Local<String> value) {
7239 : i::Handle<i::String> string = Utils::OpenHandle(*value);
7240 12 : i::Isolate* isolate = string->GetIsolate();
7241 24 : LOG_API(isolate, StringObject, New);
7242 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7243 : i::Handle<i::Object> obj =
7244 24 : i::Object::ToObject(isolate, string).ToHandleChecked();
7245 12 : return Utils::ToLocal(obj);
7246 : }
7247 :
7248 :
7249 29 : Local<v8::String> v8::StringObject::ValueOf() const {
7250 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
7251 : i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
7252 29 : i::Isolate* isolate = jsvalue->GetIsolate();
7253 58 : LOG_API(isolate, StringObject, StringValue);
7254 : return Utils::ToLocal(
7255 29 : i::Handle<i::String>(i::String::cast(jsvalue->value())));
7256 : }
7257 :
7258 :
7259 6 : Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
7260 6 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7261 12 : LOG_API(i_isolate, SymbolObject, New);
7262 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7263 : i::Handle<i::Object> obj = i::Object::ToObject(
7264 12 : i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
7265 6 : return Utils::ToLocal(obj);
7266 : }
7267 :
7268 :
7269 11 : Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
7270 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
7271 : i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
7272 11 : i::Isolate* isolate = jsvalue->GetIsolate();
7273 22 : LOG_API(isolate, SymbolObject, SymbolValue);
7274 : return Utils::ToLocal(
7275 11 : i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
7276 : }
7277 :
7278 :
7279 132 : MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
7280 132 : if (std::isnan(time)) {
7281 : // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
7282 : time = std::numeric_limits<double>::quiet_NaN();
7283 : }
7284 528 : PREPARE_FOR_EXECUTION(context, Date, New, Value);
7285 : Local<Value> result;
7286 : has_pending_exception = !ToLocal<Value>(
7287 : i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
7288 396 : &result);
7289 132 : RETURN_ON_FAILED_EXECUTION(Value);
7290 132 : RETURN_ESCAPED(result);
7291 : }
7292 :
7293 :
7294 0 : Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
7295 0 : auto context = isolate->GetCurrentContext();
7296 0 : RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
7297 : }
7298 :
7299 :
7300 10 : double v8::Date::ValueOf() const {
7301 : i::Handle<i::Object> obj = Utils::OpenHandle(this);
7302 : i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
7303 10 : i::Isolate* isolate = jsdate->GetIsolate();
7304 20 : LOG_API(isolate, Date, NumberValue);
7305 10 : return jsdate->value()->Number();
7306 : }
7307 :
7308 :
7309 6 : void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
7310 18 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7311 12 : LOG_API(i_isolate, Date, DateTimeConfigurationChangeNotification);
7312 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7313 6 : i_isolate->date_cache()->ResetDateCache();
7314 6 : if (!i_isolate->eternal_handles()->Exists(
7315 : i::EternalHandles::DATE_CACHE_VERSION)) {
7316 6 : return;
7317 : }
7318 : i::Handle<i::FixedArray> date_cache_version =
7319 : i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
7320 : i::EternalHandles::DATE_CACHE_VERSION));
7321 : DCHECK_EQ(1, date_cache_version->length());
7322 6 : CHECK(date_cache_version->get(0)->IsSmi());
7323 : date_cache_version->set(
7324 6 : 0, i::Smi::FromInt(i::Smi::ToInt(date_cache_version->get(0)) + 1));
7325 : }
7326 :
7327 :
7328 97 : MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
7329 : Local<String> pattern, Flags flags) {
7330 388 : PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
7331 : Local<v8::RegExp> result;
7332 : has_pending_exception =
7333 : !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
7334 : static_cast<i::JSRegExp::Flags>(flags)),
7335 291 : &result);
7336 97 : RETURN_ON_FAILED_EXECUTION(RegExp);
7337 91 : RETURN_ESCAPED(result);
7338 : }
7339 :
7340 :
7341 0 : Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) {
7342 : auto isolate =
7343 : reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate());
7344 0 : auto context = isolate->GetCurrentContext();
7345 0 : RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp);
7346 : }
7347 :
7348 :
7349 40 : Local<v8::String> v8::RegExp::GetSource() const {
7350 : i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7351 40 : return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
7352 : }
7353 :
7354 :
7355 : // Assert that the static flags cast in GetFlags is valid.
7356 : #define REGEXP_FLAG_ASSERT_EQ(flag) \
7357 : STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
7358 : static_cast<int>(i::JSRegExp::flag))
7359 : REGEXP_FLAG_ASSERT_EQ(kNone);
7360 : REGEXP_FLAG_ASSERT_EQ(kGlobal);
7361 : REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
7362 : REGEXP_FLAG_ASSERT_EQ(kMultiline);
7363 : REGEXP_FLAG_ASSERT_EQ(kSticky);
7364 : REGEXP_FLAG_ASSERT_EQ(kUnicode);
7365 : #undef REGEXP_FLAG_ASSERT_EQ
7366 :
7367 40 : v8::RegExp::Flags v8::RegExp::GetFlags() const {
7368 : i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
7369 40 : return RegExp::Flags(static_cast<int>(obj->GetFlags()));
7370 : }
7371 :
7372 :
7373 17071 : Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
7374 17071 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7375 34142 : LOG_API(i_isolate, Array, New);
7376 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7377 17071 : int real_length = length > 0 ? length : 0;
7378 17071 : i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
7379 : i::Handle<i::Object> length_obj =
7380 17071 : i_isolate->factory()->NewNumberFromInt(real_length);
7381 17071 : obj->set_length(*length_obj);
7382 17071 : return Utils::ToLocal(obj);
7383 : }
7384 :
7385 :
7386 5415039 : uint32_t v8::Array::Length() const {
7387 : i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
7388 : i::Object* length = obj->length();
7389 5415039 : if (length->IsSmi()) {
7390 5415039 : return i::Smi::ToInt(length);
7391 : } else {
7392 0 : return static_cast<uint32_t>(length->Number());
7393 : }
7394 : }
7395 :
7396 :
7397 0 : MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
7398 : uint32_t index) {
7399 0 : PREPARE_FOR_EXECUTION(context, Array, CloneElementAt, Object);
7400 : auto self = Utils::OpenHandle(this);
7401 0 : if (!self->HasObjectElements()) return Local<Object>();
7402 : i::FixedArray* elms = i::FixedArray::cast(self->elements());
7403 0 : i::Object* paragon = elms->get(index);
7404 0 : if (!paragon->IsJSObject()) return Local<Object>();
7405 : i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
7406 : Local<Object> result;
7407 : has_pending_exception =
7408 : !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle),
7409 0 : &result);
7410 0 : RETURN_ON_FAILED_EXECUTION(Object);
7411 0 : RETURN_ESCAPED(result);
7412 : }
7413 :
7414 :
7415 0 : Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
7416 :
7417 :
7418 5 : Local<v8::Map> v8::Map::New(Isolate* isolate) {
7419 5 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7420 10 : LOG_API(i_isolate, Map, New);
7421 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7422 5 : i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
7423 5 : return Utils::ToLocal(obj);
7424 : }
7425 :
7426 :
7427 35 : size_t v8::Map::Size() const {
7428 : i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7429 35 : return i::OrderedHashMap::cast(obj->table())->NumberOfElements();
7430 : }
7431 :
7432 :
7433 5 : void Map::Clear() {
7434 : auto self = Utils::OpenHandle(this);
7435 5 : i::Isolate* isolate = self->GetIsolate();
7436 10 : LOG_API(isolate, Map, Clear);
7437 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7438 5 : i::JSMap::Clear(self);
7439 5 : }
7440 :
7441 :
7442 15 : MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
7443 60 : PREPARE_FOR_EXECUTION(context, Map, Get, Value);
7444 : auto self = Utils::OpenHandle(this);
7445 : Local<Value> result;
7446 15 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7447 : has_pending_exception =
7448 : !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
7449 : arraysize(argv), argv),
7450 45 : &result);
7451 15 : RETURN_ON_FAILED_EXECUTION(Value);
7452 15 : RETURN_ESCAPED(result);
7453 : }
7454 :
7455 :
7456 5 : MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
7457 : Local<Value> value) {
7458 20 : PREPARE_FOR_EXECUTION(context, Map, Set, Map);
7459 : auto self = Utils::OpenHandle(this);
7460 : i::Handle<i::Object> result;
7461 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
7462 10 : Utils::OpenHandle(*value)};
7463 : has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
7464 10 : arraysize(argv), argv)
7465 10 : .ToHandle(&result);
7466 5 : RETURN_ON_FAILED_EXECUTION(Map);
7467 5 : RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
7468 : }
7469 :
7470 :
7471 30 : Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
7472 30 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7473 120 : ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
7474 : auto self = Utils::OpenHandle(this);
7475 : i::Handle<i::Object> result;
7476 30 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7477 : has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
7478 60 : arraysize(argv), argv)
7479 60 : .ToHandle(&result);
7480 30 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7481 : return Just(result->IsTrue(isolate));
7482 : }
7483 :
7484 :
7485 15 : Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
7486 15 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7487 60 : ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
7488 : auto self = Utils::OpenHandle(this);
7489 : i::Handle<i::Object> result;
7490 15 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7491 : has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
7492 30 : self, arraysize(argv), argv)
7493 30 : .ToHandle(&result);
7494 15 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7495 : return Just(result->IsTrue(isolate));
7496 : }
7497 :
7498 : namespace {
7499 :
7500 : enum class MapAsArrayKind {
7501 : kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7502 : kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7503 : kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7504 : };
7505 :
7506 106 : i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
7507 : int offset, MapAsArrayKind kind) {
7508 : i::Factory* factory = isolate->factory();
7509 : i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj));
7510 106 : if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
7511 92 : int length = (table->NumberOfElements() - offset) *
7512 92 : (kind == MapAsArrayKind::kEntries ? 2 : 1);
7513 92 : i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
7514 : int result_index = 0;
7515 : {
7516 : i::DisallowHeapAllocation no_gc;
7517 92 : int capacity = table->UsedCapacity();
7518 92 : i::Oddball* the_hole = isolate->heap()->the_hole_value();
7519 5301 : for (int i = 0; i < capacity; ++i) {
7520 5209 : i::Object* key = table->KeyAt(i);
7521 5209 : if (key == the_hole) continue;
7522 5204 : if (offset-- > 0) continue;
7523 5189 : if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys) {
7524 10332 : result->set(result_index++, key);
7525 : }
7526 5189 : if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues) {
7527 10332 : result->set(result_index++, table->ValueAt(i));
7528 : }
7529 : }
7530 : }
7531 : DCHECK_EQ(result_index, result->length());
7532 : DCHECK_EQ(result_index, length);
7533 92 : return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
7534 : }
7535 :
7536 : } // namespace
7537 :
7538 49 : Local<Array> Map::AsArray() const {
7539 : i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7540 49 : i::Isolate* isolate = obj->GetIsolate();
7541 98 : LOG_API(isolate, Map, AsArray);
7542 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7543 : return Utils::ToLocal(
7544 98 : MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7545 : }
7546 :
7547 :
7548 405 : Local<v8::Set> v8::Set::New(Isolate* isolate) {
7549 405 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7550 810 : LOG_API(i_isolate, Set, New);
7551 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7552 405 : i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7553 405 : return Utils::ToLocal(obj);
7554 : }
7555 :
7556 :
7557 35 : size_t v8::Set::Size() const {
7558 : i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7559 35 : return i::OrderedHashSet::cast(obj->table())->NumberOfElements();
7560 : }
7561 :
7562 :
7563 5 : void Set::Clear() {
7564 : auto self = Utils::OpenHandle(this);
7565 5 : i::Isolate* isolate = self->GetIsolate();
7566 10 : LOG_API(isolate, Set, Clear);
7567 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7568 5 : i::JSSet::Clear(self);
7569 5 : }
7570 :
7571 :
7572 7345 : MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7573 29380 : PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7574 : auto self = Utils::OpenHandle(this);
7575 : i::Handle<i::Object> result;
7576 7345 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7577 : has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
7578 14690 : arraysize(argv), argv)
7579 14690 : .ToHandle(&result);
7580 7345 : RETURN_ON_FAILED_EXECUTION(Set);
7581 7345 : RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7582 : }
7583 :
7584 :
7585 30 : Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7586 30 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7587 120 : ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7588 : auto self = Utils::OpenHandle(this);
7589 : i::Handle<i::Object> result;
7590 30 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7591 : has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
7592 60 : arraysize(argv), argv)
7593 60 : .ToHandle(&result);
7594 30 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7595 : return Just(result->IsTrue(isolate));
7596 : }
7597 :
7598 :
7599 70 : Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7600 70 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7601 280 : ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7602 : auto self = Utils::OpenHandle(this);
7603 : i::Handle<i::Object> result;
7604 70 : i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7605 : has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
7606 140 : self, arraysize(argv), argv)
7607 140 : .ToHandle(&result);
7608 70 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7609 : return Just(result->IsTrue(isolate));
7610 : }
7611 :
7612 : namespace {
7613 485 : i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object* table_obj,
7614 : int offset) {
7615 : i::Factory* factory = isolate->factory();
7616 : i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj));
7617 485 : int length = table->NumberOfElements() - offset;
7618 485 : if (length <= 0) return factory->NewJSArray(0);
7619 480 : i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
7620 : int result_index = 0;
7621 : {
7622 : i::DisallowHeapAllocation no_gc;
7623 480 : int capacity = table->UsedCapacity();
7624 480 : i::Oddball* the_hole = isolate->heap()->the_hole_value();
7625 13090 : for (int i = 0; i < capacity; ++i) {
7626 12610 : i::Object* key = table->KeyAt(i);
7627 12610 : if (key == the_hole) continue;
7628 12550 : if (offset-- > 0) continue;
7629 25070 : result->set(result_index++, key);
7630 : }
7631 : }
7632 : DCHECK_EQ(result_index, result->length());
7633 : DCHECK_EQ(result_index, length);
7634 480 : return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
7635 : }
7636 : } // namespace
7637 :
7638 455 : Local<Array> Set::AsArray() const {
7639 : i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7640 455 : i::Isolate* isolate = obj->GetIsolate();
7641 910 : LOG_API(isolate, Set, AsArray);
7642 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7643 910 : return Utils::ToLocal(SetAsArray(isolate, obj->table(), 0));
7644 : }
7645 :
7646 :
7647 10092 : MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7648 40368 : PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7649 : i::Handle<i::Object> result;
7650 : has_pending_exception =
7651 : !i::Execution::Call(isolate, isolate->promise_internal_constructor(),
7652 20184 : isolate->factory()->undefined_value(), 0, nullptr)
7653 20184 : .ToHandle(&result);
7654 10092 : RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7655 9900 : RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
7656 : }
7657 :
7658 :
7659 0 : Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) {
7660 0 : RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()),
7661 : Promise::Resolver);
7662 : }
7663 :
7664 :
7665 10795 : Local<Promise> Promise::Resolver::GetPromise() {
7666 : i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7667 10795 : return Local<Promise>::Cast(Utils::ToLocal(promise));
7668 : }
7669 :
7670 :
7671 1464 : Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7672 : Local<Value> value) {
7673 1464 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7674 5856 : ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7675 : i::HandleScope);
7676 : auto self = Utils::OpenHandle(this);
7677 1464 : i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
7678 : has_pending_exception =
7679 : i::Execution::Call(isolate, isolate->promise_resolve(),
7680 : isolate->factory()->undefined_value(), arraysize(argv),
7681 2928 : argv)
7682 2928 : .is_null();
7683 1464 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7684 : return Just(true);
7685 : }
7686 :
7687 :
7688 0 : void Promise::Resolver::Resolve(Local<Value> value) {
7689 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7690 0 : USE(Resolve(context, value));
7691 0 : }
7692 :
7693 :
7694 7929 : Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7695 : Local<Value> value) {
7696 7929 : auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7697 31716 : ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7698 : i::HandleScope);
7699 : auto self = Utils::OpenHandle(this);
7700 :
7701 : // We pass true to trigger the debugger's on exception handler.
7702 : i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value),
7703 7929 : isolate->factory()->ToBoolean(true)};
7704 : has_pending_exception =
7705 : i::Execution::Call(isolate, isolate->promise_internal_reject(),
7706 : isolate->factory()->undefined_value(), arraysize(argv),
7707 15858 : argv)
7708 15858 : .is_null();
7709 7929 : RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7710 : return Just(true);
7711 : }
7712 :
7713 :
7714 0 : void Promise::Resolver::Reject(Local<Value> value) {
7715 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7716 0 : USE(Reject(context, value));
7717 0 : }
7718 :
7719 :
7720 525 : MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7721 : Local<Function> handler) {
7722 2100 : PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7723 : auto self = Utils::OpenHandle(this);
7724 : i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
7725 : i::Handle<i::Object> result;
7726 : has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
7727 1050 : self, arraysize(argv), argv)
7728 1050 : .ToHandle(&result);
7729 525 : RETURN_ON_FAILED_EXECUTION(Promise);
7730 525 : RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7731 : }
7732 :
7733 :
7734 0 : Local<Promise> Promise::Catch(Local<Function> handler) {
7735 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7736 0 : RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise);
7737 : }
7738 :
7739 :
7740 1098 : MaybeLocal<Promise> Promise::Then(Local<Context> context,
7741 : Local<Function> handler) {
7742 4392 : PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7743 : auto self = Utils::OpenHandle(this);
7744 : i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
7745 : i::Handle<i::Object> result;
7746 : has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
7747 2196 : self, arraysize(argv), argv)
7748 2196 : .ToHandle(&result);
7749 1098 : RETURN_ON_FAILED_EXECUTION(Promise);
7750 1098 : RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7751 : }
7752 :
7753 :
7754 0 : Local<Promise> Promise::Then(Local<Function> handler) {
7755 0 : auto context = ContextFromHeapObject(Utils::OpenHandle(this));
7756 0 : RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise);
7757 : }
7758 :
7759 :
7760 310 : bool Promise::HasHandler() {
7761 : i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7762 310 : i::Isolate* isolate = promise->GetIsolate();
7763 620 : LOG_API(isolate, Promise, HasRejectHandler);
7764 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7765 310 : if (promise->IsJSPromise()) {
7766 : i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7767 : return js_promise->has_handler();
7768 : }
7769 : return false;
7770 : }
7771 :
7772 10 : Local<Value> Promise::Result() {
7773 : i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7774 10 : i::Isolate* isolate = promise->GetIsolate();
7775 20 : LOG_API(isolate, Promise, Result);
7776 : i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7777 10 : Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7778 : "Promise is still pending");
7779 : i::Handle<i::Object> result(js_promise->result(), isolate);
7780 10 : return Utils::ToLocal(result);
7781 : }
7782 :
7783 234 : Promise::PromiseState Promise::State() {
7784 : i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7785 234 : i::Isolate* isolate = promise->GetIsolate();
7786 468 : LOG_API(isolate, Promise, Status);
7787 : i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7788 468 : return static_cast<PromiseState>(js_promise->status());
7789 : }
7790 :
7791 10 : Local<Object> Proxy::GetTarget() {
7792 : i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7793 : i::Handle<i::JSReceiver> target(self->target());
7794 10 : return Utils::ToLocal(target);
7795 : }
7796 :
7797 :
7798 10 : Local<Value> Proxy::GetHandler() {
7799 : i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7800 : i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7801 10 : return Utils::ToLocal(handler);
7802 : }
7803 :
7804 :
7805 10 : bool Proxy::IsRevoked() {
7806 : i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7807 10 : return self->IsRevoked();
7808 : }
7809 :
7810 :
7811 5 : void Proxy::Revoke() {
7812 5 : i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7813 5 : i::JSProxy::Revoke(self);
7814 5 : }
7815 :
7816 :
7817 17 : MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7818 : Local<Object> local_handler) {
7819 68 : PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7820 : i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7821 : i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7822 : Local<Proxy> result;
7823 : has_pending_exception =
7824 34 : !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7825 17 : RETURN_ON_FAILED_EXECUTION(Proxy);
7826 17 : RETURN_ESCAPED(result);
7827 : }
7828 :
7829 72 : Local<String> WasmCompiledModule::GetWasmWireBytes() {
7830 : i::Handle<i::WasmModuleObject> obj =
7831 : i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7832 : i::Handle<i::WasmCompiledModule> compiled_part =
7833 : i::handle(i::WasmCompiledModule::cast(obj->compiled_module()));
7834 : i::Handle<i::String> wire_bytes(compiled_part->module_bytes());
7835 72 : return Local<String>::Cast(Utils::ToLocal(wire_bytes));
7836 : }
7837 :
7838 : // Currently, wasm modules are bound, both to Isolate and to
7839 : // the Context they were created in. The currently-supported means to
7840 : // decontextualize and then re-contextualize a module is via
7841 : // serialization/deserialization.
7842 : WasmCompiledModule::TransferrableModule
7843 12 : WasmCompiledModule::GetTransferrableModule() {
7844 : i::DisallowHeapAllocation no_gc;
7845 12 : WasmCompiledModule::SerializedModule compiled_part = Serialize();
7846 :
7847 12 : Local<String> wire_bytes = GetWasmWireBytes();
7848 12 : size_t wire_size = static_cast<size_t>(wire_bytes->Length());
7849 12 : uint8_t* bytes = new uint8_t[wire_size];
7850 : wire_bytes->WriteOneByte(bytes, 0, wire_bytes->Length());
7851 :
7852 : return TransferrableModule(
7853 : std::move(compiled_part),
7854 : std::make_pair(
7855 : std::unique_ptr<const uint8_t[]>(const_cast<const uint8_t*>(bytes)),
7856 12 : wire_size));
7857 : }
7858 :
7859 10 : MaybeLocal<WasmCompiledModule> WasmCompiledModule::FromTransferrableModule(
7860 : Isolate* isolate,
7861 : const WasmCompiledModule::TransferrableModule& transferrable_module) {
7862 : MaybeLocal<WasmCompiledModule> ret =
7863 : Deserialize(isolate, AsCallerOwned(transferrable_module.compiled_code),
7864 20 : AsCallerOwned(transferrable_module.wire_bytes));
7865 10 : return ret;
7866 : }
7867 :
7868 48 : WasmCompiledModule::SerializedModule WasmCompiledModule::Serialize() {
7869 : i::Handle<i::WasmModuleObject> obj =
7870 : i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7871 : i::Handle<i::WasmCompiledModule> compiled_part =
7872 : i::handle(i::WasmCompiledModule::cast(obj->compiled_module()));
7873 :
7874 : std::unique_ptr<i::ScriptData> script_data =
7875 : i::WasmCompiledModuleSerializer::SerializeWasmModule(obj->GetIsolate(),
7876 48 : compiled_part);
7877 : script_data->ReleaseDataOwnership();
7878 :
7879 48 : size_t size = static_cast<size_t>(script_data->length());
7880 96 : return {std::unique_ptr<const uint8_t[]>(script_data->data()), size};
7881 : }
7882 :
7883 58 : MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
7884 : Isolate* isolate,
7885 : const WasmCompiledModule::CallerOwnedBuffer& serialized_module,
7886 : const WasmCompiledModule::CallerOwnedBuffer& wire_bytes) {
7887 58 : int size = static_cast<int>(serialized_module.second);
7888 58 : i::ScriptData sc(serialized_module.first, size);
7889 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7890 : i::MaybeHandle<i::FixedArray> maybe_compiled_part =
7891 : i::WasmCompiledModuleSerializer::DeserializeWasmModule(
7892 116 : i_isolate, &sc, {wire_bytes.first, wire_bytes.second});
7893 : i::Handle<i::FixedArray> compiled_part;
7894 58 : if (!maybe_compiled_part.ToHandle(&compiled_part)) {
7895 42 : return MaybeLocal<WasmCompiledModule>();
7896 : }
7897 : i::Handle<i::WasmCompiledModule> compiled_module =
7898 16 : handle(i::WasmCompiledModule::cast(*compiled_part));
7899 : return Local<WasmCompiledModule>::Cast(
7900 : Utils::ToLocal(i::Handle<i::JSObject>::cast(
7901 16 : i::WasmModuleObject::New(i_isolate, compiled_module))));
7902 : }
7903 :
7904 48 : MaybeLocal<WasmCompiledModule> WasmCompiledModule::DeserializeOrCompile(
7905 : Isolate* isolate,
7906 : const WasmCompiledModule::CallerOwnedBuffer& serialized_module,
7907 : const WasmCompiledModule::CallerOwnedBuffer& wire_bytes) {
7908 : MaybeLocal<WasmCompiledModule> ret =
7909 48 : Deserialize(isolate, serialized_module, wire_bytes);
7910 48 : if (!ret.IsEmpty()) {
7911 6 : return ret;
7912 : }
7913 42 : return Compile(isolate, wire_bytes.first, wire_bytes.second);
7914 : }
7915 :
7916 54 : MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
7917 : const uint8_t* start,
7918 : size_t length) {
7919 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7920 : i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Compile()");
7921 54 : if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
7922 6 : return MaybeLocal<WasmCompiledModule>();
7923 : }
7924 : i::MaybeHandle<i::JSObject> maybe_compiled = i::wasm::SyncCompile(
7925 96 : i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
7926 48 : if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
7927 : return Local<WasmCompiledModule>::Cast(
7928 36 : Utils::ToLocal(maybe_compiled.ToHandleChecked()));
7929 : }
7930 :
7931 0 : WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7932 : Isolate* isolate)
7933 0 : : isolate_(isolate) {
7934 : MaybeLocal<Promise::Resolver> maybe_resolver =
7935 0 : Promise::Resolver::New(isolate->GetCurrentContext());
7936 : Local<Promise::Resolver> resolver = maybe_resolver.ToLocalChecked();
7937 : promise_.Reset(isolate, resolver->GetPromise());
7938 :
7939 0 : if (i::FLAG_wasm_stream_compilation) {
7940 0 : i::Handle<i::JSPromise> promise = Utils::OpenHandle(*GetPromise());
7941 0 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7942 0 : streaming_decoder_ =
7943 : i_isolate->wasm_compilation_manager()->StartStreamingCompilation(
7944 : i_isolate, handle(i_isolate->context()), promise);
7945 : }
7946 0 : }
7947 :
7948 0 : Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() {
7949 0 : return promise_.Get(isolate_);
7950 : }
7951 :
7952 0 : void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7953 : size_t size) {
7954 0 : if (i::FLAG_wasm_stream_compilation) {
7955 0 : streaming_decoder_->OnBytesReceived(i::Vector<const uint8_t>(bytes, size));
7956 0 : return;
7957 : }
7958 0 : std::unique_ptr<uint8_t[]> cloned_bytes(new uint8_t[size]);
7959 : memcpy(cloned_bytes.get(), bytes, size);
7960 : received_buffers_.push_back(
7961 : Buffer(std::unique_ptr<const uint8_t[]>(
7962 : const_cast<const uint8_t*>(cloned_bytes.release())),
7963 0 : size));
7964 0 : total_size_ += size;
7965 : }
7966 :
7967 0 : void WasmModuleObjectBuilderStreaming::Finish() {
7968 0 : if (i::FLAG_wasm_stream_compilation) {
7969 0 : streaming_decoder_->Finish();
7970 0 : return;
7971 : }
7972 0 : std::unique_ptr<uint8_t[]> wire_bytes(new uint8_t[total_size_]);
7973 : uint8_t* insert_at = wire_bytes.get();
7974 :
7975 0 : for (size_t i = 0; i < received_buffers_.size(); ++i) {
7976 0 : const Buffer& buff = received_buffers_[i];
7977 0 : memcpy(insert_at, buff.first.get(), buff.second);
7978 0 : insert_at += buff.second;
7979 : }
7980 : // AsyncCompile makes its own copy of the wire bytes. This inefficiency
7981 : // will be resolved when we move to true streaming compilation.
7982 : i::wasm::AsyncCompile(reinterpret_cast<i::Isolate*>(isolate_),
7983 0 : Utils::OpenHandle(*promise_.Get(isolate_)),
7984 0 : {wire_bytes.get(), wire_bytes.get() + total_size_});
7985 : }
7986 :
7987 0 : void WasmModuleObjectBuilderStreaming::Abort(Local<Value> exception) {
7988 0 : Local<Promise> promise = GetPromise();
7989 : // The promise has already been resolved, e.g. because of a compilation
7990 : // error.
7991 0 : if (promise->State() != v8::Promise::kPending) return;
7992 0 : if (i::FLAG_wasm_stream_compilation) streaming_decoder_->Abort();
7993 :
7994 : Local<Promise::Resolver> resolver = promise.As<Promise::Resolver>();
7995 0 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
7996 : i::HandleScope scope(i_isolate);
7997 0 : Local<Context> context = Utils::ToLocal(handle(i_isolate->context()));
7998 0 : auto maybe = resolver->Reject(context, exception);
7999 0 : CHECK_IMPLIES(!maybe.FromMaybe(false), i_isolate->has_scheduled_exception());
8000 : }
8001 :
8002 0 : WasmModuleObjectBuilderStreaming::~WasmModuleObjectBuilderStreaming() {
8003 : promise_.Reset();
8004 0 : }
8005 :
8006 24 : void WasmModuleObjectBuilder::OnBytesReceived(const uint8_t* bytes,
8007 : size_t size) {
8008 24 : std::unique_ptr<uint8_t[]> cloned_bytes(new uint8_t[size]);
8009 : memcpy(cloned_bytes.get(), bytes, size);
8010 : received_buffers_.push_back(
8011 : Buffer(std::unique_ptr<const uint8_t[]>(
8012 : const_cast<const uint8_t*>(cloned_bytes.release())),
8013 48 : size));
8014 24 : total_size_ += size;
8015 24 : }
8016 :
8017 12 : MaybeLocal<WasmCompiledModule> WasmModuleObjectBuilder::Finish() {
8018 12 : std::unique_ptr<uint8_t[]> wire_bytes(new uint8_t[total_size_]);
8019 : uint8_t* insert_at = wire_bytes.get();
8020 :
8021 72 : for (size_t i = 0; i < received_buffers_.size(); ++i) {
8022 36 : const Buffer& buff = received_buffers_[i];
8023 24 : memcpy(insert_at, buff.first.get(), buff.second);
8024 24 : insert_at += buff.second;
8025 : }
8026 24 : return WasmCompiledModule::Compile(isolate_, wire_bytes.get(), total_size_);
8027 : }
8028 :
8029 : // static
8030 80076 : v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
8031 160152 : return new ArrayBufferAllocator();
8032 : }
8033 :
8034 71 : bool v8::ArrayBuffer::IsExternal() const {
8035 71 : return Utils::OpenHandle(this)->is_external();
8036 : }
8037 :
8038 :
8039 42 : bool v8::ArrayBuffer::IsNeuterable() const {
8040 42 : return Utils::OpenHandle(this)->is_neuterable();
8041 : }
8042 :
8043 :
8044 91 : v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
8045 : i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
8046 : i::Isolate* isolate = self->GetIsolate();
8047 : Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
8048 : "ArrayBuffer already externalized");
8049 : self->set_is_external(true);
8050 91 : isolate->heap()->UnregisterArrayBuffer(*self);
8051 :
8052 91 : return GetContents();
8053 : }
8054 :
8055 :
8056 304401 : v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
8057 : i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
8058 304401 : size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
8059 : Contents contents;
8060 304401 : contents.allocation_base_ = self->allocation_base();
8061 304401 : contents.allocation_length_ = self->allocation_length();
8062 : contents.allocation_mode_ = self->has_guard_region()
8063 : ? Allocator::AllocationMode::kReservation
8064 304401 : : Allocator::AllocationMode::kNormal;
8065 304401 : contents.data_ = self->backing_store();
8066 304401 : contents.byte_length_ = byte_length;
8067 304401 : return contents;
8068 : }
8069 :
8070 :
8071 40 : void v8::ArrayBuffer::Neuter() {
8072 : i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8073 40 : i::Isolate* isolate = obj->GetIsolate();
8074 : Utils::ApiCheck(obj->is_external(),
8075 : "v8::ArrayBuffer::Neuter",
8076 : "Only externalized ArrayBuffers can be neutered");
8077 : Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
8078 : "Only neuterable ArrayBuffers can be neutered");
8079 80 : LOG_API(isolate, ArrayBuffer, Neuter);
8080 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8081 40 : obj->Neuter();
8082 40 : }
8083 :
8084 :
8085 71 : size_t v8::ArrayBuffer::ByteLength() const {
8086 : i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8087 71 : return static_cast<size_t>(obj->byte_length()->Number());
8088 : }
8089 :
8090 :
8091 112 : Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
8092 112 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8093 224 : LOG_API(i_isolate, ArrayBuffer, New);
8094 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8095 : i::Handle<i::JSArrayBuffer> obj =
8096 112 : i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
8097 : // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8098 : // version that throws an exception or otherwise does not crash.
8099 112 : if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length)) {
8100 0 : i::FatalProcessOutOfMemory("v8::ArrayBuffer::New");
8101 : }
8102 112 : return Utils::ToLocal(obj);
8103 : }
8104 :
8105 :
8106 137 : Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
8107 : size_t byte_length,
8108 : ArrayBufferCreationMode mode) {
8109 : // Embedders must guarantee that the external backing store is valid.
8110 137 : CHECK(byte_length == 0 || data != nullptr);
8111 137 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8112 274 : LOG_API(i_isolate, ArrayBuffer, New);
8113 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8114 : i::Handle<i::JSArrayBuffer> obj =
8115 137 : i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
8116 : i::JSArrayBuffer::Setup(obj, i_isolate,
8117 : mode == ArrayBufferCreationMode::kExternalized, data,
8118 137 : byte_length);
8119 137 : return Utils::ToLocal(obj);
8120 : }
8121 :
8122 :
8123 652 : Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
8124 : i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8125 : i::Handle<i::JSArrayBuffer> buffer;
8126 652 : if (obj->IsJSDataView()) {
8127 : i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
8128 : DCHECK(data_view->buffer()->IsJSArrayBuffer());
8129 : buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
8130 : } else {
8131 : DCHECK(obj->IsJSTypedArray());
8132 638 : buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
8133 : }
8134 652 : return Utils::ToLocal(buffer);
8135 : }
8136 :
8137 :
8138 18 : size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
8139 : i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8140 18 : size_t byte_offset = i::NumberToSize(self->byte_offset());
8141 : size_t bytes_to_copy =
8142 18 : i::Min(byte_length, i::NumberToSize(self->byte_length()));
8143 18 : if (bytes_to_copy) {
8144 : i::DisallowHeapAllocation no_gc;
8145 : i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
8146 : const char* source = reinterpret_cast<char*>(buffer->backing_store());
8147 18 : if (source == nullptr) {
8148 : DCHECK(self->IsJSTypedArray());
8149 : i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self));
8150 : i::Handle<i::FixedTypedArrayBase> fixed_array(
8151 : i::FixedTypedArrayBase::cast(typed_array->elements()));
8152 : source = reinterpret_cast<char*>(fixed_array->DataPtr());
8153 : }
8154 18 : memcpy(dest, source + byte_offset, bytes_to_copy);
8155 : }
8156 18 : return bytes_to_copy;
8157 : }
8158 :
8159 :
8160 36 : bool v8::ArrayBufferView::HasBuffer() const {
8161 : i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
8162 : i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
8163 36 : return buffer->backing_store() != nullptr;
8164 : }
8165 :
8166 :
8167 832 : size_t v8::ArrayBufferView::ByteOffset() {
8168 : i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8169 832 : return static_cast<size_t>(obj->byte_offset()->Number());
8170 : }
8171 :
8172 :
8173 849 : size_t v8::ArrayBufferView::ByteLength() {
8174 : i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
8175 849 : return static_cast<size_t>(obj->byte_length()->Number());
8176 : }
8177 :
8178 :
8179 287 : size_t v8::TypedArray::Length() {
8180 : i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
8181 287 : return static_cast<size_t>(obj->length_value());
8182 : }
8183 :
8184 : static_assert(v8::TypedArray::kMaxLength == i::Smi::kMaxValue,
8185 : "v8::TypedArray::kMaxLength must match i::Smi::kMaxValue");
8186 :
8187 : #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
8188 : Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
8189 : size_t byte_offset, size_t length) { \
8190 : i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
8191 : LOG_API(isolate, Type##Array, New); \
8192 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
8193 : if (!Utils::ApiCheck(length <= kMaxLength, \
8194 : "v8::" #Type \
8195 : "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
8196 : "length exceeds max allowed value")) { \
8197 : return Local<Type##Array>(); \
8198 : } \
8199 : i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
8200 : i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
8201 : i::kExternal##Type##Array, buffer, byte_offset, length); \
8202 : return Utils::ToLocal##Type##Array(obj); \
8203 : } \
8204 : Local<Type##Array> Type##Array::New( \
8205 : Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
8206 : size_t length) { \
8207 : CHECK(i::FLAG_harmony_sharedarraybuffer); \
8208 : i::Isolate* isolate = \
8209 : Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
8210 : LOG_API(isolate, Type##Array, New); \
8211 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
8212 : if (!Utils::ApiCheck( \
8213 : length <= kMaxLength, \
8214 : "v8::" #Type \
8215 : "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
8216 : "length exceeds max allowed value")) { \
8217 : return Local<Type##Array>(); \
8218 : } \
8219 : i::Handle<i::JSArrayBuffer> buffer = \
8220 : Utils::OpenHandle(*shared_array_buffer); \
8221 : i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
8222 : i::kExternal##Type##Array, buffer, byte_offset, length); \
8223 : return Utils::ToLocal##Type##Array(obj); \
8224 : }
8225 :
8226 672 : TYPED_ARRAYS(TYPED_ARRAY_NEW)
8227 : #undef TYPED_ARRAY_NEW
8228 :
8229 17 : Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
8230 : size_t byte_offset, size_t byte_length) {
8231 : i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
8232 17 : i::Isolate* isolate = buffer->GetIsolate();
8233 34 : LOG_API(isolate, DataView, New);
8234 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8235 : i::Handle<i::JSDataView> obj =
8236 17 : isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8237 17 : return Utils::ToLocal(obj);
8238 : }
8239 :
8240 :
8241 6 : Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
8242 : size_t byte_offset, size_t byte_length) {
8243 6 : CHECK(i::FLAG_harmony_sharedarraybuffer);
8244 : i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
8245 6 : i::Isolate* isolate = buffer->GetIsolate();
8246 12 : LOG_API(isolate, DataView, New);
8247 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
8248 : i::Handle<i::JSDataView> obj =
8249 6 : isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
8250 6 : return Utils::ToLocal(obj);
8251 : }
8252 :
8253 :
8254 237 : bool v8::SharedArrayBuffer::IsExternal() const {
8255 237 : return Utils::OpenHandle(this)->is_external();
8256 : }
8257 :
8258 :
8259 104 : v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
8260 : i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
8261 : i::Isolate* isolate = self->GetIsolate();
8262 : Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
8263 : "SharedArrayBuffer already externalized");
8264 : self->set_is_external(true);
8265 104 : isolate->heap()->UnregisterArrayBuffer(*self);
8266 104 : return GetContents();
8267 : }
8268 :
8269 :
8270 121 : v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
8271 : i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
8272 225 : size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
8273 : Contents contents;
8274 225 : contents.data_ = self->backing_store();
8275 225 : contents.byte_length_ = byte_length;
8276 : // SharedArrayBuffers never have guard regions, so their allocation and data
8277 : // are equivalent.
8278 225 : contents.allocation_base_ = self->backing_store();
8279 225 : contents.allocation_length_ = byte_length;
8280 : contents.allocation_mode_ =
8281 : ArrayBufferAllocator::Allocator::AllocationMode::kNormal;
8282 121 : return contents;
8283 : }
8284 :
8285 :
8286 18 : size_t v8::SharedArrayBuffer::ByteLength() const {
8287 : i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
8288 18 : return static_cast<size_t>(obj->byte_length()->Number());
8289 : }
8290 :
8291 :
8292 12 : Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
8293 : size_t byte_length) {
8294 12 : CHECK(i::FLAG_harmony_sharedarraybuffer);
8295 12 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8296 24 : LOG_API(i_isolate, SharedArrayBuffer, New);
8297 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8298 : i::Handle<i::JSArrayBuffer> obj =
8299 12 : i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
8300 : // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
8301 : // version that throws an exception or otherwise does not crash.
8302 12 : if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true,
8303 12 : i::SharedFlag::kShared)) {
8304 0 : i::FatalProcessOutOfMemory("v8::SharedArrayBuffer::New");
8305 : }
8306 12 : return Utils::ToLocalShared(obj);
8307 : }
8308 :
8309 :
8310 277 : Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
8311 : Isolate* isolate, void* data, size_t byte_length,
8312 : ArrayBufferCreationMode mode) {
8313 277 : CHECK(i::FLAG_harmony_sharedarraybuffer);
8314 : // Embedders must guarantee that the external backing store is valid.
8315 277 : CHECK(byte_length == 0 || data != nullptr);
8316 277 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8317 554 : LOG_API(i_isolate, SharedArrayBuffer, New);
8318 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8319 : i::Handle<i::JSArrayBuffer> obj =
8320 277 : i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
8321 : i::JSArrayBuffer::Setup(obj, i_isolate,
8322 : mode == ArrayBufferCreationMode::kExternalized, data,
8323 277 : byte_length, i::SharedFlag::kShared);
8324 277 : return Utils::ToLocalShared(obj);
8325 : }
8326 :
8327 :
8328 136 : Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
8329 136 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8330 272 : LOG_API(i_isolate, Symbol, New);
8331 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8332 136 : i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8333 183 : if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
8334 136 : return Utils::ToLocal(result);
8335 : }
8336 :
8337 :
8338 24 : Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8339 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8340 24 : i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8341 : return Utils::ToLocal(i_isolate->SymbolFor(
8342 24 : i::Heap::kPublicSymbolTableRootIndex, i_name, false));
8343 : }
8344 :
8345 :
8346 24 : Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8347 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8348 24 : i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8349 : return Utils::ToLocal(
8350 24 : i_isolate->SymbolFor(i::Heap::kApiSymbolTableRootIndex, i_name, false));
8351 : }
8352 :
8353 : #define WELL_KNOWN_SYMBOLS(V) \
8354 : V(HasInstance, has_instance) \
8355 : V(IsConcatSpreadable, is_concat_spreadable) \
8356 : V(Iterator, iterator) \
8357 : V(Match, match) \
8358 : V(Replace, replace) \
8359 : V(Search, search) \
8360 : V(Split, split) \
8361 : V(ToPrimitive, to_primitive) \
8362 : V(ToStringTag, to_string_tag) \
8363 : V(Unscopables, unscopables)
8364 :
8365 : #define SYMBOL_GETTER(Name, name) \
8366 : Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) { \
8367 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8368 : return Utils::ToLocal(i_isolate->factory()->name##_symbol()); \
8369 : }
8370 :
8371 91300 : WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8372 :
8373 : #undef SYMBOL_GETTER
8374 : #undef WELL_KNOWN_SYMBOLS
8375 :
8376 74 : Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8377 74 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8378 148 : LOG_API(i_isolate, Private, New);
8379 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8380 74 : i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8381 136 : if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
8382 : Local<Symbol> result = Utils::ToLocal(symbol);
8383 148 : return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8384 : }
8385 :
8386 :
8387 9634839 : Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8388 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8389 9634839 : i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8390 : Local<Symbol> result = Utils::ToLocal(i_isolate->SymbolFor(
8391 9634839 : i::Heap::kApiPrivateSymbolTableRootIndex, i_name, true));
8392 9634839 : return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8393 : }
8394 :
8395 :
8396 36586 : Local<Number> v8::Number::New(Isolate* isolate, double value) {
8397 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8398 36586 : if (std::isnan(value)) {
8399 : // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8400 : value = std::numeric_limits<double>::quiet_NaN();
8401 : }
8402 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8403 36586 : i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8404 36586 : return Utils::NumberToLocal(result);
8405 : }
8406 :
8407 :
8408 736161 : Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8409 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8410 : if (i::Smi::IsValid(value)) {
8411 : return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
8412 : internal_isolate));
8413 : }
8414 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8415 : i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8416 : return Utils::IntegerToLocal(result);
8417 : }
8418 :
8419 :
8420 137 : Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8421 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8422 137 : bool fits_into_int32_t = (value & (1 << 31)) == 0;
8423 137 : if (fits_into_int32_t) {
8424 31 : return Integer::New(isolate, static_cast<int32_t>(value));
8425 : }
8426 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8427 106 : i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8428 : return Utils::IntegerToLocal(result);
8429 : }
8430 :
8431 :
8432 354 : void Isolate::ReportExternalAllocationLimitReached() {
8433 354 : i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8434 708 : if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8435 354 : heap->ReportExternalMemoryPressure();
8436 : }
8437 :
8438 1350 : void Isolate::CheckMemoryPressure() {
8439 1350 : i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8440 2700 : if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8441 1350 : heap->CheckMemoryPressure();
8442 : }
8443 :
8444 7137 : HeapProfiler* Isolate::GetHeapProfiler() {
8445 : i::HeapProfiler* heap_profiler =
8446 : reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8447 7137 : return reinterpret_cast<HeapProfiler*>(heap_profiler);
8448 : }
8449 :
8450 :
8451 0 : CpuProfiler* Isolate::GetCpuProfiler() {
8452 : i::CpuProfiler* cpu_profiler =
8453 : reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
8454 0 : return reinterpret_cast<CpuProfiler*>(cpu_profiler);
8455 : }
8456 :
8457 :
8458 136846 : bool Isolate::InContext() {
8459 136846 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8460 136846 : return isolate->context() != nullptr;
8461 : }
8462 :
8463 :
8464 28976720 : v8::Local<v8::Context> Isolate::GetCurrentContext() {
8465 28976720 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8466 : i::Context* context = isolate->context();
8467 28976720 : if (context == nullptr) return Local<Context>();
8468 : i::Context* native_context = context->native_context();
8469 28976696 : if (native_context == nullptr) return Local<Context>();
8470 : return Utils::ToLocal(i::Handle<i::Context>(native_context));
8471 : }
8472 :
8473 :
8474 0 : v8::Local<v8::Context> Isolate::GetCallingContext() {
8475 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8476 0 : i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
8477 0 : if (calling.is_null()) return Local<Context>();
8478 : return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
8479 : }
8480 :
8481 :
8482 45681 : v8::Local<v8::Context> Isolate::GetEnteredContext() {
8483 45681 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8484 : i::Handle<i::Object> last =
8485 45681 : isolate->handle_scope_implementer()->LastEnteredContext();
8486 45681 : if (last.is_null()) return Local<Context>();
8487 : return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8488 : }
8489 :
8490 0 : v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8491 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8492 : i::Handle<i::Object> last;
8493 0 : if (isolate->handle_scope_implementer()
8494 : ->MicrotaskContextIsLastEnteredContext()) {
8495 0 : last = isolate->handle_scope_implementer()->MicrotaskContext();
8496 : } else {
8497 0 : last = isolate->handle_scope_implementer()->LastEnteredContext();
8498 : }
8499 0 : if (last.is_null()) return Local<Context>();
8500 : return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8501 : }
8502 :
8503 0 : v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8504 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8505 0 : i::Handle<i::Context> context = isolate->GetIncumbentContext();
8506 0 : return Utils::ToLocal(context);
8507 : }
8508 :
8509 7634 : v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8510 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8511 : ENTER_V8_DO_NOT_USE(isolate);
8512 : // If we're passed an empty handle, we throw an undefined exception
8513 : // to deal more gracefully with out of memory situations.
8514 7634 : if (value.IsEmpty()) {
8515 24 : isolate->ScheduleThrow(isolate->heap()->undefined_value());
8516 : } else {
8517 7610 : isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8518 : }
8519 15268 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8520 : }
8521 :
8522 10 : void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8523 : GCType gc_type) {
8524 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8525 40 : isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8526 10 : }
8527 :
8528 10 : void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8529 : void* data) {
8530 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8531 35 : isolate->heap()->RemoveGCPrologueCallback(callback, data);
8532 10 : }
8533 :
8534 10 : void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8535 : GCType gc_type) {
8536 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8537 35 : isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8538 10 : }
8539 :
8540 10 : void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8541 : void* data) {
8542 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8543 35 : isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8544 10 : }
8545 :
8546 92 : static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8547 : GCCallbackFlags flags, void* data) {
8548 92 : reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8549 92 : }
8550 :
8551 30 : void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8552 : void* data = reinterpret_cast<void*>(callback);
8553 : AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8554 30 : }
8555 :
8556 25 : void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8557 : void* data = reinterpret_cast<void*>(callback);
8558 : RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8559 25 : }
8560 :
8561 25 : void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8562 : void* data = reinterpret_cast<void*>(callback);
8563 : AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8564 25 : }
8565 :
8566 25 : void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8567 : void* data = reinterpret_cast<void*>(callback);
8568 : RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8569 25 : }
8570 :
8571 0 : static void CallGCCallbackWithoutIsolate(Isolate* isolate, GCType type,
8572 : GCCallbackFlags flags, void* data) {
8573 0 : reinterpret_cast<v8::GCCallback>(data)(type, flags);
8574 0 : }
8575 :
8576 0 : void V8::AddGCPrologueCallback(v8::GCCallback callback, GCType gc_type) {
8577 : void* data = reinterpret_cast<void*>(callback);
8578 : Isolate::GetCurrent()->AddGCPrologueCallback(CallGCCallbackWithoutIsolate,
8579 : data, gc_type);
8580 0 : }
8581 :
8582 0 : void V8::AddGCEpilogueCallback(v8::GCCallback callback, GCType gc_type) {
8583 : void* data = reinterpret_cast<void*>(callback);
8584 : Isolate::GetCurrent()->AddGCEpilogueCallback(CallGCCallbackWithoutIsolate,
8585 : data, gc_type);
8586 0 : }
8587 :
8588 0 : void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8589 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8590 0 : isolate->heap()->SetEmbedderHeapTracer(tracer);
8591 0 : }
8592 :
8593 0 : void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8594 : GetExternallyAllocatedMemoryInBytesCallback callback) {
8595 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8596 : isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8597 0 : }
8598 :
8599 1118 : void Isolate::TerminateExecution() {
8600 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8601 1118 : isolate->stack_guard()->RequestTerminateExecution();
8602 1118 : }
8603 :
8604 :
8605 1440 : bool Isolate::IsExecutionTerminating() {
8606 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8607 1440 : return IsExecutionTerminatingCheck(isolate);
8608 : }
8609 :
8610 :
8611 12 : void Isolate::CancelTerminateExecution() {
8612 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8613 12 : isolate->stack_guard()->ClearTerminateExecution();
8614 12 : isolate->CancelTerminateExecution();
8615 12 : }
8616 :
8617 :
8618 107 : void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8619 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8620 107 : isolate->RequestInterrupt(callback, data);
8621 107 : }
8622 :
8623 :
8624 9520 : void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8625 9520 : CHECK(i::FLAG_expose_gc);
8626 9520 : if (type == kMinorGarbageCollection) {
8627 : reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8628 : i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8629 120 : kGCCallbackFlagForced);
8630 : } else {
8631 : DCHECK_EQ(kFullGarbageCollection, type);
8632 : reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
8633 : i::Heap::kAbortIncrementalMarkingMask,
8634 9400 : i::GarbageCollectionReason::kTesting, kGCCallbackFlagForced);
8635 : }
8636 9520 : }
8637 :
8638 :
8639 667743 : Isolate* Isolate::GetCurrent() {
8640 : i::Isolate* isolate = i::Isolate::Current();
8641 667743 : return reinterpret_cast<Isolate*>(isolate);
8642 : }
8643 :
8644 :
8645 54723 : Isolate* Isolate::New(const Isolate::CreateParams& params) {
8646 54723 : i::Isolate* isolate = new i::Isolate(false);
8647 54723 : return IsolateNewImpl(isolate, params);
8648 : }
8649 :
8650 : // This is separate so that tests can provide a different |isolate|.
8651 54818 : Isolate* IsolateNewImpl(internal::Isolate* isolate,
8652 : const v8::Isolate::CreateParams& params) {
8653 : Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
8654 54818 : CHECK_NOT_NULL(params.array_buffer_allocator);
8655 : isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8656 54818 : if (params.snapshot_blob != nullptr) {
8657 : isolate->set_snapshot_blob(params.snapshot_blob);
8658 : } else {
8659 54708 : isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8660 : }
8661 54818 : if (params.entry_hook) {
8662 : #ifdef V8_USE_SNAPSHOT
8663 : // Setting a FunctionEntryHook is only supported in no-snapshot builds.
8664 : Utils::ApiCheck(
8665 : false, "v8::Isolate::New",
8666 : "Setting a FunctionEntryHook is only supported in no-snapshot builds.");
8667 : #endif
8668 0 : isolate->set_function_entry_hook(params.entry_hook);
8669 : }
8670 54818 : auto code_event_handler = params.code_event_handler;
8671 : #ifdef ENABLE_GDB_JIT_INTERFACE
8672 54818 : if (code_event_handler == nullptr && i::FLAG_gdbjit) {
8673 : code_event_handler = i::GDBJITInterface::EventHandler;
8674 : }
8675 : #endif // ENABLE_GDB_JIT_INTERFACE
8676 54818 : if (code_event_handler) {
8677 0 : isolate->InitializeLoggingAndCounters();
8678 : isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
8679 0 : code_event_handler);
8680 : }
8681 54818 : if (params.counter_lookup_callback) {
8682 : v8_isolate->SetCounterFunction(params.counter_lookup_callback);
8683 : }
8684 :
8685 54818 : if (params.create_histogram_callback) {
8686 : v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8687 : }
8688 :
8689 54818 : if (params.add_histogram_sample_callback) {
8690 : v8_isolate->SetAddHistogramSampleFunction(
8691 : params.add_histogram_sample_callback);
8692 : }
8693 :
8694 54818 : isolate->set_api_external_references(params.external_references);
8695 54818 : isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8696 :
8697 54818 : SetResourceConstraints(isolate, params.constraints);
8698 : // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
8699 : Isolate::Scope isolate_scope(v8_isolate);
8700 54818 : if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
8701 : base::ElapsedTimer timer;
8702 0 : if (i::FLAG_profile_deserialization) timer.Start();
8703 0 : isolate->Init(nullptr);
8704 0 : if (i::FLAG_profile_deserialization) {
8705 0 : double ms = timer.Elapsed().InMillisecondsF();
8706 0 : i::PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
8707 : }
8708 : }
8709 54818 : return v8_isolate;
8710 : }
8711 :
8712 :
8713 53370 : void Isolate::Dispose() {
8714 53370 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8715 106740 : if (!Utils::ApiCheck(!isolate->IsInUse(),
8716 : "v8::Isolate::Dispose()",
8717 : "Disposing the isolate that is entered by a thread.")) {
8718 53370 : return;
8719 : }
8720 53365 : isolate->TearDown();
8721 : }
8722 :
8723 0 : void Isolate::DumpAndResetStats() {
8724 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8725 0 : isolate->DumpAndResetStats();
8726 0 : }
8727 :
8728 1500 : void Isolate::DiscardThreadSpecificMetadata() {
8729 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8730 1500 : isolate->DiscardPerThreadDataForThisThread();
8731 1499 : }
8732 :
8733 :
8734 130626 : void Isolate::Enter() {
8735 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8736 185565 : isolate->Enter();
8737 130617 : }
8738 :
8739 :
8740 130608 : void Isolate::Exit() {
8741 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8742 185547 : isolate->Exit();
8743 130606 : }
8744 :
8745 :
8746 5 : void Isolate::SetAbortOnUncaughtExceptionCallback(
8747 : AbortOnUncaughtExceptionCallback callback) {
8748 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8749 5 : isolate->SetAbortOnUncaughtExceptionCallback(callback);
8750 5 : }
8751 :
8752 27400 : void Isolate::SetHostImportModuleDynamicallyCallback(
8753 : HostImportModuleDynamicallyCallback callback) {
8754 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8755 27400 : isolate->SetHostImportModuleDynamicallyCallback(callback);
8756 27400 : }
8757 :
8758 27400 : void Isolate::SetHostInitializeImportMetaObjectCallback(
8759 : HostInitializeImportMetaObjectCallback callback) {
8760 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8761 27400 : isolate->SetHostInitializeImportMetaObjectCallback(callback);
8762 27400 : }
8763 :
8764 1610391 : Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8765 : Isolate* isolate,
8766 : Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8767 1610391 : : on_failure_(on_failure) {
8768 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8769 1610391 : if (on_failure_ == CRASH_ON_FAILURE) {
8770 : internal_ = reinterpret_cast<void*>(
8771 5 : new i::DisallowJavascriptExecution(i_isolate));
8772 : } else {
8773 : DCHECK_EQ(THROW_ON_FAILURE, on_failure);
8774 : internal_ = reinterpret_cast<void*>(
8775 1610386 : new i::ThrowOnJavascriptExecution(i_isolate));
8776 : }
8777 1610391 : }
8778 :
8779 :
8780 1610391 : Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8781 1610391 : if (on_failure_ == CRASH_ON_FAILURE) {
8782 5 : delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
8783 : } else {
8784 1610386 : delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
8785 : }
8786 1610391 : }
8787 :
8788 :
8789 780519 : Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8790 : Isolate* isolate) {
8791 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8792 : internal_assert_ = reinterpret_cast<void*>(
8793 780519 : new i::AllowJavascriptExecution(i_isolate));
8794 : internal_throws_ = reinterpret_cast<void*>(
8795 780519 : new i::NoThrowOnJavascriptExecution(i_isolate));
8796 780519 : }
8797 :
8798 :
8799 780519 : Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8800 780519 : delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
8801 780519 : delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
8802 780519 : }
8803 :
8804 :
8805 98363 : Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8806 : Isolate* isolate)
8807 98363 : : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
8808 196726 : isolate_->handle_scope_implementer()->IncrementCallDepth();
8809 98363 : isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
8810 98363 : }
8811 :
8812 :
8813 98362 : Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8814 196724 : isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
8815 98362 : isolate_->handle_scope_implementer()->DecrementCallDepth();
8816 98362 : }
8817 :
8818 :
8819 6 : void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8820 12 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8821 12 : i::Heap* heap = isolate->heap();
8822 6 : heap_statistics->total_heap_size_ = heap->CommittedMemory();
8823 : heap_statistics->total_heap_size_executable_ =
8824 6 : heap->CommittedMemoryExecutable();
8825 6 : heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8826 6 : heap_statistics->total_available_size_ = heap->Available();
8827 6 : heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8828 6 : heap_statistics->heap_size_limit_ = heap->MaxReserved();
8829 : heap_statistics->malloced_memory_ =
8830 6 : isolate->allocator()->GetCurrentMemoryUsage();
8831 : heap_statistics->peak_malloced_memory_ =
8832 6 : isolate->allocator()->GetMaxMemoryUsage();
8833 6 : heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8834 6 : }
8835 :
8836 :
8837 0 : size_t Isolate::NumberOfHeapSpaces() {
8838 0 : return i::LAST_SPACE - i::FIRST_SPACE + 1;
8839 : }
8840 :
8841 :
8842 0 : bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8843 : size_t index) {
8844 0 : if (!space_statistics) return false;
8845 0 : if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8846 : return false;
8847 :
8848 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8849 0 : i::Heap* heap = isolate->heap();
8850 0 : i::Space* space = heap->space(static_cast<int>(index));
8851 :
8852 0 : space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index));
8853 0 : space_statistics->space_size_ = space->CommittedMemory();
8854 0 : space_statistics->space_used_size_ = space->SizeOfObjects();
8855 0 : space_statistics->space_available_size_ = space->Available();
8856 0 : space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8857 0 : return true;
8858 : }
8859 :
8860 :
8861 0 : size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8862 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8863 0 : i::Heap* heap = isolate->heap();
8864 0 : return heap->NumberOfTrackedHeapObjectTypes();
8865 : }
8866 :
8867 :
8868 0 : bool Isolate::GetHeapObjectStatisticsAtLastGC(
8869 : HeapObjectStatistics* object_statistics, size_t type_index) {
8870 0 : if (!object_statistics) return false;
8871 0 : if (V8_LIKELY(!i::FLAG_gc_stats)) return false;
8872 :
8873 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8874 0 : i::Heap* heap = isolate->heap();
8875 0 : if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8876 :
8877 : const char* object_type;
8878 : const char* object_sub_type;
8879 0 : size_t object_count = heap->ObjectCountAtLastGC(type_index);
8880 0 : size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8881 0 : if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8882 : // There should be no objects counted when the type is unknown.
8883 : DCHECK_EQ(object_count, 0U);
8884 : DCHECK_EQ(object_size, 0U);
8885 : return false;
8886 : }
8887 :
8888 0 : object_statistics->object_type_ = object_type;
8889 0 : object_statistics->object_sub_type_ = object_sub_type;
8890 0 : object_statistics->object_count_ = object_count;
8891 0 : object_statistics->object_size_ = object_size;
8892 0 : return true;
8893 : }
8894 :
8895 0 : bool Isolate::GetHeapCodeAndMetadataStatistics(
8896 : HeapCodeStatistics* code_statistics) {
8897 0 : if (!code_statistics) return false;
8898 :
8899 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8900 0 : isolate->heap()->CollectCodeStatistics();
8901 :
8902 0 : code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8903 : code_statistics->bytecode_and_metadata_size_ =
8904 0 : isolate->bytecode_and_metadata_size();
8905 0 : return true;
8906 : }
8907 :
8908 18 : void Isolate::GetStackSample(const RegisterState& state, void** frames,
8909 : size_t frames_limit, SampleInfo* sample_info) {
8910 18 : RegisterState regs = state;
8911 18 : if (TickSample::GetStackSample(this, ®s, TickSample::kSkipCEntryFrame,
8912 : frames, frames_limit, sample_info)) {
8913 18 : return;
8914 : }
8915 0 : sample_info->frames_count = 0;
8916 0 : sample_info->vm_state = OTHER;
8917 0 : sample_info->external_callback_entry = nullptr;
8918 : }
8919 :
8920 15 : size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
8921 15 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8922 15 : size_t result = isolate->global_handles()->NumberOfPhantomHandleResets();
8923 : isolate->global_handles()->ResetNumberOfPhantomHandleResets();
8924 15 : return result;
8925 : }
8926 :
8927 5 : void Isolate::SetEventLogger(LogEventCallback that) {
8928 : // Do not overwrite the event logger if we want to log explicitly.
8929 10 : if (i::FLAG_log_internal_timer_events) return;
8930 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8931 : isolate->set_event_logger(that);
8932 : }
8933 :
8934 :
8935 15 : void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
8936 30 : if (callback == nullptr) return;
8937 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8938 15 : isolate->AddBeforeCallEnteredCallback(callback);
8939 : }
8940 :
8941 :
8942 5 : void Isolate::RemoveBeforeCallEnteredCallback(
8943 : BeforeCallEnteredCallback callback) {
8944 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8945 5 : isolate->RemoveBeforeCallEnteredCallback(callback);
8946 5 : }
8947 :
8948 :
8949 25 : void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
8950 50 : if (callback == nullptr) return;
8951 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8952 25 : isolate->AddCallCompletedCallback(callback);
8953 : }
8954 :
8955 :
8956 5 : void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
8957 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8958 5 : isolate->RemoveCallCompletedCallback(callback);
8959 5 : }
8960 :
8961 :
8962 0 : void Isolate::AddCallCompletedCallback(
8963 : DeprecatedCallCompletedCallback callback) {
8964 : AddCallCompletedCallback(reinterpret_cast<CallCompletedCallback>(callback));
8965 0 : }
8966 :
8967 :
8968 0 : void Isolate::RemoveCallCompletedCallback(
8969 : DeprecatedCallCompletedCallback callback) {
8970 : RemoveCallCompletedCallback(
8971 : reinterpret_cast<CallCompletedCallback>(callback));
8972 0 : }
8973 :
8974 10 : void Isolate::SetPromiseHook(PromiseHook hook) {
8975 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8976 10 : isolate->SetPromiseHook(hook);
8977 10 : }
8978 :
8979 813 : void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
8980 1626 : if (callback == nullptr) return;
8981 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8982 813 : isolate->SetPromiseRejectCallback(callback);
8983 : }
8984 :
8985 :
8986 35432 : void Isolate::RunMicrotasks() {
8987 : DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
8988 35432 : reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
8989 35432 : }
8990 :
8991 :
8992 123 : void Isolate::EnqueueMicrotask(Local<Function> microtask) {
8993 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8994 123 : isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
8995 123 : }
8996 :
8997 :
8998 356 : void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
8999 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9000 : i::HandleScope scope(isolate);
9001 : i::Handle<i::CallHandlerInfo> callback_info =
9002 : i::Handle<i::CallHandlerInfo>::cast(
9003 356 : isolate->factory()->NewStruct(i::TUPLE2_TYPE, i::NOT_TENURED));
9004 712 : SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
9005 712 : SET_FIELD_WRAPPED(callback_info, set_data, data);
9006 356 : isolate->EnqueueMicrotask(callback_info);
9007 356 : }
9008 :
9009 :
9010 0 : void Isolate::SetAutorunMicrotasks(bool autorun) {
9011 : SetMicrotasksPolicy(
9012 0 : autorun ? MicrotasksPolicy::kAuto : MicrotasksPolicy::kExplicit);
9013 0 : }
9014 :
9015 :
9016 0 : bool Isolate::WillAutorunMicrotasks() const {
9017 0 : return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto;
9018 : }
9019 :
9020 :
9021 1657 : void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
9022 1657 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9023 : isolate->handle_scope_implementer()->set_microtasks_policy(policy);
9024 1657 : }
9025 :
9026 :
9027 0 : MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
9028 0 : i::Isolate* isolate =
9029 : reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
9030 0 : return isolate->handle_scope_implementer()->microtasks_policy();
9031 : }
9032 :
9033 :
9034 5 : void Isolate::AddMicrotasksCompletedCallback(
9035 : MicrotasksCompletedCallback callback) {
9036 : DCHECK(callback);
9037 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9038 5 : isolate->AddMicrotasksCompletedCallback(callback);
9039 5 : }
9040 :
9041 :
9042 5 : void Isolate::RemoveMicrotasksCompletedCallback(
9043 : MicrotasksCompletedCallback callback) {
9044 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9045 5 : isolate->RemoveMicrotasksCompletedCallback(callback);
9046 5 : }
9047 :
9048 :
9049 60 : void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
9050 60 : reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
9051 60 : }
9052 :
9053 :
9054 5 : void Isolate::SetCounterFunction(CounterLookupCallback callback) {
9055 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9056 5 : isolate->counters()->ResetCounterFunction(callback);
9057 5 : }
9058 :
9059 :
9060 5 : void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
9061 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9062 5 : isolate->counters()->ResetCreateHistogramFunction(callback);
9063 5 : }
9064 :
9065 :
9066 5 : void Isolate::SetAddHistogramSampleFunction(
9067 : AddHistogramSampleCallback callback) {
9068 : reinterpret_cast<i::Isolate*>(this)
9069 : ->counters()
9070 : ->SetAddHistogramSampleFunction(callback);
9071 5 : }
9072 :
9073 :
9074 0 : bool Isolate::IdleNotification(int idle_time_in_ms) {
9075 : // Returning true tells the caller that it need not
9076 : // continue to call IdleNotification.
9077 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9078 0 : if (!i::FLAG_use_idle_notification) return true;
9079 0 : return isolate->heap()->IdleNotification(idle_time_in_ms);
9080 : }
9081 :
9082 :
9083 5855 : bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
9084 : // Returning true tells the caller that it need not
9085 : // continue to call IdleNotification.
9086 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9087 5855 : if (!i::FLAG_use_idle_notification) return true;
9088 5855 : return isolate->heap()->IdleNotification(deadline_in_seconds);
9089 : }
9090 :
9091 5988 : void Isolate::LowMemoryNotification() {
9092 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9093 : {
9094 : i::HistogramTimerScope idle_notification_scope(
9095 5988 : isolate->counters()->gc_low_memory_notification());
9096 17964 : TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
9097 : isolate->heap()->CollectAllAvailableGarbage(
9098 5988 : i::GarbageCollectionReason::kLowMemoryNotification);
9099 : }
9100 : {
9101 5988 : i::HeapIterator iterator(isolate->heap());
9102 : i::HeapObject* obj;
9103 35597839 : while ((obj = iterator.next()) != nullptr) {
9104 35585863 : if (obj->IsAbstractCode()) {
9105 5765601 : i::AbstractCode::cast(obj)->DropStackFrameCache();
9106 : }
9107 5988 : }
9108 : }
9109 5988 : }
9110 :
9111 :
9112 5984 : int Isolate::ContextDisposedNotification(bool dependant_context) {
9113 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9114 5994 : return isolate->heap()->NotifyContextDisposed(dependant_context);
9115 : }
9116 :
9117 :
9118 0 : void Isolate::IsolateInForegroundNotification() {
9119 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9120 0 : return isolate->IsolateInForegroundNotification();
9121 : }
9122 :
9123 :
9124 0 : void Isolate::IsolateInBackgroundNotification() {
9125 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9126 0 : return isolate->IsolateInBackgroundNotification();
9127 : }
9128 :
9129 22 : void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
9130 64 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9131 : bool on_isolate_thread =
9132 22 : v8::Locker::IsActive()
9133 : ? isolate->thread_manager()->IsLockedByCurrentThread()
9134 64 : : i::ThreadId::Current().Equals(isolate->thread_id());
9135 22 : isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
9136 22 : isolate->allocator()->MemoryPressureNotification(level);
9137 : isolate->compiler_dispatcher()->MemoryPressureNotification(level,
9138 22 : on_isolate_thread);
9139 22 : }
9140 :
9141 0 : void Isolate::SetRAILMode(RAILMode rail_mode) {
9142 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9143 0 : return isolate->SetRAILMode(rail_mode);
9144 : }
9145 :
9146 15 : void Isolate::IncreaseHeapLimitForDebugging() {
9147 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9148 : isolate->heap()->IncreaseHeapLimitForDebugging();
9149 15 : }
9150 :
9151 3086 : void Isolate::RestoreOriginalHeapLimit() {
9152 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9153 3086 : isolate->heap()->RestoreOriginalHeapLimit();
9154 3086 : }
9155 :
9156 15 : bool Isolate::IsHeapLimitIncreasedForDebugging() {
9157 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9158 15 : return isolate->heap()->IsHeapLimitIncreasedForDebugging();
9159 : }
9160 :
9161 66 : void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
9162 : JitCodeEventHandler event_handler) {
9163 66 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9164 : // Ensure that logging is initialized for our isolate.
9165 66 : isolate->InitializeLoggingAndCounters();
9166 66 : isolate->logger()->SetCodeEventHandler(options, event_handler);
9167 66 : }
9168 :
9169 :
9170 10 : void Isolate::SetStackLimit(uintptr_t stack_limit) {
9171 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9172 10 : CHECK(stack_limit);
9173 10 : isolate->stack_guard()->SetStackLimit(stack_limit);
9174 10 : }
9175 :
9176 0 : void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9177 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9178 0 : if (isolate->heap()->memory_allocator()->code_range()->valid()) {
9179 0 : *start = isolate->heap()->memory_allocator()->code_range()->start();
9180 : *length_in_bytes =
9181 0 : isolate->heap()->memory_allocator()->code_range()->size();
9182 : } else {
9183 0 : *start = nullptr;
9184 0 : *length_in_bytes = 0;
9185 : }
9186 0 : }
9187 :
9188 :
9189 43 : void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
9190 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9191 : isolate->set_exception_behavior(that);
9192 43 : }
9193 :
9194 0 : void Isolate::SetOOMErrorHandler(OOMErrorCallback that) {
9195 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9196 : isolate->set_oom_behavior(that);
9197 0 : }
9198 :
9199 108 : void Isolate::SetAllowCodeGenerationFromStringsCallback(
9200 : AllowCodeGenerationFromStringsCallback callback) {
9201 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9202 : isolate->set_allow_code_gen_callback(callback);
9203 108 : }
9204 :
9205 : #define CALLBACK_SETTER(ExternalName, Type, InternalName) \
9206 : void Isolate::Set##ExternalName(Type callback) { \
9207 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9208 : isolate->set_##InternalName(callback); \
9209 : }
9210 :
9211 120 : CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9212 20 : CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9213 :
9214 0 : CALLBACK_SETTER(WasmCompileStreamingCallback, ApiImplementationCallback,
9215 : wasm_compile_streaming_callback)
9216 :
9217 0 : bool Isolate::IsDead() {
9218 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9219 0 : return isolate->IsDead();
9220 : }
9221 :
9222 959 : bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9223 959 : return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9224 : }
9225 :
9226 27751 : bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9227 : int message_levels,
9228 : Local<Value> data) {
9229 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9230 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9231 : i::HandleScope scope(isolate);
9232 : i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9233 27751 : i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9234 : i::Handle<i::Foreign> foreign =
9235 27751 : isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9236 27751 : listener->set(0, *foreign);
9237 27745 : listener->set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
9238 55502 : : *Utils::OpenHandle(*data));
9239 : listener->set(2, i::Smi::FromInt(message_levels));
9240 27751 : list = i::TemplateList::Add(isolate, list, listener);
9241 : isolate->heap()->SetMessageListeners(*list);
9242 27751 : return true;
9243 : }
9244 :
9245 :
9246 155 : void Isolate::RemoveMessageListeners(MessageCallback that) {
9247 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9248 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9249 : i::HandleScope scope(isolate);
9250 : i::DisallowHeapAllocation no_gc;
9251 155 : i::TemplateList* listeners = isolate->heap()->message_listeners();
9252 507 : for (int i = 0; i < listeners->length(); i++) {
9253 197 : if (listeners->get(i)->IsUndefined(isolate)) continue; // skip deleted ones
9254 : i::FixedArray* listener = i::FixedArray::cast(listeners->get(i));
9255 : i::Foreign* callback_obj = i::Foreign::cast(listener->get(0));
9256 155 : if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
9257 155 : listeners->set(i, isolate->heap()->undefined_value());
9258 : }
9259 : }
9260 155 : }
9261 :
9262 :
9263 27 : void Isolate::SetFailedAccessCheckCallbackFunction(
9264 : FailedAccessCheckCallback callback) {
9265 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9266 27 : isolate->SetFailedAccessCheckCallback(callback);
9267 27 : }
9268 :
9269 :
9270 1188 : void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9271 : bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9272 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9273 : isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9274 1188 : options);
9275 1188 : }
9276 :
9277 :
9278 5 : void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9279 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9280 5 : isolate->heap()->VisitExternalResources(visitor);
9281 5 : }
9282 :
9283 :
9284 32235 : bool Isolate::IsInUse() {
9285 32235 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9286 32235 : return isolate->IsInUse();
9287 : }
9288 :
9289 :
9290 5 : void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9291 5 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9292 : i::DisallowHeapAllocation no_allocation;
9293 5 : isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9294 5 : }
9295 :
9296 :
9297 5 : void Isolate::VisitHandlesForPartialDependence(
9298 : PersistentHandleVisitor* visitor) {
9299 5 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9300 : i::DisallowHeapAllocation no_allocation;
9301 5 : isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(visitor);
9302 5 : }
9303 :
9304 :
9305 0 : void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9306 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9307 : i::DisallowHeapAllocation no_allocation;
9308 0 : isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(visitor);
9309 0 : }
9310 :
9311 5 : void Isolate::SetAllowAtomicsWait(bool allow) {
9312 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9313 : isolate->set_allow_atomics_wait(allow);
9314 5 : }
9315 :
9316 898030 : MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9317 : : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9318 898030 : run_(type == MicrotasksScope::kRunMicrotasks) {
9319 898030 : auto handle_scope_implementer = isolate_->handle_scope_implementer();
9320 898030 : if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
9321 : #ifdef DEBUG
9322 : if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
9323 : #endif
9324 898030 : }
9325 :
9326 :
9327 898033 : MicrotasksScope::~MicrotasksScope() {
9328 1028393 : auto handle_scope_implementer = isolate_->handle_scope_implementer();
9329 898033 : if (run_) {
9330 : handle_scope_implementer->DecrementMicrotasksScopeDepth();
9331 130360 : if (MicrotasksPolicy::kScoped ==
9332 : handle_scope_implementer->microtasks_policy()) {
9333 55247 : PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9334 : }
9335 : }
9336 : #ifdef DEBUG
9337 : if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
9338 : #endif
9339 898032 : }
9340 :
9341 :
9342 55272 : void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
9343 55272 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
9344 110543 : if (IsExecutionTerminatingCheck(isolate)) return;
9345 109314 : auto handle_scope_implementer = isolate->handle_scope_implementer();
9346 109314 : if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
9347 : !handle_scope_implementer->HasMicrotasksSuppressions()) {
9348 54032 : isolate->RunMicrotasks();
9349 : }
9350 : }
9351 :
9352 :
9353 0 : int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
9354 0 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
9355 0 : return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
9356 : }
9357 :
9358 100 : bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8Isolate) {
9359 100 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
9360 100 : return isolate->IsRunningMicrotasks();
9361 : }
9362 :
9363 9047052 : String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9364 9047052 : : str_(nullptr), length_(0) {
9365 9047071 : if (obj.IsEmpty()) return;
9366 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9367 : ENTER_V8_DO_NOT_USE(i_isolate);
9368 : i::HandleScope scope(i_isolate);
9369 9047042 : Local<Context> context = isolate->GetCurrentContext();
9370 18094075 : TryCatch try_catch(isolate);
9371 : Local<String> str;
9372 18094093 : if (!obj->ToString(context).ToLocal(&str)) return;
9373 : i::Handle<i::String> i_str = Utils::OpenHandle(*str);
9374 9047033 : length_ = v8::Utf8Length(*i_str, i_isolate);
9375 9047033 : str_ = i::NewArray<char>(length_ + 1);
9376 9047033 : str->WriteUtf8(str_);
9377 : }
9378 :
9379 0 : String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
9380 0 : : String::Utf8Value::Utf8Value(Isolate::GetCurrent(), obj) {}
9381 :
9382 9047052 : String::Utf8Value::~Utf8Value() {
9383 9047052 : i::DeleteArray(str_);
9384 9047052 : }
9385 :
9386 6 : String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9387 6 : : str_(nullptr), length_(0) {
9388 6 : if (obj.IsEmpty()) return;
9389 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9390 : ENTER_V8_DO_NOT_USE(i_isolate);
9391 : i::HandleScope scope(i_isolate);
9392 6 : Local<Context> context = isolate->GetCurrentContext();
9393 12 : TryCatch try_catch(isolate);
9394 : Local<String> str;
9395 12 : if (!obj->ToString(context).ToLocal(&str)) return;
9396 6 : length_ = str->Length();
9397 6 : str_ = i::NewArray<uint16_t>(length_ + 1);
9398 : str->Write(str_);
9399 : }
9400 :
9401 0 : String::Value::Value(v8::Local<v8::Value> obj)
9402 0 : : String::Value::Value(v8::Isolate::GetCurrent(), obj) {}
9403 :
9404 6 : String::Value::~Value() {
9405 6 : i::DeleteArray(str_);
9406 6 : }
9407 :
9408 : #define DEFINE_ERROR(NAME, name) \
9409 : Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
9410 : i::Isolate* isolate = i::Isolate::Current(); \
9411 : LOG_API(isolate, NAME, New); \
9412 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
9413 : i::Object* error; \
9414 : { \
9415 : i::HandleScope scope(isolate); \
9416 : i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
9417 : i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9418 : error = *isolate->factory()->NewError(constructor, message); \
9419 : } \
9420 : i::Handle<i::Object> result(error, isolate); \
9421 : return Utils::ToLocal(result); \
9422 : }
9423 :
9424 130 : DEFINE_ERROR(RangeError, range_error)
9425 30 : DEFINE_ERROR(ReferenceError, reference_error)
9426 30 : DEFINE_ERROR(SyntaxError, syntax_error)
9427 30 : DEFINE_ERROR(TypeError, type_error)
9428 1205 : DEFINE_ERROR(Error, error)
9429 :
9430 : #undef DEFINE_ERROR
9431 :
9432 :
9433 227 : Local<Message> Exception::CreateMessage(Isolate* isolate,
9434 : Local<Value> exception) {
9435 227 : i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9436 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9437 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9438 : i::HandleScope scope(i_isolate);
9439 : return Utils::MessageToLocal(
9440 454 : scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9441 : }
9442 :
9443 :
9444 0 : Local<Message> Exception::CreateMessage(Local<Value> exception) {
9445 : i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9446 0 : if (!obj->IsHeapObject()) return Local<Message>();
9447 : i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
9448 0 : return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception);
9449 : }
9450 :
9451 :
9452 66 : Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9453 : i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9454 66 : if (!obj->IsJSObject()) return Local<StackTrace>();
9455 : i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9456 : i::Isolate* isolate = js_obj->GetIsolate();
9457 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9458 66 : return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9459 : }
9460 :
9461 :
9462 : // --- D e b u g S u p p o r t ---
9463 :
9464 0 : bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
9465 : Local<Value> data) {
9466 0 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9467 0 : if (that == nullptr) {
9468 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9469 : i::HandleScope scope(i_isolate);
9470 0 : i_isolate->debug()->SetDebugDelegate(nullptr, false);
9471 : } else {
9472 : // Might create the Debug context.
9473 : ENTER_V8_FOR_NEW_CONTEXT(i_isolate);
9474 : i::HandleScope scope(i_isolate);
9475 : i::Handle<i::Object> i_data = i_isolate->factory()->undefined_value();
9476 0 : if (!data.IsEmpty()) i_data = Utils::OpenHandle(*data);
9477 : i::NativeDebugDelegate* delegate =
9478 0 : new i::NativeDebugDelegate(i_isolate, that, i_data);
9479 0 : i_isolate->debug()->SetDebugDelegate(delegate, true);
9480 : }
9481 0 : return true;
9482 : }
9483 :
9484 0 : void Debug::DebugBreak(Isolate* isolate) { debug::DebugBreak(isolate); }
9485 :
9486 0 : void Debug::CancelDebugBreak(Isolate* isolate) {
9487 : debug::CancelDebugBreak(isolate);
9488 0 : }
9489 :
9490 0 : bool Debug::CheckDebugBreak(Isolate* isolate) {
9491 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9492 0 : return internal_isolate->stack_guard()->CheckDebugBreak();
9493 : }
9494 :
9495 0 : void Debug::SetMessageHandler(Isolate* isolate,
9496 0 : v8::Debug::MessageHandler handler) {}
9497 :
9498 0 : void Debug::SendCommand(Isolate* isolate, const uint16_t* command, int length,
9499 0 : ClientData* client_data) {}
9500 :
9501 0 : MaybeLocal<Value> Debug::Call(Local<Context> context,
9502 : v8::Local<v8::Function> fun,
9503 : v8::Local<v8::Value> data) {
9504 0 : return debug::Call(context, fun, data);
9505 : }
9506 :
9507 0 : void Debug::ProcessDebugMessages(Isolate* isolate) {}
9508 :
9509 0 : Local<Context> Debug::GetDebugContext(Isolate* isolate) {
9510 0 : return debug::GetDebugContext(isolate);
9511 : }
9512 :
9513 0 : MaybeLocal<Context> Debug::GetDebuggedContext(Isolate* isolate) {
9514 0 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9515 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9516 0 : if (!i_isolate->debug()->in_debug_scope()) return MaybeLocal<Context>();
9517 0 : i::Handle<i::Object> calling = i_isolate->GetCallingNativeContext();
9518 0 : if (calling.is_null()) return MaybeLocal<Context>();
9519 0 : return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
9520 : }
9521 :
9522 0 : void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
9523 : debug::SetLiveEditEnabled(isolate, enable);
9524 0 : }
9525 :
9526 0 : bool Debug::IsTailCallEliminationEnabled(Isolate* isolate) { return false; }
9527 :
9528 0 : void Debug::SetTailCallEliminationEnabled(Isolate* isolate, bool enabled) {
9529 0 : }
9530 :
9531 0 : MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate,
9532 : Local<Value> value) {
9533 0 : return debug::GetInternalProperties(v8_isolate, value);
9534 : }
9535 :
9536 3326 : void debug::SetContextId(Local<Context> context, int id) {
9537 : Utils::OpenHandle(*context)->set_debug_context_id(i::Smi::FromInt(id));
9538 3326 : }
9539 :
9540 722160 : int debug::GetContextId(Local<Context> context) {
9541 : i::Object* value = Utils::OpenHandle(*context)->debug_context_id();
9542 1444320 : return (value->IsSmi()) ? i::Smi::ToInt(value) : 0;
9543 : }
9544 :
9545 49970 : Local<Context> debug::GetDebugContext(Isolate* isolate) {
9546 49970 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9547 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9548 99940 : return Utils::ToLocal(i_isolate->debug()->GetDebugContext());
9549 : }
9550 :
9551 135 : MaybeLocal<Value> debug::Call(Local<Context> context,
9552 : v8::Local<v8::Function> fun,
9553 : v8::Local<v8::Value> data) {
9554 675 : PREPARE_FOR_EXECUTION(context, Debug, Call, Value);
9555 : i::Handle<i::Object> data_obj;
9556 135 : if (data.IsEmpty()) {
9557 130 : data_obj = isolate->factory()->undefined_value();
9558 : } else {
9559 5 : data_obj = Utils::OpenHandle(*data);
9560 : }
9561 : Local<Value> result;
9562 : has_pending_exception = !ToLocal<Value>(
9563 270 : isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj), &result);
9564 135 : RETURN_ON_FAILED_EXECUTION(Value);
9565 120 : RETURN_ESCAPED(result);
9566 : }
9567 :
9568 2458 : void debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
9569 2458 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9570 : internal_isolate->debug()->set_live_edit_enabled(enable);
9571 2458 : }
9572 :
9573 16420 : void debug::DebugBreak(Isolate* isolate) {
9574 16420 : reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
9575 16420 : }
9576 :
9577 80 : void debug::CancelDebugBreak(Isolate* isolate) {
9578 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9579 80 : internal_isolate->stack_guard()->ClearDebugBreak();
9580 80 : }
9581 :
9582 67176 : MaybeLocal<Array> debug::GetInternalProperties(Isolate* v8_isolate,
9583 : Local<Value> value) {
9584 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9585 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9586 67176 : i::Handle<i::Object> val = Utils::OpenHandle(*value);
9587 : i::Handle<i::JSArray> result;
9588 134352 : if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
9589 0 : return MaybeLocal<Array>();
9590 67176 : return Utils::ToLocal(result);
9591 : }
9592 :
9593 6976 : void debug::ChangeBreakOnException(Isolate* isolate, ExceptionBreakState type) {
9594 13952 : i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9595 : internal_isolate->debug()->ChangeBreakOnException(
9596 13952 : i::BreakException, type == BreakOnAnyException);
9597 : internal_isolate->debug()->ChangeBreakOnException(i::BreakUncaughtException,
9598 13952 : type != NoBreakOnException);
9599 6976 : }
9600 :
9601 6354 : void debug::SetBreakPointsActive(Isolate* v8_isolate, bool is_active) {
9602 6354 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9603 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9604 : isolate->debug()->set_break_points_active(is_active);
9605 6354 : }
9606 :
9607 6157 : void debug::SetOutOfMemoryCallback(Isolate* isolate,
9608 : OutOfMemoryCallback callback, void* data) {
9609 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9610 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9611 6157 : i_isolate->heap()->SetOutOfMemoryCallback(callback, data);
9612 6157 : }
9613 :
9614 39681 : void debug::PrepareStep(Isolate* v8_isolate, StepAction action) {
9615 79362 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9616 : ENTER_V8_DO_NOT_USE(isolate);
9617 39681 : CHECK(isolate->debug()->CheckExecutionState());
9618 : // Clear all current stepping setup.
9619 39681 : isolate->debug()->ClearStepping();
9620 : // Prepare step.
9621 79362 : isolate->debug()->PrepareStep(static_cast<i::StepAction>(action));
9622 39681 : }
9623 :
9624 60 : void debug::ClearStepping(Isolate* v8_isolate) {
9625 60 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9626 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9627 : // Clear all current stepping setup.
9628 60 : isolate->debug()->ClearStepping();
9629 60 : }
9630 :
9631 95 : void debug::BreakRightNow(Isolate* v8_isolate) {
9632 95 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9633 : ENTER_V8_DO_NOT_USE(isolate);
9634 95 : isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed);
9635 95 : }
9636 :
9637 105 : bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) {
9638 105 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9639 : ENTER_V8_DO_NOT_USE(isolate);
9640 210 : return isolate->debug()->AllFramesOnStackAreBlackboxed();
9641 : }
9642 :
9643 0 : v8::Isolate* debug::Script::GetIsolate() const {
9644 0 : return reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate());
9645 : }
9646 :
9647 0 : ScriptOriginOptions debug::Script::OriginOptions() const {
9648 0 : return Utils::OpenHandle(this)->origin_options();
9649 : }
9650 :
9651 8169 : bool debug::Script::WasCompiled() const {
9652 : return Utils::OpenHandle(this)->compilation_state() ==
9653 8169 : i::Script::COMPILATION_STATE_COMPILED;
9654 : }
9655 :
9656 8149 : bool debug::Script::IsEmbedded() const {
9657 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9658 8149 : return script->context_data() == script->GetHeap()->uninitialized_symbol();
9659 : }
9660 :
9661 576514 : int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); }
9662 :
9663 25887 : int debug::Script::LineOffset() const {
9664 25887 : return Utils::OpenHandle(this)->line_offset();
9665 : }
9666 :
9667 25887 : int debug::Script::ColumnOffset() const {
9668 25887 : return Utils::OpenHandle(this)->column_offset();
9669 : }
9670 :
9671 25887 : std::vector<int> debug::Script::LineEnds() const {
9672 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9673 25887 : if (script->type() == i::Script::TYPE_WASM) return std::vector<int>();
9674 : i::Isolate* isolate = script->GetIsolate();
9675 : i::HandleScope scope(isolate);
9676 25887 : i::Script::InitLineEnds(script);
9677 25887 : CHECK(script->line_ends()->IsFixedArray());
9678 : i::Handle<i::FixedArray> line_ends(i::FixedArray::cast(script->line_ends()));
9679 25887 : std::vector<int> result(line_ends->length());
9680 9122920 : for (int i = 0; i < line_ends->length(); ++i) {
9681 : i::Smi* line_end = i::Smi::cast(line_ends->get(i));
9682 9071146 : result[i] = line_end->value();
9683 : }
9684 : return result;
9685 : }
9686 :
9687 26210 : MaybeLocal<String> debug::Script::Name() const {
9688 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9689 : i::HandleScope handle_scope(isolate);
9690 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9691 : i::Handle<i::Object> value(script->name(), isolate);
9692 26210 : if (!value->IsString()) return MaybeLocal<String>();
9693 : return Utils::ToLocal(
9694 12341 : handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9695 : }
9696 :
9697 39756 : MaybeLocal<String> debug::Script::SourceURL() const {
9698 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9699 : i::HandleScope handle_scope(isolate);
9700 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9701 : i::Handle<i::Object> value(script->source_url(), isolate);
9702 39756 : if (!value->IsString()) return MaybeLocal<String>();
9703 : return Utils::ToLocal(
9704 1395 : handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9705 : }
9706 :
9707 25887 : MaybeLocal<String> debug::Script::SourceMappingURL() const {
9708 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9709 : i::HandleScope handle_scope(isolate);
9710 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9711 : i::Handle<i::Object> value(script->source_mapping_url(), isolate);
9712 25887 : if (!value->IsString()) return MaybeLocal<String>();
9713 : return Utils::ToLocal(
9714 3733 : handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9715 : }
9716 :
9717 63612 : Maybe<int> debug::Script::ContextId() const {
9718 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9719 : i::HandleScope handle_scope(isolate);
9720 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9721 : i::Object* value = script->context_data();
9722 63612 : if (value->IsSmi()) return Just(i::Smi::ToInt(value));
9723 : return Nothing<int>();
9724 : }
9725 :
9726 25897 : MaybeLocal<String> debug::Script::Source() const {
9727 : i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
9728 : i::HandleScope handle_scope(isolate);
9729 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9730 : i::Handle<i::Object> value(script->source(), isolate);
9731 25897 : if (!value->IsString()) return MaybeLocal<String>();
9732 : return Utils::ToLocal(
9733 25897 : handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9734 : }
9735 :
9736 17827 : bool debug::Script::IsWasm() const {
9737 17827 : return Utils::OpenHandle(this)->type() == i::Script::TYPE_WASM;
9738 : }
9739 :
9740 25887 : bool debug::Script::IsModule() const {
9741 25887 : return Utils::OpenHandle(this)->origin_options().IsModule();
9742 : }
9743 :
9744 : namespace {
9745 : int GetSmiValue(i::Handle<i::FixedArray> array, int index) {
9746 : return i::Smi::ToInt(array->get(index));
9747 : }
9748 :
9749 19605 : bool CompareBreakLocation(const i::BreakLocation& loc1,
9750 19605 : const i::BreakLocation& loc2) {
9751 19605 : return loc1.position() < loc2.position();
9752 : }
9753 : } // namespace
9754 :
9755 255 : bool debug::Script::GetPossibleBreakpoints(
9756 : const debug::Location& start, const debug::Location& end,
9757 : bool restrict_to_function,
9758 : std::vector<debug::BreakLocation>* locations) const {
9759 255 : CHECK(!start.IsEmpty());
9760 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9761 255 : if (script->type() == i::Script::TYPE_WASM) {
9762 : i::Handle<i::WasmCompiledModule> compiled_module(
9763 : i::WasmCompiledModule::cast(script->wasm_compiled_module()));
9764 30 : return compiled_module->GetPossibleBreakpoints(start, end, locations);
9765 : }
9766 :
9767 225 : i::Script::InitLineEnds(script);
9768 225 : CHECK(script->line_ends()->IsFixedArray());
9769 200 : i::Isolate* isolate = script->GetIsolate();
9770 : i::Handle<i::FixedArray> line_ends =
9771 : i::Handle<i::FixedArray>::cast(i::handle(script->line_ends(), isolate));
9772 225 : CHECK(line_ends->length());
9773 :
9774 225 : int start_offset = GetSourceOffset(start);
9775 : int end_offset = end.IsEmpty()
9776 140 : ? GetSmiValue(line_ends, line_ends->length() - 1) + 1
9777 365 : : GetSourceOffset(end);
9778 225 : if (start_offset >= end_offset) return true;
9779 :
9780 : std::vector<i::BreakLocation> v8_locations;
9781 200 : if (!isolate->debug()->GetPossibleBreakpoints(
9782 : script, start_offset, end_offset, restrict_to_function,
9783 400 : &v8_locations)) {
9784 : return false;
9785 : }
9786 :
9787 195 : std::sort(v8_locations.begin(), v8_locations.end(), CompareBreakLocation);
9788 : int current_line_end_index = 0;
9789 3880 : for (const auto& v8_location : v8_locations) {
9790 : int offset = v8_location.position();
9791 9010 : while (offset > GetSmiValue(line_ends, current_line_end_index)) {
9792 2030 : ++current_line_end_index;
9793 2030 : CHECK(current_line_end_index < line_ends->length());
9794 : }
9795 : int line_offset = 0;
9796 :
9797 3490 : if (current_line_end_index > 0) {
9798 6100 : line_offset = GetSmiValue(line_ends, current_line_end_index - 1) + 1;
9799 : }
9800 : locations->emplace_back(
9801 3490 : current_line_end_index + script->line_offset(),
9802 6980 : offset - line_offset +
9803 : (current_line_end_index == 0 ? script->column_offset() : 0),
9804 10470 : v8_location.type());
9805 : }
9806 : return true;
9807 : }
9808 :
9809 2519 : int debug::Script::GetSourceOffset(const debug::Location& location) const {
9810 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9811 2519 : if (script->type() == i::Script::TYPE_WASM) {
9812 : return i::WasmCompiledModule::cast(script->wasm_compiled_module())
9813 140 : ->GetFunctionOffset(location.GetLineNumber()) +
9814 70 : location.GetColumnNumber();
9815 : }
9816 :
9817 7347 : int line = std::max(location.GetLineNumber() - script->line_offset(), 0);
9818 2449 : int column = location.GetColumnNumber();
9819 2449 : if (line == 0) {
9820 806 : column = std::max(0, column - script->column_offset());
9821 : }
9822 :
9823 2449 : i::Script::InitLineEnds(script);
9824 2449 : CHECK(script->line_ends()->IsFixedArray());
9825 : i::Handle<i::FixedArray> line_ends = i::Handle<i::FixedArray>::cast(
9826 : i::handle(script->line_ends(), script->GetIsolate()));
9827 2449 : CHECK(line_ends->length());
9828 2449 : if (line >= line_ends->length())
9829 80 : return GetSmiValue(line_ends, line_ends->length() - 1);
9830 2409 : int line_offset = GetSmiValue(line_ends, line);
9831 2812 : if (line == 0) return std::min(column, line_offset);
9832 2006 : int prev_line_offset = GetSmiValue(line_ends, line - 1);
9833 4012 : return std::min(prev_line_offset + column + 1, line_offset);
9834 : }
9835 :
9836 303636 : v8::debug::Location debug::Script::GetSourceLocation(int offset) const {
9837 303636 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9838 : i::Script::PositionInfo info;
9839 303636 : i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
9840 303636 : return debug::Location(info.line, info.column);
9841 : }
9842 :
9843 35 : bool debug::Script::SetScriptSource(v8::Local<v8::String> newSource,
9844 : bool preview, bool* stack_changed) const {
9845 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9846 35 : i::Isolate* isolate = script->GetIsolate();
9847 : return isolate->debug()->SetScriptSource(
9848 70 : script, Utils::OpenHandle(*newSource), preview, stack_changed);
9849 : }
9850 :
9851 1969 : bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition,
9852 : debug::Location* location,
9853 : debug::BreakpointId* id) const {
9854 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9855 1969 : i::Isolate* isolate = script->GetIsolate();
9856 1969 : int offset = GetSourceOffset(*location);
9857 1969 : if (!isolate->debug()->SetBreakpoint(script, Utils::OpenHandle(*condition),
9858 1969 : &offset, id)) {
9859 : return false;
9860 : }
9861 1949 : *location = GetSourceLocation(offset);
9862 1949 : return true;
9863 : }
9864 :
9865 1949 : void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) {
9866 1949 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9867 : i::HandleScope handle_scope(isolate);
9868 1949 : isolate->debug()->RemoveBreakpoint(id);
9869 1949 : }
9870 :
9871 49 : debug::WasmScript* debug::WasmScript::Cast(debug::Script* script) {
9872 49 : CHECK(script->IsWasm());
9873 49 : return static_cast<WasmScript*>(script);
9874 : }
9875 :
9876 132 : int debug::WasmScript::NumFunctions() const {
9877 : i::DisallowHeapAllocation no_gc;
9878 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9879 : DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9880 : i::WasmCompiledModule* compiled_module =
9881 : i::WasmCompiledModule::cast(script->wasm_compiled_module());
9882 : DCHECK_GE(i::kMaxInt, compiled_module->module()->functions.size());
9883 264 : return static_cast<int>(compiled_module->module()->functions.size());
9884 : }
9885 :
9886 132 : int debug::WasmScript::NumImportedFunctions() const {
9887 : i::DisallowHeapAllocation no_gc;
9888 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9889 : DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9890 : i::WasmCompiledModule* compiled_module =
9891 : i::WasmCompiledModule::cast(script->wasm_compiled_module());
9892 : DCHECK_GE(i::kMaxInt, compiled_module->module()->num_imported_functions);
9893 132 : return static_cast<int>(compiled_module->module()->num_imported_functions);
9894 : }
9895 :
9896 5 : std::pair<int, int> debug::WasmScript::GetFunctionRange(
9897 : int function_index) const {
9898 : i::DisallowHeapAllocation no_gc;
9899 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9900 : DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9901 : i::WasmCompiledModule* compiled_module =
9902 : i::WasmCompiledModule::cast(script->wasm_compiled_module());
9903 : DCHECK_LE(0, function_index);
9904 : DCHECK_GT(compiled_module->module()->functions.size(), function_index);
9905 : i::wasm::WasmFunction& func =
9906 5 : compiled_module->module()->functions[function_index];
9907 : DCHECK_GE(i::kMaxInt, func.code.offset());
9908 : DCHECK_GE(i::kMaxInt, func.code.end_offset());
9909 : return std::make_pair(static_cast<int>(func.code.offset()),
9910 5 : static_cast<int>(func.code.end_offset()));
9911 : }
9912 :
9913 83 : debug::WasmDisassembly debug::WasmScript::DisassembleFunction(
9914 : int function_index) const {
9915 : i::DisallowHeapAllocation no_gc;
9916 : i::Handle<i::Script> script = Utils::OpenHandle(this);
9917 : DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9918 : i::WasmCompiledModule* compiled_module =
9919 : i::WasmCompiledModule::cast(script->wasm_compiled_module());
9920 83 : return compiled_module->DisassembleFunction(function_index);
9921 : }
9922 :
9923 31527 : debug::Location::Location(int line_number, int column_number)
9924 : : line_number_(line_number),
9925 : column_number_(column_number),
9926 35017 : is_empty_(false) {}
9927 :
9928 265 : debug::Location::Location()
9929 : : line_number_(v8::Function::kLineOffsetNotFound),
9930 : column_number_(v8::Function::kLineOffsetNotFound),
9931 265 : is_empty_(true) {}
9932 :
9933 313965 : int debug::Location::GetLineNumber() const {
9934 : DCHECK(!IsEmpty());
9935 316484 : return line_number_;
9936 : }
9937 :
9938 311779 : int debug::Location::GetColumnNumber() const {
9939 : DCHECK(!IsEmpty());
9940 314298 : return column_number_;
9941 : }
9942 :
9943 888 : bool debug::Location::IsEmpty() const { return is_empty_; }
9944 :
9945 3131 : void debug::GetLoadedScripts(v8::Isolate* v8_isolate,
9946 : PersistentValueVector<debug::Script>& scripts) {
9947 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9948 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9949 : // TODO(kozyatinskiy): remove this GC once tests are dealt with.
9950 : isolate->heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask,
9951 3131 : i::GarbageCollectionReason::kDebugger);
9952 : {
9953 : i::DisallowHeapAllocation no_gc;
9954 3131 : i::Script::Iterator iterator(isolate);
9955 : i::Script* script;
9956 61722 : while ((script = iterator.Next()) != nullptr) {
9957 55460 : if (!script->IsUserJavaScript()) continue;
9958 8174 : if (script->HasValidSource()) {
9959 : i::HandleScope handle_scope(isolate);
9960 : i::Handle<i::Script> script_handle(script, isolate);
9961 8174 : scripts.Append(ToApiHandle<Script>(script_handle));
9962 : }
9963 : }
9964 : }
9965 3131 : }
9966 :
9967 3175 : MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
9968 : Local<String> source) {
9969 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9970 9525 : PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, UnboundScript);
9971 3175 : i::ScriptData* script_data = nullptr;
9972 3175 : i::Handle<i::String> str = Utils::OpenHandle(*source);
9973 : i::Handle<i::SharedFunctionInfo> result;
9974 : {
9975 : ScriptOriginOptions origin_options;
9976 : i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info =
9977 : i::Compiler::GetSharedFunctionInfoForScript(
9978 : str, i::MaybeHandle<i::Object>(), 0, 0, origin_options,
9979 : i::MaybeHandle<i::Object>(), isolate->native_context(), nullptr,
9980 : &script_data, ScriptCompiler::kNoCompileOptions,
9981 : i::FLAG_expose_inspector_scripts ? i::NOT_NATIVES_CODE
9982 : : i::INSPECTOR_CODE,
9983 6350 : i::MaybeHandle<i::FixedArray>());
9984 : has_pending_exception = !maybe_function_info.ToHandle(&result);
9985 3175 : RETURN_ON_FAILED_EXECUTION(UnboundScript);
9986 : }
9987 3175 : RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
9988 : }
9989 :
9990 6247 : void debug::SetDebugDelegate(Isolate* v8_isolate,
9991 : debug::DebugDelegate* delegate) {
9992 6247 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9993 : // Might create the Debug context.
9994 : ENTER_V8_FOR_NEW_CONTEXT(isolate);
9995 6247 : isolate->debug()->SetDebugDelegate(delegate, false);
9996 6247 : }
9997 :
9998 52043 : void debug::ResetBlackboxedStateCache(Isolate* v8_isolate,
9999 : v8::Local<debug::Script> script) {
10000 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10001 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10002 : i::DisallowHeapAllocation no_gc;
10003 52043 : i::SharedFunctionInfo::ScriptIterator iter(Utils::OpenHandle(*script));
10004 803753 : while (i::SharedFunctionInfo* info = iter.Next()) {
10005 751710 : info->set_computed_debug_is_blackboxed(false);
10006 : }
10007 52043 : }
10008 :
10009 6625 : int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local<v8::Value> value) {
10010 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10011 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10012 : i::Handle<i::Object> object = Utils::OpenHandle(*value);
10013 6625 : if (object->IsSmi()) return i::kPointerSize;
10014 5965 : CHECK(object->IsHeapObject());
10015 5965 : return i::Handle<i::HeapObject>::cast(object)->Size();
10016 : }
10017 :
10018 67176 : v8::MaybeLocal<v8::Array> debug::EntriesPreview(Isolate* v8_isolate,
10019 : v8::Local<v8::Value> value,
10020 : bool* is_key_value) {
10021 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10022 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10023 67176 : if (value->IsMap()) {
10024 34 : *is_key_value = true;
10025 34 : return value.As<Map>()->AsArray();
10026 : }
10027 67142 : if (value->IsSet()) {
10028 40 : *is_key_value = false;
10029 40 : return value.As<Set>()->AsArray();
10030 : }
10031 :
10032 : i::Handle<i::Object> object = Utils::OpenHandle(*value);
10033 67102 : if (object->IsJSWeakCollection()) {
10034 30 : *is_key_value = object->IsJSWeakMap();
10035 : return Utils::ToLocal(i::JSWeakCollection::GetEntries(
10036 30 : i::Handle<i::JSWeakCollection>::cast(object), 0));
10037 : }
10038 67072 : if (object->IsJSMapIterator()) {
10039 : i::Handle<i::JSMapIterator> iterator =
10040 : i::Handle<i::JSMapIterator>::cast(object);
10041 : MapAsArrayKind const kind =
10042 62 : static_cast<MapAsArrayKind>(iterator->map()->instance_type());
10043 62 : *is_key_value = kind == MapAsArrayKind::kEntries;
10044 62 : if (!iterator->HasMore()) return v8::Array::New(v8_isolate);
10045 : return Utils::ToLocal(MapAsArray(isolate, iterator->table(),
10046 57 : i::Smi::ToInt(iterator->index()), kind));
10047 : }
10048 67010 : if (object->IsJSSetIterator()) {
10049 : i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
10050 35 : *is_key_value = false;
10051 35 : if (!it->HasMore()) return v8::Array::New(v8_isolate);
10052 : return Utils::ToLocal(
10053 30 : SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index())));
10054 : }
10055 66975 : return v8::MaybeLocal<v8::Array>();
10056 : }
10057 :
10058 14720 : Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
10059 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10060 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10061 : i::HandleScope handle_scope(isolate);
10062 : i::Builtins::Name name;
10063 14720 : switch (builtin) {
10064 : case kObjectKeys:
10065 : name = i::Builtins::kObjectKeys;
10066 : break;
10067 : case kObjectGetPrototypeOf:
10068 : name = i::Builtins::kObjectGetPrototypeOf;
10069 2944 : break;
10070 : case kObjectGetOwnPropertyDescriptor:
10071 : name = i::Builtins::kObjectGetOwnPropertyDescriptor;
10072 2944 : break;
10073 : case kObjectGetOwnPropertyNames:
10074 : name = i::Builtins::kObjectGetOwnPropertyNames;
10075 2944 : break;
10076 : case kObjectGetOwnPropertySymbols:
10077 : name = i::Builtins::kObjectGetOwnPropertySymbols;
10078 2944 : break;
10079 : default:
10080 0 : UNREACHABLE();
10081 : }
10082 : i::Handle<i::Code> call_code(isolate->builtins()->builtin(name));
10083 : i::Handle<i::JSFunction> fun =
10084 : isolate->factory()->NewFunctionWithoutPrototype(
10085 : isolate->factory()->empty_string(), call_code,
10086 14720 : i::LanguageMode::kSloppy);
10087 14720 : if (i::Builtins::IsLazy(name)) {
10088 : fun->shared()->set_lazy_deserialization_builtin_id(name);
10089 : }
10090 : fun->shared()->DontAdaptArguments();
10091 29440 : return Utils::ToLocal(handle_scope.CloseAndEscape(fun));
10092 : }
10093 :
10094 33698 : void debug::SetConsoleDelegate(Isolate* v8_isolate, ConsoleDelegate* delegate) {
10095 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10096 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10097 : isolate->set_console_delegate(delegate);
10098 33698 : }
10099 :
10100 380 : debug::ConsoleCallArguments::ConsoleCallArguments(
10101 : const v8::FunctionCallbackInfo<v8::Value>& info)
10102 380 : : v8::FunctionCallbackInfo<v8::Value>(nullptr, info.values_, info.length_) {
10103 380 : }
10104 :
10105 7347 : debug::ConsoleCallArguments::ConsoleCallArguments(
10106 : internal::BuiltinArguments& args)
10107 : : v8::FunctionCallbackInfo<v8::Value>(nullptr, &args[0] - 1,
10108 22041 : args.length() - 1) {}
10109 :
10110 41577 : int debug::GetStackFrameId(v8::Local<v8::StackFrame> frame) {
10111 41577 : return Utils::OpenHandle(*frame)->id();
10112 : }
10113 :
10114 15 : v8::Local<v8::StackTrace> debug::GetDetailedStackTrace(
10115 : Isolate* v8_isolate, v8::Local<v8::Object> v8_error) {
10116 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10117 : i::Handle<i::JSReceiver> error = Utils::OpenHandle(*v8_error);
10118 15 : if (!error->IsJSObject()) {
10119 0 : return v8::Local<v8::StackTrace>();
10120 : }
10121 : i::Handle<i::FixedArray> stack_trace =
10122 15 : isolate->GetDetailedStackTrace(i::Handle<i::JSObject>::cast(error));
10123 : return Utils::StackTraceToLocal(stack_trace);
10124 : }
10125 :
10126 35 : MaybeLocal<debug::Script> debug::GeneratorObject::Script() {
10127 : i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10128 : i::Object* maybe_script = obj->function()->shared()->script();
10129 35 : if (!maybe_script->IsScript()) return MaybeLocal<debug::Script>();
10130 : i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
10131 35 : return ToApiHandle<debug::Script>(script);
10132 : }
10133 :
10134 10 : Local<Function> debug::GeneratorObject::Function() {
10135 : i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10136 10 : return Utils::ToLocal(handle(obj->function()));
10137 : }
10138 :
10139 35 : debug::Location debug::GeneratorObject::SuspendedLocation() {
10140 : i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10141 35 : CHECK(obj->is_suspended());
10142 : i::Object* maybe_script = obj->function()->shared()->script();
10143 35 : if (!maybe_script->IsScript()) return debug::Location();
10144 : i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
10145 : i::Script::PositionInfo info;
10146 : i::Script::GetPositionInfo(script, obj->source_position(), &info,
10147 35 : i::Script::WITH_OFFSET);
10148 35 : return debug::Location(info.line, info.column);
10149 : }
10150 :
10151 90 : bool debug::GeneratorObject::IsSuspended() {
10152 90 : return Utils::OpenHandle(this)->is_suspended();
10153 : }
10154 :
10155 90 : v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast(
10156 : v8::Local<v8::Value> value) {
10157 90 : CHECK(value->IsGeneratorObject());
10158 90 : return ToApiHandle<debug::GeneratorObject>(Utils::OpenHandle(*value));
10159 : }
10160 :
10161 65 : void debug::QueryObjects(v8::Local<v8::Context> v8_context,
10162 : QueryObjectPredicate* predicate,
10163 : PersistentValueVector<v8::Object>* objects) {
10164 65 : i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_context->GetIsolate());
10165 : ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10166 : isolate->heap_profiler()->QueryObjects(Utils::OpenHandle(*v8_context),
10167 65 : predicate, objects);
10168 65 : }
10169 :
10170 35 : void debug::GlobalLexicalScopeNames(
10171 : v8::Local<v8::Context> v8_context,
10172 : v8::PersistentValueVector<v8::String>* names) {
10173 : i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
10174 : i::Handle<i::ScriptContextTable> table(
10175 35 : context->global_object()->native_context()->script_context_table());
10176 340 : for (int i = 0; i < table->used(); i++) {
10177 135 : i::Handle<i::Context> context = i::ScriptContextTable::GetContext(table, i);
10178 : DCHECK(context->IsScriptContext());
10179 135 : i::Handle<i::ScopeInfo> scope_info(context->scope_info());
10180 135 : int local_count = scope_info->ContextLocalCount();
10181 285 : for (int j = 0; j < local_count; ++j) {
10182 150 : i::String* name = scope_info->ContextLocalName(j);
10183 150 : if (i::ScopeInfo::VariableIsSynthetic(name)) continue;
10184 115 : names->Append(Utils::ToLocal(handle(name)));
10185 : }
10186 : }
10187 35 : }
10188 :
10189 382 : Local<String> CpuProfileNode::GetFunctionName() const {
10190 764 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10191 : i::Isolate* isolate = node->isolate();
10192 764 : const i::CodeEntry* entry = node->entry();
10193 : i::Handle<i::String> name =
10194 382 : isolate->factory()->InternalizeUtf8String(entry->name());
10195 382 : if (!entry->has_name_prefix()) {
10196 : return ToApiHandle<String>(name);
10197 : } else {
10198 : // We do not expect this to fail. Change this if it does.
10199 : i::Handle<i::String> cons = isolate->factory()->NewConsString(
10200 : isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
10201 60 : name).ToHandleChecked();
10202 : return ToApiHandle<String>(cons);
10203 : }
10204 : }
10205 :
10206 110 : int debug::Coverage::BlockData::StartOffset() const { return block_->start; }
10207 110 : int debug::Coverage::BlockData::EndOffset() const { return block_->end; }
10208 110 : uint32_t debug::Coverage::BlockData::Count() const { return block_->count; }
10209 :
10210 515 : int debug::Coverage::FunctionData::StartOffset() const {
10211 515 : return function_->start;
10212 : }
10213 515 : int debug::Coverage::FunctionData::EndOffset() const { return function_->end; }
10214 505 : uint32_t debug::Coverage::FunctionData::Count() const {
10215 505 : return function_->count;
10216 : }
10217 :
10218 475 : MaybeLocal<String> debug::Coverage::FunctionData::Name() const {
10219 475 : return ToApiHandle<String>(function_->name);
10220 : }
10221 :
10222 585 : size_t debug::Coverage::FunctionData::BlockCount() const {
10223 1170 : return function_->blocks.size();
10224 : }
10225 :
10226 475 : bool debug::Coverage::FunctionData::HasBlockCoverage() const {
10227 475 : return function_->has_block_coverage;
10228 : }
10229 :
10230 110 : debug::Coverage::BlockData debug::Coverage::FunctionData::GetBlockData(
10231 : size_t i) const {
10232 220 : return BlockData(&function_->blocks.at(i), coverage_);
10233 : }
10234 :
10235 210 : Local<debug::Script> debug::Coverage::ScriptData::GetScript() const {
10236 210 : return ToApiHandle<debug::Script>(script_->script);
10237 : }
10238 :
10239 690 : size_t debug::Coverage::ScriptData::FunctionCount() const {
10240 1380 : return script_->functions.size();
10241 : }
10242 :
10243 500 : debug::Coverage::FunctionData debug::Coverage::ScriptData::GetFunctionData(
10244 : size_t i) const {
10245 1000 : return FunctionData(&script_->functions.at(i), coverage_);
10246 : }
10247 :
10248 215 : debug::Coverage::ScriptData::ScriptData(size_t index,
10249 : std::shared_ptr<i::Coverage> coverage)
10250 645 : : script_(&coverage->at(index)), coverage_(std::move(coverage)) {}
10251 :
10252 770 : size_t debug::Coverage::ScriptCount() const { return coverage_->size(); }
10253 :
10254 215 : debug::Coverage::ScriptData debug::Coverage::GetScriptData(size_t i) const {
10255 430 : return ScriptData(i, coverage_);
10256 : }
10257 :
10258 125 : debug::Coverage debug::Coverage::CollectPrecise(Isolate* isolate) {
10259 : return Coverage(
10260 375 : i::Coverage::CollectPrecise(reinterpret_cast<i::Isolate*>(isolate)));
10261 : }
10262 :
10263 60 : debug::Coverage debug::Coverage::CollectBestEffort(Isolate* isolate) {
10264 : return Coverage(
10265 180 : i::Coverage::CollectBestEffort(reinterpret_cast<i::Isolate*>(isolate)));
10266 : }
10267 :
10268 362 : void debug::Coverage::SelectMode(Isolate* isolate, debug::Coverage::Mode mode) {
10269 362 : i::Coverage::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode);
10270 362 : }
10271 :
10272 185 : int debug::TypeProfile::Entry::SourcePosition() const {
10273 185 : return entry_->position;
10274 : }
10275 :
10276 185 : std::vector<MaybeLocal<String>> debug::TypeProfile::Entry::Types() const {
10277 : std::vector<MaybeLocal<String>> result;
10278 615 : for (const internal::Handle<internal::String>& type : entry_->types) {
10279 245 : result.emplace_back(ToApiHandle<String>(type));
10280 : }
10281 185 : return result;
10282 : }
10283 :
10284 40 : debug::TypeProfile::ScriptData::ScriptData(
10285 : size_t index, std::shared_ptr<i::TypeProfile> type_profile)
10286 40 : : script_(&type_profile->at(index)),
10287 80 : type_profile_(std::move(type_profile)) {}
10288 :
10289 40 : Local<debug::Script> debug::TypeProfile::ScriptData::GetScript() const {
10290 40 : return ToApiHandle<debug::Script>(script_->script);
10291 : }
10292 :
10293 40 : std::vector<debug::TypeProfile::Entry> debug::TypeProfile::ScriptData::Entries()
10294 : const {
10295 : std::vector<debug::TypeProfile::Entry> result;
10296 305 : for (const internal::TypeProfileEntry& entry : script_->entries) {
10297 185 : result.push_back(debug::TypeProfile::Entry(&entry, type_profile_));
10298 : }
10299 40 : return result;
10300 : }
10301 :
10302 50 : debug::TypeProfile debug::TypeProfile::Collect(Isolate* isolate) {
10303 : return TypeProfile(
10304 150 : i::TypeProfile::Collect(reinterpret_cast<i::Isolate*>(isolate)));
10305 : }
10306 :
10307 125 : void debug::TypeProfile::SelectMode(Isolate* isolate,
10308 : debug::TypeProfile::Mode mode) {
10309 125 : i::TypeProfile::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode);
10310 125 : }
10311 :
10312 180 : size_t debug::TypeProfile::ScriptCount() const { return type_profile_->size(); }
10313 :
10314 40 : debug::TypeProfile::ScriptData debug::TypeProfile::GetScriptData(
10315 : size_t i) const {
10316 80 : return ScriptData(i, type_profile_);
10317 : }
10318 :
10319 20 : const char* CpuProfileNode::GetFunctionNameStr() const {
10320 20 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10321 20 : return node->entry()->name();
10322 : }
10323 :
10324 125 : int CpuProfileNode::GetScriptId() const {
10325 125 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10326 125 : const i::CodeEntry* entry = node->entry();
10327 125 : return entry->script_id();
10328 : }
10329 :
10330 113 : Local<String> CpuProfileNode::GetScriptResourceName() const {
10331 226 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10332 : i::Isolate* isolate = node->isolate();
10333 : return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
10334 113 : node->entry()->resource_name()));
10335 : }
10336 :
10337 20 : const char* CpuProfileNode::GetScriptResourceNameStr() const {
10338 20 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10339 20 : return node->entry()->resource_name();
10340 : }
10341 :
10342 113 : int CpuProfileNode::GetLineNumber() const {
10343 113 : return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
10344 : }
10345 :
10346 :
10347 113 : int CpuProfileNode::GetColumnNumber() const {
10348 : return reinterpret_cast<const i::ProfileNode*>(this)->
10349 113 : entry()->column_number();
10350 : }
10351 :
10352 :
10353 93 : unsigned int CpuProfileNode::GetHitLineCount() const {
10354 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10355 93 : return node->GetHitLineCount();
10356 : }
10357 :
10358 :
10359 16 : bool CpuProfileNode::GetLineTicks(LineTick* entries,
10360 : unsigned int length) const {
10361 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10362 16 : return node->GetLineTicks(entries, length);
10363 : }
10364 :
10365 :
10366 99 : const char* CpuProfileNode::GetBailoutReason() const {
10367 99 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10368 99 : return node->entry()->bailout_reason();
10369 : }
10370 :
10371 :
10372 103 : unsigned CpuProfileNode::GetHitCount() const {
10373 103 : return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
10374 : }
10375 :
10376 :
10377 0 : unsigned CpuProfileNode::GetCallUid() const {
10378 0 : return reinterpret_cast<const i::ProfileNode*>(this)->function_id();
10379 : }
10380 :
10381 :
10382 223 : unsigned CpuProfileNode::GetNodeId() const {
10383 223 : return reinterpret_cast<const i::ProfileNode*>(this)->id();
10384 : }
10385 :
10386 :
10387 394 : int CpuProfileNode::GetChildrenCount() const {
10388 : return static_cast<int>(
10389 788 : reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
10390 : }
10391 :
10392 :
10393 397 : const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
10394 : const i::ProfileNode* child =
10395 794 : reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
10396 397 : return reinterpret_cast<const CpuProfileNode*>(child);
10397 : }
10398 :
10399 :
10400 0 : const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
10401 : const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10402 0 : return node->deopt_infos();
10403 : }
10404 :
10405 :
10406 119 : void CpuProfile::Delete() {
10407 119 : i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
10408 : i::CpuProfiler* profiler = profile->cpu_profiler();
10409 : DCHECK_NOT_NULL(profiler);
10410 119 : profiler->DeleteProfile(profile);
10411 119 : }
10412 :
10413 :
10414 0 : Local<String> CpuProfile::GetTitle() const {
10415 0 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10416 0 : i::Isolate* isolate = profile->top_down()->isolate();
10417 : return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
10418 0 : profile->title()));
10419 : }
10420 :
10421 :
10422 105 : const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
10423 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10424 105 : return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
10425 : }
10426 :
10427 :
10428 7988 : const CpuProfileNode* CpuProfile::GetSample(int index) const {
10429 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10430 7988 : return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
10431 : }
10432 :
10433 :
10434 7988 : int64_t CpuProfile::GetSampleTimestamp(int index) const {
10435 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10436 15976 : return (profile->sample_timestamp(index) - base::TimeTicks())
10437 7988 : .InMicroseconds();
10438 : }
10439 :
10440 :
10441 68 : int64_t CpuProfile::GetStartTime() const {
10442 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10443 68 : return (profile->start_time() - base::TimeTicks()).InMicroseconds();
10444 : }
10445 :
10446 :
10447 39 : int64_t CpuProfile::GetEndTime() const {
10448 : const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10449 39 : return (profile->end_time() - base::TimeTicks()).InMicroseconds();
10450 : }
10451 :
10452 :
10453 7990 : int CpuProfile::GetSamplesCount() const {
10454 7990 : return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
10455 : }
10456 :
10457 186 : CpuProfiler* CpuProfiler::New(Isolate* isolate) {
10458 : return reinterpret_cast<CpuProfiler*>(
10459 186 : new i::CpuProfiler(reinterpret_cast<i::Isolate*>(isolate)));
10460 : }
10461 :
10462 186 : void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
10463 :
10464 40 : void CpuProfiler::SetSamplingInterval(int us) {
10465 : DCHECK_GE(us, 0);
10466 : return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
10467 40 : base::TimeDelta::FromMicroseconds(us));
10468 : }
10469 :
10470 5 : void CpuProfiler::CollectSample() {
10471 5 : reinterpret_cast<i::CpuProfiler*>(this)->CollectSample();
10472 5 : }
10473 :
10474 236 : void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
10475 : reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10476 472 : *Utils::OpenHandle(*title), record_samples);
10477 236 : }
10478 :
10479 :
10480 156 : CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
10481 : return reinterpret_cast<CpuProfile*>(
10482 : reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
10483 156 : *Utils::OpenHandle(*title)));
10484 : }
10485 :
10486 :
10487 37 : void CpuProfiler::SetIdle(bool is_idle) {
10488 37 : i::CpuProfiler* profiler = reinterpret_cast<i::CpuProfiler*>(this);
10489 47 : i::Isolate* isolate = profiler->isolate();
10490 37 : if (!isolate->is_profiling()) return;
10491 : v8::StateTag state = isolate->current_vm_state();
10492 : DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
10493 10 : if (isolate->js_entry_sp() != nullptr) return;
10494 10 : if (is_idle) {
10495 : isolate->set_current_vm_state(v8::IDLE);
10496 5 : } else if (state == v8::IDLE) {
10497 : isolate->set_current_vm_state(v8::EXTERNAL);
10498 : }
10499 : }
10500 :
10501 :
10502 : static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10503 : return const_cast<i::HeapGraphEdge*>(
10504 : reinterpret_cast<const i::HeapGraphEdge*>(edge));
10505 : }
10506 :
10507 :
10508 6055345 : HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10509 12110690 : return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10510 : }
10511 :
10512 :
10513 6007002 : Local<Value> HeapGraphEdge::GetName() const {
10514 12014004 : i::HeapGraphEdge* edge = ToInternal(this);
10515 : i::Isolate* isolate = edge->isolate();
10516 6007002 : switch (edge->type()) {
10517 : case i::HeapGraphEdge::kContextVariable:
10518 : case i::HeapGraphEdge::kInternal:
10519 : case i::HeapGraphEdge::kProperty:
10520 : case i::HeapGraphEdge::kShortcut:
10521 : case i::HeapGraphEdge::kWeak:
10522 : return ToApiHandle<String>(
10523 6005807 : isolate->factory()->InternalizeUtf8String(edge->name()));
10524 : case i::HeapGraphEdge::kElement:
10525 : case i::HeapGraphEdge::kHidden:
10526 : return ToApiHandle<Number>(
10527 1195 : isolate->factory()->NewNumberFromInt(edge->index()));
10528 0 : default: UNREACHABLE();
10529 : }
10530 : return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
10531 : }
10532 :
10533 :
10534 320 : const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10535 : const i::HeapEntry* from = ToInternal(this)->from();
10536 320 : return reinterpret_cast<const HeapGraphNode*>(from);
10537 : }
10538 :
10539 :
10540 787119 : const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10541 787119 : const i::HeapEntry* to = ToInternal(this)->to();
10542 787119 : return reinterpret_cast<const HeapGraphNode*>(to);
10543 : }
10544 :
10545 :
10546 : static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10547 : return const_cast<i::HeapEntry*>(
10548 : reinterpret_cast<const i::HeapEntry*>(entry));
10549 : }
10550 :
10551 :
10552 390 : HeapGraphNode::Type HeapGraphNode::GetType() const {
10553 390 : return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10554 : }
10555 :
10556 :
10557 1860 : Local<String> HeapGraphNode::GetName() const {
10558 1860 : i::Isolate* isolate = ToInternal(this)->isolate();
10559 : return ToApiHandle<String>(
10560 1860 : isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10561 : }
10562 :
10563 :
10564 640325 : SnapshotObjectId HeapGraphNode::GetId() const {
10565 640325 : return ToInternal(this)->id();
10566 : }
10567 :
10568 :
10569 20 : size_t HeapGraphNode::GetShallowSize() const {
10570 20 : return ToInternal(this)->self_size();
10571 : }
10572 :
10573 :
10574 70264 : int HeapGraphNode::GetChildrenCount() const {
10575 70264 : return ToInternal(this)->children_count();
10576 : }
10577 :
10578 :
10579 6413853 : const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10580 6413853 : return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10581 : }
10582 :
10583 :
10584 : static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10585 : return const_cast<i::HeapSnapshot*>(
10586 : reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10587 : }
10588 :
10589 :
10590 35 : void HeapSnapshot::Delete() {
10591 100 : i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10592 35 : if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
10593 5 : ToInternal(this)->Delete();
10594 : } else {
10595 : // If this is the last snapshot, clean up all accessory data as well.
10596 30 : isolate->heap_profiler()->DeleteAllSnapshots();
10597 : }
10598 35 : }
10599 :
10600 :
10601 448 : const HeapGraphNode* HeapSnapshot::GetRoot() const {
10602 448 : return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10603 : }
10604 :
10605 :
10606 213765 : const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10607 : return reinterpret_cast<const HeapGraphNode*>(
10608 213765 : ToInternal(this)->GetEntryById(id));
10609 : }
10610 :
10611 :
10612 10 : int HeapSnapshot::GetNodesCount() const {
10613 20 : return static_cast<int>(ToInternal(this)->entries().size());
10614 : }
10615 :
10616 :
10617 77530 : const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10618 : return reinterpret_cast<const HeapGraphNode*>(
10619 155060 : &ToInternal(this)->entries().at(index));
10620 : }
10621 :
10622 :
10623 20 : SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10624 20 : return ToInternal(this)->max_snapshot_js_object_id();
10625 : }
10626 :
10627 :
10628 30 : void HeapSnapshot::Serialize(OutputStream* stream,
10629 : HeapSnapshot::SerializationFormat format) const {
10630 : Utils::ApiCheck(format == kJSON,
10631 : "v8::HeapSnapshot::Serialize",
10632 : "Unknown serialization format");
10633 30 : Utils::ApiCheck(stream->GetChunkSize() > 0,
10634 : "v8::HeapSnapshot::Serialize",
10635 : "Invalid stream chunk size");
10636 : i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10637 30 : serializer.Serialize(stream);
10638 30 : }
10639 :
10640 :
10641 : // static
10642 : STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10643 : HeapProfiler::kUnknownObjectId;
10644 :
10645 :
10646 115 : int HeapProfiler::GetSnapshotCount() {
10647 115 : return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10648 : }
10649 :
10650 :
10651 30 : const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10652 : return reinterpret_cast<const HeapSnapshot*>(
10653 30 : reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10654 : }
10655 :
10656 :
10657 155 : SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10658 155 : i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10659 155 : return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10660 : }
10661 :
10662 :
10663 140 : Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10664 : i::Handle<i::Object> obj =
10665 140 : reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10666 140 : if (obj.is_null()) return Local<Value>();
10667 : return Utils::ToLocal(obj);
10668 : }
10669 :
10670 :
10671 3411 : void HeapProfiler::ClearObjectIds() {
10672 3411 : reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
10673 3411 : }
10674 :
10675 :
10676 319 : const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
10677 : ActivityControl* control, ObjectNameResolver* resolver) {
10678 : return reinterpret_cast<const HeapSnapshot*>(
10679 : reinterpret_cast<i::HeapProfiler*>(this)
10680 319 : ->TakeSnapshot(control, resolver));
10681 : }
10682 :
10683 :
10684 40 : void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
10685 : reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
10686 40 : track_allocations);
10687 40 : }
10688 :
10689 :
10690 3446 : void HeapProfiler::StopTrackingHeapObjects() {
10691 3446 : reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
10692 3446 : }
10693 :
10694 :
10695 55 : SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
10696 : int64_t* timestamp_us) {
10697 : i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
10698 55 : return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
10699 : }
10700 :
10701 28 : bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
10702 : int stack_depth,
10703 : SamplingFlags flags) {
10704 : return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
10705 28 : sample_interval, stack_depth, flags);
10706 : }
10707 :
10708 :
10709 28 : void HeapProfiler::StopSamplingHeapProfiler() {
10710 28 : reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
10711 28 : }
10712 :
10713 :
10714 31 : AllocationProfile* HeapProfiler::GetAllocationProfile() {
10715 31 : return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
10716 : }
10717 :
10718 :
10719 25 : void HeapProfiler::DeleteAllHeapSnapshots() {
10720 25 : reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
10721 25 : }
10722 :
10723 :
10724 10 : void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
10725 : WrapperInfoCallback callback) {
10726 : reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
10727 10 : callback);
10728 10 : }
10729 :
10730 0 : void HeapProfiler::SetGetRetainerInfosCallback(
10731 : GetRetainerInfosCallback callback) {
10732 : reinterpret_cast<i::HeapProfiler*>(this)->SetGetRetainerInfosCallback(
10733 0 : callback);
10734 0 : }
10735 :
10736 : v8::Testing::StressType internal::Testing::stress_type_ =
10737 : v8::Testing::kStressTypeOpt;
10738 :
10739 :
10740 4402 : void Testing::SetStressRunType(Testing::StressType type) {
10741 : internal::Testing::set_stress_type(type);
10742 4402 : }
10743 :
10744 :
10745 4402 : int Testing::GetStressRuns() {
10746 44012 : if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
10747 : #ifdef DEBUG
10748 : // In debug mode the code runs much slower so stressing will only make two
10749 : // runs.
10750 : return 2;
10751 : #else
10752 : return 5;
10753 : #endif
10754 : }
10755 :
10756 :
10757 17605 : static void SetFlagsFromString(const char* flags) {
10758 : V8::SetFlagsFromString(flags, i::StrLength(flags));
10759 17605 : }
10760 :
10761 :
10762 22006 : void Testing::PrepareStressRun(int run) {
10763 : static const char* kLazyOptimizations =
10764 : "--prepare-always-opt "
10765 : "--max-inlined-bytecode-size=999999 "
10766 : "--max-inlined-bytecode-size-cumulative=999999 "
10767 : "--noalways-opt";
10768 : static const char* kForcedOptimizations = "--always-opt";
10769 :
10770 : // If deoptimization stressed turn on frequent deoptimization. If no value
10771 : // is spefified through --deopt-every-n-times use a default default value.
10772 : static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
10773 22006 : if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
10774 0 : internal::FLAG_deopt_every_n_times == 0) {
10775 0 : SetFlagsFromString(kDeoptEvery13Times);
10776 : }
10777 :
10778 : #ifdef DEBUG
10779 : // As stressing in debug mode only make two runs skip the deopt stressing
10780 : // here.
10781 : if (run == GetStressRuns() - 1) {
10782 : SetFlagsFromString(kForcedOptimizations);
10783 : } else {
10784 : SetFlagsFromString(kLazyOptimizations);
10785 : }
10786 : #else
10787 22006 : if (run == GetStressRuns() - 1) {
10788 4402 : SetFlagsFromString(kForcedOptimizations);
10789 17604 : } else if (run != GetStressRuns() - 2) {
10790 13203 : SetFlagsFromString(kLazyOptimizations);
10791 : }
10792 : #endif
10793 22006 : }
10794 :
10795 :
10796 4402 : void Testing::DeoptimizeAll(Isolate* isolate) {
10797 : i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
10798 : i::HandleScope scope(i_isolate);
10799 4402 : internal::Deoptimizer::DeoptimizeAll(i_isolate);
10800 4402 : }
10801 :
10802 :
10803 : namespace internal {
10804 :
10805 5856 : void HandleScopeImplementer::FreeThreadResources() {
10806 5856 : Free();
10807 5856 : }
10808 :
10809 :
10810 24163 : char* HandleScopeImplementer::ArchiveThread(char* storage) {
10811 24163 : HandleScopeData* current = isolate_->handle_scope_data();
10812 24163 : handle_scope_data_ = *current;
10813 : MemCopy(storage, this, sizeof(*this));
10814 :
10815 : ResetAfterArchive();
10816 : current->Initialize();
10817 :
10818 24163 : return storage + ArchiveSpacePerThread();
10819 : }
10820 :
10821 :
10822 93644 : int HandleScopeImplementer::ArchiveSpacePerThread() {
10823 93644 : return sizeof(HandleScopeImplementer);
10824 : }
10825 :
10826 :
10827 24163 : char* HandleScopeImplementer::RestoreThread(char* storage) {
10828 : MemCopy(this, storage, sizeof(*this));
10829 24163 : *isolate_->handle_scope_data() = handle_scope_data_;
10830 24163 : return storage + ArchiveSpacePerThread();
10831 : }
10832 :
10833 470845 : void HandleScopeImplementer::IterateThis(RootVisitor* v) {
10834 : #ifdef DEBUG
10835 : bool found_block_before_deferred = false;
10836 : #endif
10837 : // Iterate over all handles in the blocks except for the last.
10838 558508 : for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
10839 87663 : Object** block = blocks()->at(i);
10840 87668 : if (last_handle_before_deferred_block_ != nullptr &&
10841 10 : (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
10842 : (last_handle_before_deferred_block_ >= block)) {
10843 : v->VisitRootPointers(Root::kHandleScope, block,
10844 5 : last_handle_before_deferred_block_);
10845 5 : DCHECK(!found_block_before_deferred);
10846 : #ifdef DEBUG
10847 : found_block_before_deferred = true;
10848 : #endif
10849 : } else {
10850 87658 : v->VisitRootPointers(Root::kHandleScope, block, &block[kHandleBlockSize]);
10851 : }
10852 : }
10853 :
10854 : DCHECK(last_handle_before_deferred_block_ == nullptr ||
10855 : found_block_before_deferred);
10856 :
10857 : // Iterate over live handles in the last block (if any).
10858 470845 : if (!blocks()->empty()) {
10859 : v->VisitRootPointers(Root::kHandleScope, blocks()->back(),
10860 521894 : handle_scope_data_.next);
10861 : }
10862 :
10863 : DetachableVector<Context*>* context_lists[2] = {&saved_contexts_,
10864 470843 : &entered_contexts_};
10865 1412533 : for (unsigned i = 0; i < arraysize(context_lists); i++) {
10866 1883376 : if (context_lists[i]->empty()) continue;
10867 : Object** start = reinterpret_cast<Object**>(&context_lists[i]->front());
10868 : v->VisitRootPointers(Root::kHandleScope, start,
10869 1112660 : start + context_lists[i]->size());
10870 : }
10871 470845 : if (microtask_context_) {
10872 : v->VisitRootPointer(Root::kHandleScope,
10873 1330 : reinterpret_cast<Object**>(µtask_context_));
10874 : }
10875 470845 : }
10876 :
10877 464851 : void HandleScopeImplementer::Iterate(RootVisitor* v) {
10878 464851 : HandleScopeData* current = isolate_->handle_scope_data();
10879 464851 : handle_scope_data_ = *current;
10880 464851 : IterateThis(v);
10881 464851 : }
10882 :
10883 5994 : char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
10884 : HandleScopeImplementer* scope_implementer =
10885 : reinterpret_cast<HandleScopeImplementer*>(storage);
10886 5994 : scope_implementer->IterateThis(v);
10887 5994 : return storage + ArchiveSpacePerThread();
10888 : }
10889 :
10890 :
10891 9393 : DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
10892 : DeferredHandles* deferred =
10893 9393 : new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
10894 :
10895 28179 : while (!blocks_.empty()) {
10896 18786 : Object** block_start = blocks_.back();
10897 18786 : Object** block_limit = &block_start[kHandleBlockSize];
10898 : // We should not need to check for SealHandleScope here. Assert this.
10899 : DCHECK(prev_limit == block_limit ||
10900 : !(block_start <= prev_limit && prev_limit <= block_limit));
10901 18786 : if (prev_limit == block_limit) break;
10902 9393 : deferred->blocks_.push_back(blocks_.back());
10903 : blocks_.pop_back();
10904 : }
10905 :
10906 : // deferred->blocks_ now contains the blocks installed on the
10907 : // HandleScope stack since BeginDeferredScope was called, but in
10908 : // reverse order.
10909 :
10910 : DCHECK(prev_limit == nullptr || !blocks_.empty());
10911 :
10912 : DCHECK(!blocks_.empty() && prev_limit != nullptr);
10913 : DCHECK_NOT_NULL(last_handle_before_deferred_block_);
10914 9393 : last_handle_before_deferred_block_ = nullptr;
10915 9393 : return deferred;
10916 : }
10917 :
10918 :
10919 9393 : void HandleScopeImplementer::BeginDeferredScope() {
10920 : DCHECK_NULL(last_handle_before_deferred_block_);
10921 9393 : last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
10922 9393 : }
10923 :
10924 :
10925 9390 : DeferredHandles::~DeferredHandles() {
10926 18780 : isolate_->UnlinkDeferredHandles(this);
10927 :
10928 37560 : for (size_t i = 0; i < blocks_.size(); i++) {
10929 : #ifdef ENABLE_HANDLE_ZAPPING
10930 28170 : HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
10931 : #endif
10932 9390 : isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
10933 : }
10934 9390 : }
10935 :
10936 2349 : void DeferredHandles::Iterate(RootVisitor* v) {
10937 : DCHECK(!blocks_.empty());
10938 :
10939 : DCHECK((first_block_limit_ >= blocks_.front()) &&
10940 : (first_block_limit_ <= &(blocks_.front())[kHandleBlockSize]));
10941 :
10942 7047 : v->VisitRootPointers(Root::kHandleScope, blocks_.front(), first_block_limit_);
10943 :
10944 4698 : for (size_t i = 1; i < blocks_.size(); i++) {
10945 : v->VisitRootPointers(Root::kHandleScope, blocks_[i],
10946 0 : &blocks_[i][kHandleBlockSize]);
10947 : }
10948 2349 : }
10949 :
10950 :
10951 780 : void InvokeAccessorGetterCallback(
10952 : v8::Local<v8::Name> property,
10953 : const v8::PropertyCallbackInfo<v8::Value>& info,
10954 : v8::AccessorNameGetterCallback getter) {
10955 : // Leaving JavaScript.
10956 : Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10957 : RuntimeCallTimerScope timer(isolate,
10958 780 : &RuntimeCallStats::AccessorGetterCallback);
10959 : Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
10960 : getter));
10961 1560 : VMState<EXTERNAL> state(isolate);
10962 1560 : ExternalCallbackScope call_scope(isolate, getter_address);
10963 780 : getter(property, info);
10964 780 : }
10965 :
10966 :
10967 66 : void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
10968 : v8::FunctionCallback callback) {
10969 : Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
10970 : RuntimeCallTimerScope timer(isolate,
10971 66 : &RuntimeCallStats::InvokeFunctionCallback);
10972 : Address callback_address =
10973 : reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
10974 132 : VMState<EXTERNAL> state(isolate);
10975 132 : ExternalCallbackScope call_scope(isolate, callback_address);
10976 66 : callback(info);
10977 66 : }
10978 :
10979 :
10980 : } // namespace internal
10981 : } // namespace v8
|