1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/api/api.h"
6
7 #include <algorithm> // For min
8 #include <cmath> // For isnan.
9 #include <limits>
10 #include <string>
11 #include <utility> // For move
12 #include <vector>
13
14 #include "include/v8-cppgc.h"
15 #include "include/v8-fast-api-calls.h"
16 #include "include/v8-profiler.h"
17 #include "include/v8-unwinder-state.h"
18 #include "include/v8-util.h"
19 #include "src/api/api-inl.h"
20 #include "src/api/api-natives.h"
21 #include "src/base/functional.h"
22 #include "src/base/logging.h"
23 #include "src/base/platform/platform.h"
24 #include "src/base/platform/time.h"
25 #include "src/base/safe_conversions.h"
26 #include "src/base/utils/random-number-generator.h"
27 #include "src/builtins/accessors.h"
28 #include "src/builtins/builtins-utils.h"
29 #include "src/codegen/compiler.h"
30 #include "src/codegen/cpu-features.h"
31 #include "src/common/assert-scope.h"
32 #include "src/common/external-pointer.h"
33 #include "src/common/globals.h"
34 #include "src/compiler-dispatcher/compiler-dispatcher.h"
35 #include "src/date/date.h"
36 #include "src/debug/debug-coverage.h"
37 #include "src/debug/debug-evaluate.h"
38 #include "src/debug/debug-type-profile.h"
39 #include "src/debug/debug.h"
40 #include "src/debug/liveedit.h"
41 #include "src/deoptimizer/deoptimizer.h"
42 #include "src/diagnostics/gdb-jit.h"
43 #include "src/execution/execution.h"
44 #include "src/execution/frames-inl.h"
45 #include "src/execution/isolate-inl.h"
46 #include "src/execution/messages.h"
47 #include "src/execution/microtask-queue.h"
48 #include "src/execution/runtime-profiler.h"
49 #include "src/execution/simulator.h"
50 #include "src/execution/v8threads.h"
51 #include "src/execution/vm-state-inl.h"
52 #include "src/handles/global-handles.h"
53 #include "src/handles/persistent-handles.h"
54 #include "src/heap/embedder-tracing.h"
55 #include "src/heap/heap-inl.h"
56 #include "src/init/bootstrapper.h"
57 #include "src/init/icu_util.h"
58 #include "src/init/startup-data-util.h"
59 #include "src/init/v8.h"
60 #include "src/json/json-parser.h"
61 #include "src/json/json-stringifier.h"
62 #include "src/logging/counters.h"
63 #include "src/logging/metrics.h"
64 #include "src/logging/tracing-flags.h"
65 #include "src/numbers/conversions-inl.h"
66 #include "src/objects/api-callbacks.h"
67 #include "src/objects/contexts.h"
68 #include "src/objects/embedder-data-array-inl.h"
69 #include "src/objects/embedder-data-slot-inl.h"
70 #include "src/objects/frame-array-inl.h"
71 #include "src/objects/hash-table-inl.h"
72 #include "src/objects/heap-object.h"
73 #include "src/objects/js-array-inl.h"
74 #include "src/objects/js-collection-inl.h"
75 #include "src/objects/js-generator-inl.h"
76 #include "src/objects/js-promise-inl.h"
77 #include "src/objects/js-regexp-inl.h"
78 #include "src/objects/js-weak-refs-inl.h"
79 #include "src/objects/module-inl.h"
80 #include "src/objects/objects-inl.h"
81 #include "src/objects/oddball.h"
82 #include "src/objects/ordered-hash-table-inl.h"
83 #include "src/objects/property-descriptor.h"
84 #include "src/objects/property-details.h"
85 #include "src/objects/property.h"
86 #include "src/objects/prototype.h"
87 #include "src/objects/slots.h"
88 #include "src/objects/smi.h"
89 #include "src/objects/stack-frame-info-inl.h"
90 #include "src/objects/synthetic-module-inl.h"
91 #include "src/objects/templates.h"
92 #include "src/objects/value-serializer.h"
93 #include "src/parsing/parse-info.h"
94 #include "src/parsing/parser.h"
95 #include "src/parsing/pending-compilation-error-handler.h"
96 #include "src/parsing/scanner-character-streams.h"
97 #include "src/profiler/cpu-profiler.h"
98 #include "src/profiler/heap-profiler.h"
99 #include "src/profiler/heap-snapshot-generator-inl.h"
100 #include "src/profiler/profile-generator-inl.h"
101 #include "src/profiler/tick-sample.h"
102 #include "src/regexp/regexp-utils.h"
103 #include "src/runtime/runtime.h"
104 #include "src/snapshot/code-serializer.h"
105 #include "src/snapshot/embedded/embedded-data.h"
106 #include "src/snapshot/snapshot.h"
107 #include "src/snapshot/startup-serializer.h" // For SerializedHandleChecker.
108 #include "src/strings/char-predicates-inl.h"
109 #include "src/strings/string-hasher.h"
110 #include "src/strings/unicode-inl.h"
111 #include "src/tracing/trace-event.h"
112 #include "src/trap-handler/trap-handler.h"
113 #include "src/utils/detachable-vector.h"
114 #include "src/utils/version.h"
115 #include "src/wasm/streaming-decoder.h"
116 #include "src/wasm/value-type.h"
117 #include "src/wasm/wasm-engine.h"
118 #include "src/wasm/wasm-objects-inl.h"
119 #include "src/wasm/wasm-result.h"
120 #include "src/wasm/wasm-serialization.h"
121
122 #if V8_OS_LINUX || V8_OS_MACOSX || V8_OS_FREEBSD
123 #include <signal.h>
124 #include "include/v8-wasm-trap-handler-posix.h"
125 #include "src/trap-handler/handler-inside-posix.h"
126 #endif
127
128 #if V8_OS_WIN
129 #include <versionhelpers.h>
130 #include <windows.h>
131 #include "include/v8-wasm-trap-handler-win.h"
132 #include "src/trap-handler/handler-inside-win.h"
133 #if defined(V8_OS_WIN64)
134 #include "src/diagnostics/unwinding-info-win64.h"
135 #endif // V8_OS_WIN64
136 #endif // V8_OS_WIN
137
138 #define TRACE_BS(...) \
139 do { \
140 if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \
141 } while (false)
142
143 namespace v8 {
144
145 /*
146 * Most API methods should use one of the three macros:
147 *
148 * ENTER_V8, ENTER_V8_NO_SCRIPT, ENTER_V8_NO_SCRIPT_NO_EXCEPTION.
149 *
150 * The latter two assume that no script is executed, and no exceptions are
151 * scheduled in addition (respectively). Creating a pending exception and
152 * removing it before returning is ok.
153 *
154 * Exceptions should be handled either by invoking one of the
155 * RETURN_ON_FAILED_EXECUTION* macros.
156 *
157 * Don't use macros with DO_NOT_USE in their name.
158 *
159 * TODO(jochen): Document debugger specific macros.
160 * TODO(jochen): Document LOG_API and other RuntimeCallStats macros.
161 * TODO(jochen): All API methods should invoke one of the ENTER_V8* macros.
162 * TODO(jochen): Remove calls form API methods to DO_NOT_USE macros.
163 */
164
165 #define LOG_API(isolate, class_name, function_name) \
166 i::RuntimeCallTimerScope _runtime_timer( \
167 isolate, i::RuntimeCallCounterId::kAPI_##class_name##_##function_name); \
168 LOG(isolate, ApiEntryCall("v8::" #class_name "::" #function_name))
169
170 #define ENTER_V8_DO_NOT_USE(isolate) i::VMState<v8::OTHER> __state__((isolate))
171
172 #define ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, \
173 function_name, bailout_value, \
174 HandleScopeClass, do_callback) \
175 if (IsExecutionTerminatingCheck(isolate)) { \
176 return bailout_value; \
177 } \
178 HandleScopeClass handle_scope(isolate); \
179 CallDepthScope<do_callback> call_depth_scope(isolate, context); \
180 LOG_API(isolate, class_name, function_name); \
181 i::VMState<v8::OTHER> __state__((isolate)); \
182 bool has_pending_exception = false
183
184 #define PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, T) \
185 if (IsExecutionTerminatingCheck(isolate)) { \
186 return MaybeLocal<T>(); \
187 } \
188 InternalEscapableScope handle_scope(isolate); \
189 CallDepthScope<false> call_depth_scope(isolate, v8::Local<v8::Context>()); \
190 i::VMState<v8::OTHER> __state__((isolate)); \
191 bool has_pending_exception = false
192
193 #define PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
194 bailout_value, HandleScopeClass, \
195 do_callback) \
196 auto isolate = context.IsEmpty() \
197 ? i::Isolate::Current() \
198 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
199 ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
200 bailout_value, HandleScopeClass, do_callback);
201
202 #define PREPARE_FOR_EXECUTION(context, class_name, function_name, T) \
203 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, class_name, function_name, \
204 MaybeLocal<T>(), InternalEscapableScope, \
205 false)
206
207 #define ENTER_V8(isolate, context, class_name, function_name, bailout_value, \
208 HandleScopeClass) \
209 ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
210 bailout_value, HandleScopeClass, true)
211
212 #ifdef DEBUG
213 #define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \
214 bailout_value, HandleScopeClass) \
215 ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
216 bailout_value, HandleScopeClass, false); \
217 i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate))
218
219 #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \
220 i::VMState<v8::OTHER> __state__((isolate)); \
221 i::DisallowJavascriptExecutionDebugOnly __no_script__((isolate)); \
222 i::DisallowExceptions __no_exceptions__((isolate))
223
224 #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \
225 i::VMState<v8::OTHER> __state__((isolate)); \
226 i::DisallowExceptions __no_exceptions__((isolate))
227 #else
228 #define ENTER_V8_NO_SCRIPT(isolate, context, class_name, function_name, \
229 bailout_value, HandleScopeClass) \
230 ENTER_V8_HELPER_DO_NOT_USE(isolate, context, class_name, function_name, \
231 bailout_value, HandleScopeClass, false)
232
233 #define ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate) \
234 i::VMState<v8::OTHER> __state__((isolate));
235
236 #define ENTER_V8_FOR_NEW_CONTEXT(isolate) \
237 i::VMState<v8::OTHER> __state__((isolate));
238 #endif // DEBUG
239
240 #define EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, value) \
241 do { \
242 if (has_pending_exception) { \
243 call_depth_scope.Escape(); \
244 return value; \
245 } \
246 } while (false)
247
248 #define RETURN_ON_FAILED_EXECUTION(T) \
249 EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, MaybeLocal<T>())
250
251 #define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \
252 EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE(isolate, Nothing<T>())
253
254 #define RETURN_ESCAPED(value) return handle_scope.Escape(value);
255
256 namespace {
257
258 class InternalEscapableScope : public v8::EscapableHandleScope {
259 public:
InternalEscapableScope(i::Isolate * isolate)260 explicit inline InternalEscapableScope(i::Isolate* isolate)
261 : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {}
262 };
263
264 // TODO(jochen): This should be #ifdef DEBUG
265 #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY
CheckMicrotasksScopesConsistency(i::MicrotaskQueue * microtask_queue)266 void CheckMicrotasksScopesConsistency(i::MicrotaskQueue* microtask_queue) {
267 if (microtask_queue &&
268 microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kScoped) {
269 DCHECK(microtask_queue->GetMicrotasksScopeDepth() ||
270 !microtask_queue->DebugMicrotasksScopeDepthIsZero());
271 }
272 }
273 #endif
274
275 template <bool do_callback>
276 class CallDepthScope {
277 public:
CallDepthScope(i::Isolate * isolate,Local<Context> context)278 CallDepthScope(i::Isolate* isolate, Local<Context> context)
279 : isolate_(isolate),
280 context_(context),
281 escaped_(false),
282 safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()),
283 interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION,
284 isolate_->only_terminate_in_safe_scope()
285 ? (safe_for_termination_
286 ? i::InterruptsScope::kRunInterrupts
287 : i::InterruptsScope::kPostponeInterrupts)
288 : i::InterruptsScope::kNoop) {
289 isolate_->thread_local_top()->IncrementCallDepth(this);
290 isolate_->set_next_v8_call_is_safe_for_termination(false);
291 if (!context.IsEmpty()) {
292 i::Handle<i::Context> env = Utils::OpenHandle(*context);
293 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
294 if (!isolate->context().is_null() &&
295 isolate->context().native_context() == env->native_context()) {
296 context_ = Local<Context>();
297 } else {
298 impl->SaveContext(isolate->context());
299 isolate->set_context(*env);
300 }
301 }
302 if (do_callback) isolate_->FireBeforeCallEnteredCallback();
303 }
~CallDepthScope()304 ~CallDepthScope() {
305 i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue();
306 if (!context_.IsEmpty()) {
307 i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
308 isolate_->set_context(impl->RestoreContext());
309
310 i::Handle<i::Context> env = Utils::OpenHandle(*context_);
311 microtask_queue = env->native_context().microtask_queue();
312 }
313 if (!escaped_) isolate_->thread_local_top()->DecrementCallDepth(this);
314 if (do_callback) isolate_->FireCallCompletedCallback(microtask_queue);
315 // TODO(jochen): This should be #ifdef DEBUG
316 #ifdef V8_CHECK_MICROTASKS_SCOPES_CONSISTENCY
317 if (do_callback) CheckMicrotasksScopesConsistency(microtask_queue);
318 #endif
319 DCHECK(CheckKeptObjectsClearedAfterMicrotaskCheckpoint(microtask_queue));
320 isolate_->set_next_v8_call_is_safe_for_termination(safe_for_termination_);
321 }
322
Escape()323 void Escape() {
324 DCHECK(!escaped_);
325 escaped_ = true;
326 auto thread_local_top = isolate_->thread_local_top();
327 thread_local_top->DecrementCallDepth(this);
328 bool clear_exception = thread_local_top->CallDepthIsZero() &&
329 thread_local_top->try_catch_handler_ == nullptr;
330 isolate_->OptionalRescheduleException(clear_exception);
331 }
332
333 private:
CheckKeptObjectsClearedAfterMicrotaskCheckpoint(i::MicrotaskQueue * microtask_queue)334 bool CheckKeptObjectsClearedAfterMicrotaskCheckpoint(
335 i::MicrotaskQueue* microtask_queue) {
336 bool did_perform_microtask_checkpoint =
337 isolate_->thread_local_top()->CallDepthIsZero() &&
338 do_callback && microtask_queue &&
339 microtask_queue->microtasks_policy() == MicrotasksPolicy::kAuto;
340 return !did_perform_microtask_checkpoint ||
341 isolate_->heap()->weak_refs_keep_during_job().IsUndefined(isolate_);
342 }
343
344 i::Isolate* const isolate_;
345 Local<Context> context_;
346 bool escaped_;
347 bool do_callback_;
348 bool safe_for_termination_;
349 i::InterruptsScope interrupts_scope_;
350 i::Address previous_stack_height_;
351
352 friend class i::ThreadLocalTop;
353
354 DISALLOW_NEW_AND_DELETE()
355 DISALLOW_COPY_AND_ASSIGN(CallDepthScope);
356 };
357
358 } // namespace
359
GetScriptOriginForScript(i::Isolate * isolate,i::Handle<i::Script> script)360 static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
361 i::Handle<i::Script> script) {
362 i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
363 i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
364 i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(),
365 isolate);
366 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
367 ScriptOriginOptions options(script->origin_options());
368 v8::ScriptOrigin origin(
369 Utils::ToLocal(scriptName),
370 v8::Integer::New(v8_isolate, script->line_offset()),
371 v8::Integer::New(v8_isolate, script->column_offset()),
372 v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
373 v8::Integer::New(v8_isolate, script->id()),
374 Utils::ToLocal(source_map_url),
375 v8::Boolean::New(v8_isolate, options.IsOpaque()),
376 v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM),
377 v8::Boolean::New(v8_isolate, options.IsModule()),
378 Utils::ToLocal(host_defined_options));
379 return origin;
380 }
381
382 // --- E x c e p t i o n B e h a v i o r ---
383
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location)384 void i::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location) {
385 i::V8::FatalProcessOutOfMemory(isolate, location, false);
386 }
387
388 // When V8 cannot allocate memory FatalProcessOutOfMemory is called. The default
389 // OOM error handler is called and execution is stopped.
FatalProcessOutOfMemory(i::Isolate * isolate,const char * location,bool is_heap_oom)390 void i::V8::FatalProcessOutOfMemory(i::Isolate* isolate, const char* location,
391 bool is_heap_oom) {
392 char last_few_messages[Heap::kTraceRingBufferSize + 1];
393 char js_stacktrace[Heap::kStacktraceBufferSize + 1];
394 i::HeapStats heap_stats;
395
396 if (isolate == nullptr) {
397 isolate = Isolate::TryGetCurrent();
398 }
399
400 if (isolate == nullptr) {
401 // If the Isolate is not available for the current thread we cannot retrieve
402 // memory information from the Isolate. Write easy-to-recognize values on
403 // the stack.
404 memset(last_few_messages, 0x0BADC0DE, Heap::kTraceRingBufferSize + 1);
405 memset(js_stacktrace, 0x0BADC0DE, Heap::kStacktraceBufferSize + 1);
406 memset(&heap_stats, 0xBADC0DE, sizeof(heap_stats));
407 // Note that the embedder's oom handler is also not available and therefore
408 // won't be called in this case. We just crash.
409 FATAL("Fatal process out of memory: %s", location);
410 UNREACHABLE();
411 }
412
413 memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
414 memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
415
416 intptr_t start_marker;
417 heap_stats.start_marker = &start_marker;
418 size_t ro_space_size;
419 heap_stats.ro_space_size = &ro_space_size;
420 size_t ro_space_capacity;
421 heap_stats.ro_space_capacity = &ro_space_capacity;
422 size_t new_space_size;
423 heap_stats.new_space_size = &new_space_size;
424 size_t new_space_capacity;
425 heap_stats.new_space_capacity = &new_space_capacity;
426 size_t old_space_size;
427 heap_stats.old_space_size = &old_space_size;
428 size_t old_space_capacity;
429 heap_stats.old_space_capacity = &old_space_capacity;
430 size_t code_space_size;
431 heap_stats.code_space_size = &code_space_size;
432 size_t code_space_capacity;
433 heap_stats.code_space_capacity = &code_space_capacity;
434 size_t map_space_size;
435 heap_stats.map_space_size = &map_space_size;
436 size_t map_space_capacity;
437 heap_stats.map_space_capacity = &map_space_capacity;
438 size_t lo_space_size;
439 heap_stats.lo_space_size = &lo_space_size;
440 size_t code_lo_space_size;
441 heap_stats.code_lo_space_size = &code_lo_space_size;
442 size_t global_handle_count;
443 heap_stats.global_handle_count = &global_handle_count;
444 size_t weak_global_handle_count;
445 heap_stats.weak_global_handle_count = &weak_global_handle_count;
446 size_t pending_global_handle_count;
447 heap_stats.pending_global_handle_count = &pending_global_handle_count;
448 size_t near_death_global_handle_count;
449 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
450 size_t free_global_handle_count;
451 heap_stats.free_global_handle_count = &free_global_handle_count;
452 size_t memory_allocator_size;
453 heap_stats.memory_allocator_size = &memory_allocator_size;
454 size_t memory_allocator_capacity;
455 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
456 size_t malloced_memory;
457 heap_stats.malloced_memory = &malloced_memory;
458 size_t malloced_peak_memory;
459 heap_stats.malloced_peak_memory = &malloced_peak_memory;
460 size_t objects_per_type[LAST_TYPE + 1] = {0};
461 heap_stats.objects_per_type = objects_per_type;
462 size_t size_per_type[LAST_TYPE + 1] = {0};
463 heap_stats.size_per_type = size_per_type;
464 int os_error;
465 heap_stats.os_error = &os_error;
466 heap_stats.last_few_messages = last_few_messages;
467 heap_stats.js_stacktrace = js_stacktrace;
468 intptr_t end_marker;
469 heap_stats.end_marker = &end_marker;
470 if (isolate->heap()->HasBeenSetUp()) {
471 // BUG(1718): Don't use the take_snapshot since we don't support
472 // HeapObjectIterator here without doing a special GC.
473 isolate->heap()->RecordStats(&heap_stats, false);
474 if (!FLAG_correctness_fuzzer_suppressions) {
475 char* first_newline = strchr(last_few_messages, '\n');
476 if (first_newline == nullptr || first_newline[1] == '\0')
477 first_newline = last_few_messages;
478 base::OS::PrintError("\n<--- Last few GCs --->\n%s\n", first_newline);
479 base::OS::PrintError("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
480 }
481 }
482 Utils::ReportOOMFailure(isolate, location, is_heap_oom);
483 // If the fatal error handler returns, we stop execution.
484 FATAL("API fatal error handler returned after process out of memory");
485 }
486
ReportApiFailure(const char * location,const char * message)487 void Utils::ReportApiFailure(const char* location, const char* message) {
488 i::Isolate* isolate = i::Isolate::TryGetCurrent();
489 FatalErrorCallback callback = nullptr;
490 if (isolate != nullptr) {
491 callback = isolate->exception_behavior();
492 }
493 if (callback == nullptr) {
494 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
495 message);
496 base::OS::Abort();
497 } else {
498 callback(location, message);
499 }
500 isolate->SignalFatalError();
501 }
502
ReportOOMFailure(i::Isolate * isolate,const char * location,bool is_heap_oom)503 void Utils::ReportOOMFailure(i::Isolate* isolate, const char* location,
504 bool is_heap_oom) {
505 OOMErrorCallback oom_callback = isolate->oom_behavior();
506 if (oom_callback == nullptr) {
507 // TODO(wfh): Remove this fallback once Blink is setting OOM handler. See
508 // crbug.com/614440.
509 FatalErrorCallback fatal_callback = isolate->exception_behavior();
510 if (fatal_callback == nullptr) {
511 base::OS::PrintError("\n#\n# Fatal %s OOM in %s\n#\n\n",
512 is_heap_oom ? "javascript" : "process", location);
513 #ifdef V8_FUZZILLI
514 exit(0);
515 #else
516 base::OS::Abort();
517 #endif // V8_FUZZILLI
518 } else {
519 fatal_callback(location,
520 is_heap_oom
521 ? "Allocation failed - JavaScript heap out of memory"
522 : "Allocation failed - process out of memory");
523 }
524 } else {
525 oom_callback(location, is_heap_oom);
526 }
527 isolate->SignalFatalError();
528 }
529
IsExecutionTerminatingCheck(i::Isolate * isolate)530 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
531 if (isolate->has_scheduled_exception()) {
532 return isolate->scheduled_exception() ==
533 i::ReadOnlyRoots(isolate).termination_exception();
534 }
535 return false;
536 }
537
SetSnapshotDataBlob(StartupData * snapshot_blob)538 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
539 i::V8::SetSnapshotBlob(snapshot_blob);
540 }
541
542 namespace {
543
544 class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
545 public:
Allocate(size_t length)546 void* Allocate(size_t length) override {
547 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
548 // Work around for GCC bug on AIX
549 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
550 void* data = __linux_calloc(length, 1);
551 #else
552 void* data = calloc(length, 1);
553 #endif
554 return data;
555 }
556
AllocateUninitialized(size_t length)557 void* AllocateUninitialized(size_t length) override {
558 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
559 // Work around for GCC bug on AIX
560 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
561 void* data = __linux_malloc(length);
562 #else
563 void* data = malloc(length);
564 #endif
565 return data;
566 }
567
Free(void * data,size_t)568 void Free(void* data, size_t) override { free(data); }
569
Reallocate(void * data,size_t old_length,size_t new_length)570 void* Reallocate(void* data, size_t old_length, size_t new_length) override {
571 #if V8_OS_AIX && _LINUX_SOURCE_COMPAT
572 // Work around for GCC bug on AIX
573 // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79839
574 void* new_data = __linux_realloc(data, new_length);
575 #else
576 void* new_data = realloc(data, new_length);
577 #endif
578 if (new_length > old_length) {
579 memset(reinterpret_cast<uint8_t*>(new_data) + old_length, 0,
580 new_length - old_length);
581 }
582 return new_data;
583 }
584 };
585
586 struct SnapshotCreatorData {
SnapshotCreatorDatav8::__anona26d73470211::SnapshotCreatorData587 explicit SnapshotCreatorData(Isolate* isolate)
588 : isolate_(isolate),
589 default_context_(),
590 contexts_(isolate),
591 created_(false) {}
592
castv8::__anona26d73470211::SnapshotCreatorData593 static SnapshotCreatorData* cast(void* data) {
594 return reinterpret_cast<SnapshotCreatorData*>(data);
595 }
596
597 ArrayBufferAllocator allocator_;
598 Isolate* isolate_;
599 Persistent<Context> default_context_;
600 SerializeInternalFieldsCallback default_embedder_fields_serializer_;
601 PersistentValueVector<Context> contexts_;
602 std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers_;
603 bool created_;
604 };
605
606 } // namespace
607
SnapshotCreator(Isolate * isolate,const intptr_t * external_references,StartupData * existing_snapshot)608 SnapshotCreator::SnapshotCreator(Isolate* isolate,
609 const intptr_t* external_references,
610 StartupData* existing_snapshot) {
611 SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
612 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
613 internal_isolate->set_array_buffer_allocator(&data->allocator_);
614 internal_isolate->set_api_external_references(external_references);
615 internal_isolate->enable_serializer();
616 isolate->Enter();
617 const StartupData* blob = existing_snapshot
618 ? existing_snapshot
619 : i::Snapshot::DefaultSnapshotBlob();
620 if (blob && blob->raw_size > 0) {
621 internal_isolate->set_snapshot_blob(blob);
622 i::Snapshot::Initialize(internal_isolate);
623 } else {
624 internal_isolate->InitWithoutSnapshot();
625 }
626 data_ = data;
627 }
628
SnapshotCreator(const intptr_t * external_references,StartupData * existing_snapshot)629 SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
630 StartupData* existing_snapshot)
631 : SnapshotCreator(Isolate::Allocate(), external_references,
632 existing_snapshot) {}
633
~SnapshotCreator()634 SnapshotCreator::~SnapshotCreator() {
635 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
636 DCHECK(data->created_);
637 Isolate* isolate = data->isolate_;
638 isolate->Exit();
639 isolate->Dispose();
640 delete data;
641 }
642
GetIsolate()643 Isolate* SnapshotCreator::GetIsolate() {
644 return SnapshotCreatorData::cast(data_)->isolate_;
645 }
646
SetDefaultContext(Local<Context> context,SerializeInternalFieldsCallback callback)647 void SnapshotCreator::SetDefaultContext(
648 Local<Context> context, SerializeInternalFieldsCallback callback) {
649 DCHECK(!context.IsEmpty());
650 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
651 DCHECK(!data->created_);
652 DCHECK(data->default_context_.IsEmpty());
653 Isolate* isolate = data->isolate_;
654 CHECK_EQ(isolate, context->GetIsolate());
655 data->default_context_.Reset(isolate, context);
656 data->default_embedder_fields_serializer_ = callback;
657 }
658
AddContext(Local<Context> context,SerializeInternalFieldsCallback callback)659 size_t SnapshotCreator::AddContext(Local<Context> context,
660 SerializeInternalFieldsCallback callback) {
661 DCHECK(!context.IsEmpty());
662 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
663 DCHECK(!data->created_);
664 Isolate* isolate = data->isolate_;
665 CHECK_EQ(isolate, context->GetIsolate());
666 size_t index = data->contexts_.Size();
667 data->contexts_.Append(context);
668 data->embedder_fields_serializers_.push_back(callback);
669 return index;
670 }
671
AddData(i::Address object)672 size_t SnapshotCreator::AddData(i::Address object) {
673 DCHECK_NE(object, i::kNullAddress);
674 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
675 DCHECK(!data->created_);
676 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
677 i::HandleScope scope(isolate);
678 i::Handle<i::Object> obj(i::Object(object), isolate);
679 i::Handle<i::ArrayList> list;
680 if (!isolate->heap()->serialized_objects().IsArrayList()) {
681 list = i::ArrayList::New(isolate, 1);
682 } else {
683 list = i::Handle<i::ArrayList>(
684 i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
685 }
686 size_t index = static_cast<size_t>(list->Length());
687 list = i::ArrayList::Add(isolate, list, obj);
688 isolate->heap()->SetSerializedObjects(*list);
689 return index;
690 }
691
AddData(Local<Context> context,i::Address object)692 size_t SnapshotCreator::AddData(Local<Context> context, i::Address object) {
693 DCHECK_NE(object, i::kNullAddress);
694 DCHECK(!SnapshotCreatorData::cast(data_)->created_);
695 i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
696 i::Isolate* isolate = ctx->GetIsolate();
697 i::HandleScope scope(isolate);
698 i::Handle<i::Object> obj(i::Object(object), isolate);
699 i::Handle<i::ArrayList> list;
700 if (!ctx->serialized_objects().IsArrayList()) {
701 list = i::ArrayList::New(isolate, 1);
702 } else {
703 list = i::Handle<i::ArrayList>(
704 i::ArrayList::cast(ctx->serialized_objects()), isolate);
705 }
706 size_t index = static_cast<size_t>(list->Length());
707 list = i::ArrayList::Add(isolate, list, obj);
708 ctx->set_serialized_objects(*list);
709 return index;
710 }
711
712 namespace {
ConvertSerializedObjectsToFixedArray(Local<Context> context)713 void ConvertSerializedObjectsToFixedArray(Local<Context> context) {
714 i::Handle<i::Context> ctx = Utils::OpenHandle(*context);
715 i::Isolate* isolate = ctx->GetIsolate();
716 if (!ctx->serialized_objects().IsArrayList()) {
717 ctx->set_serialized_objects(i::ReadOnlyRoots(isolate).empty_fixed_array());
718 } else {
719 i::Handle<i::ArrayList> list(i::ArrayList::cast(ctx->serialized_objects()),
720 isolate);
721 i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
722 ctx->set_serialized_objects(*elements);
723 }
724 }
725
ConvertSerializedObjectsToFixedArray(i::Isolate * isolate)726 void ConvertSerializedObjectsToFixedArray(i::Isolate* isolate) {
727 if (!isolate->heap()->serialized_objects().IsArrayList()) {
728 isolate->heap()->SetSerializedObjects(
729 i::ReadOnlyRoots(isolate).empty_fixed_array());
730 } else {
731 i::Handle<i::ArrayList> list(
732 i::ArrayList::cast(isolate->heap()->serialized_objects()), isolate);
733 i::Handle<i::FixedArray> elements = i::ArrayList::Elements(isolate, list);
734 isolate->heap()->SetSerializedObjects(*elements);
735 }
736 }
737 } // anonymous namespace
738
CreateBlob(SnapshotCreator::FunctionCodeHandling function_code_handling)739 StartupData SnapshotCreator::CreateBlob(
740 SnapshotCreator::FunctionCodeHandling function_code_handling) {
741 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
742 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
743 DCHECK(!data->created_);
744 DCHECK(!data->default_context_.IsEmpty());
745
746 const int num_additional_contexts = static_cast<int>(data->contexts_.Size());
747 const int num_contexts = num_additional_contexts + 1; // The default context.
748
749 // Create and store lists of embedder-provided data needed during
750 // serialization.
751 {
752 i::HandleScope scope(isolate);
753 // Convert list of context-independent data to FixedArray.
754 ConvertSerializedObjectsToFixedArray(isolate);
755
756 // Convert lists of context-dependent data to FixedArray.
757 ConvertSerializedObjectsToFixedArray(
758 data->default_context_.Get(data->isolate_));
759 for (int i = 0; i < num_additional_contexts; i++) {
760 ConvertSerializedObjectsToFixedArray(data->contexts_.Get(i));
761 }
762
763 // We need to store the global proxy size upfront in case we need the
764 // bootstrapper to create a global proxy before we deserialize the context.
765 i::Handle<i::FixedArray> global_proxy_sizes =
766 isolate->factory()->NewFixedArray(num_additional_contexts,
767 i::AllocationType::kOld);
768 for (int i = 0; i < num_additional_contexts; i++) {
769 i::Handle<i::Context> context =
770 v8::Utils::OpenHandle(*data->contexts_.Get(i));
771 global_proxy_sizes->set(i,
772 i::Smi::FromInt(context->global_proxy().Size()));
773 }
774 isolate->heap()->SetSerializedGlobalProxySizes(*global_proxy_sizes);
775 }
776
777 // We might rehash strings and re-sort descriptors. Clear the lookup cache.
778 isolate->descriptor_lookup_cache()->Clear();
779
780 // If we don't do this then we end up with a stray root pointing at the
781 // context even after we have disposed of the context.
782 isolate->heap()->CollectAllAvailableGarbage(
783 i::GarbageCollectionReason::kSnapshotCreator);
784 {
785 i::HandleScope scope(isolate);
786 isolate->heap()->CompactWeakArrayLists(internal::AllocationType::kOld);
787 }
788
789 i::Snapshot::ClearReconstructableDataForSerialization(
790 isolate, function_code_handling == FunctionCodeHandling::kClear);
791
792 i::DisallowGarbageCollection no_gc_from_here_on;
793
794 // Create a vector with all contexts and clear associated Persistent fields.
795 // Note these contexts may be dead after calling Clear(), but will not be
796 // collected until serialization completes and the DisallowHeapAllocation
797 // scope above goes out of scope.
798 std::vector<i::Context> contexts;
799 contexts.reserve(num_contexts);
800 {
801 i::HandleScope scope(isolate);
802 contexts.push_back(
803 *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)));
804 data->default_context_.Reset();
805 for (int i = 0; i < num_additional_contexts; i++) {
806 i::Handle<i::Context> context =
807 v8::Utils::OpenHandle(*data->contexts_.Get(i));
808 contexts.push_back(*context);
809 }
810 data->contexts_.Clear();
811 }
812
813 // Check that values referenced by global/eternal handles are accounted for.
814 i::SerializedHandleChecker handle_checker(isolate, &contexts);
815 CHECK(handle_checker.CheckGlobalAndEternalHandles());
816
817 // Create a vector with all embedder fields serializers.
818 std::vector<SerializeInternalFieldsCallback> embedder_fields_serializers;
819 embedder_fields_serializers.reserve(num_contexts);
820 embedder_fields_serializers.push_back(
821 data->default_embedder_fields_serializer_);
822 for (int i = 0; i < num_additional_contexts; i++) {
823 embedder_fields_serializers.push_back(
824 data->embedder_fields_serializers_[i]);
825 }
826
827 data->created_ = true;
828 return i::Snapshot::Create(isolate, &contexts, embedder_fields_serializers,
829 no_gc_from_here_on);
830 }
831
CanBeRehashed() const832 bool StartupData::CanBeRehashed() const {
833 DCHECK(i::Snapshot::VerifyChecksum(this));
834 return i::Snapshot::ExtractRehashability(this);
835 }
836
IsValid() const837 bool StartupData::IsValid() const { return i::Snapshot::VersionIsValid(this); }
838
SetDcheckErrorHandler(DcheckErrorCallback that)839 void V8::SetDcheckErrorHandler(DcheckErrorCallback that) {
840 v8::base::SetDcheckFunction(that);
841 }
842
SetFlagsFromString(const char * str)843 void V8::SetFlagsFromString(const char* str) {
844 SetFlagsFromString(str, strlen(str));
845 }
846
SetFlagsFromString(const char * str,size_t length)847 void V8::SetFlagsFromString(const char* str, size_t length) {
848 i::FlagList::SetFlagsFromString(str, length);
849 i::FlagList::EnforceFlagImplications();
850 }
851
SetFlagsFromCommandLine(int * argc,char ** argv,bool remove_flags)852 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
853 using HelpOptions = i::FlagList::HelpOptions;
854 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags,
855 HelpOptions(HelpOptions::kDontExit));
856 }
857
858 RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
859
RegisteredExtension(std::unique_ptr<Extension> extension)860 RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
861 : extension_(std::move(extension)) {}
862
863 // static
Register(std::unique_ptr<Extension> extension)864 void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
865 RegisteredExtension* new_extension =
866 new RegisteredExtension(std::move(extension));
867 new_extension->next_ = first_extension_;
868 first_extension_ = new_extension;
869 }
870
871 // static
UnregisterAll()872 void RegisteredExtension::UnregisterAll() {
873 RegisteredExtension* re = first_extension_;
874 while (re != nullptr) {
875 RegisteredExtension* next = re->next();
876 delete re;
877 re = next;
878 }
879 first_extension_ = nullptr;
880 }
881
882 namespace {
883 class ExtensionResource : public String::ExternalOneByteStringResource {
884 public:
ExtensionResource()885 ExtensionResource() : data_(nullptr), length_(0) {}
ExtensionResource(const char * data,size_t length)886 ExtensionResource(const char* data, size_t length)
887 : data_(data), length_(length) {}
data() const888 const char* data() const override { return data_; }
length() const889 size_t length() const override { return length_; }
Dispose()890 void Dispose() override {}
891
892 private:
893 const char* data_;
894 size_t length_;
895 };
896 } // anonymous namespace
897
RegisterExtension(std::unique_ptr<Extension> extension)898 void RegisterExtension(std::unique_ptr<Extension> extension) {
899 RegisteredExtension::Register(std::move(extension));
900 }
901
Extension(const char * name,const char * source,int dep_count,const char ** deps,int source_length)902 Extension::Extension(const char* name, const char* source, int dep_count,
903 const char** deps, int source_length)
904 : name_(name),
905 source_length_(source_length >= 0
906 ? source_length
907 : (source ? static_cast<int>(strlen(source)) : 0)),
908 dep_count_(dep_count),
909 deps_(deps),
910 auto_enable_(false) {
911 source_ = new ExtensionResource(source, source_length_);
912 CHECK(source != nullptr || source_length_ == 0);
913 }
914
ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,size_t maximum_heap_size_in_bytes)915 void ResourceConstraints::ConfigureDefaultsFromHeapSize(
916 size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes) {
917 CHECK_LE(initial_heap_size_in_bytes, maximum_heap_size_in_bytes);
918 if (maximum_heap_size_in_bytes == 0) {
919 return;
920 }
921 size_t young_generation, old_generation;
922 i::Heap::GenerationSizesFromHeapSize(maximum_heap_size_in_bytes,
923 &young_generation, &old_generation);
924 set_max_young_generation_size_in_bytes(
925 std::max(young_generation, i::Heap::MinYoungGenerationSize()));
926 set_max_old_generation_size_in_bytes(
927 std::max(old_generation, i::Heap::MinOldGenerationSize()));
928 if (initial_heap_size_in_bytes > 0) {
929 i::Heap::GenerationSizesFromHeapSize(initial_heap_size_in_bytes,
930 &young_generation, &old_generation);
931 // We do not set lower bounds for the initial sizes.
932 set_initial_young_generation_size_in_bytes(young_generation);
933 set_initial_old_generation_size_in_bytes(old_generation);
934 }
935 if (i::kPlatformRequiresCodeRange) {
936 set_code_range_size_in_bytes(
937 std::min(i::kMaximalCodeRangeSize, maximum_heap_size_in_bytes));
938 }
939 }
940
ConfigureDefaults(uint64_t physical_memory,uint64_t virtual_memory_limit)941 void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
942 uint64_t virtual_memory_limit) {
943 size_t heap_size = i::Heap::HeapSizeFromPhysicalMemory(physical_memory);
944 size_t young_generation, old_generation;
945 i::Heap::GenerationSizesFromHeapSize(heap_size, &young_generation,
946 &old_generation);
947 set_max_young_generation_size_in_bytes(young_generation);
948 set_max_old_generation_size_in_bytes(old_generation);
949
950 if (virtual_memory_limit > 0 && i::kPlatformRequiresCodeRange) {
951 set_code_range_size_in_bytes(
952 std::min(i::kMaximalCodeRangeSize,
953 static_cast<size_t>(virtual_memory_limit / 8)));
954 }
955 }
956
max_semi_space_size_in_kb() const957 size_t ResourceConstraints::max_semi_space_size_in_kb() const {
958 return i::Heap::SemiSpaceSizeFromYoungGenerationSize(
959 max_young_generation_size_) /
960 i::KB;
961 }
962
set_max_semi_space_size_in_kb(size_t limit_in_kb)963 void ResourceConstraints::set_max_semi_space_size_in_kb(size_t limit_in_kb) {
964 set_max_young_generation_size_in_bytes(
965 i::Heap::YoungGenerationSizeFromSemiSpaceSize(limit_in_kb * i::KB));
966 }
967
GlobalizeReference(i::Isolate * isolate,i::Address * obj)968 i::Address* V8::GlobalizeReference(i::Isolate* isolate, i::Address* obj) {
969 LOG_API(isolate, Persistent, New);
970 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
971 #ifdef VERIFY_HEAP
972 if (i::FLAG_verify_heap) {
973 i::Object(*obj).ObjectVerify(isolate);
974 }
975 #endif // VERIFY_HEAP
976 return result.location();
977 }
978
GlobalizeTracedReference(i::Isolate * isolate,i::Address * obj,internal::Address * slot,bool has_destructor)979 i::Address* V8::GlobalizeTracedReference(i::Isolate* isolate, i::Address* obj,
980 internal::Address* slot,
981 bool has_destructor) {
982 LOG_API(isolate, TracedGlobal, New);
983 #ifdef DEBUG
984 Utils::ApiCheck((slot != nullptr), "v8::GlobalizeTracedReference",
985 "the address slot must be not null");
986 #endif
987 i::Handle<i::Object> result =
988 isolate->global_handles()->CreateTraced(*obj, slot, has_destructor);
989 #ifdef VERIFY_HEAP
990 if (i::FLAG_verify_heap) {
991 i::Object(*obj).ObjectVerify(isolate);
992 }
993 #endif // VERIFY_HEAP
994 return result.location();
995 }
996
CopyGlobalReference(i::Address * from)997 i::Address* V8::CopyGlobalReference(i::Address* from) {
998 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(from);
999 return result.location();
1000 }
1001
MoveGlobalReference(internal::Address ** from,internal::Address ** to)1002 void V8::MoveGlobalReference(internal::Address** from, internal::Address** to) {
1003 i::GlobalHandles::MoveGlobal(from, to);
1004 }
1005
MoveTracedGlobalReference(internal::Address ** from,internal::Address ** to)1006 void V8::MoveTracedGlobalReference(internal::Address** from,
1007 internal::Address** to) {
1008 i::GlobalHandles::MoveTracedGlobal(from, to);
1009 }
1010
CopyTracedGlobalReference(const internal::Address * const * from,internal::Address ** to)1011 void V8::CopyTracedGlobalReference(const internal::Address* const* from,
1012 internal::Address** to) {
1013 i::GlobalHandles::CopyTracedGlobal(from, to);
1014 }
1015
MakeWeak(i::Address * location,void * parameter,WeakCallbackInfo<void>::Callback weak_callback,WeakCallbackType type)1016 void V8::MakeWeak(i::Address* location, void* parameter,
1017 WeakCallbackInfo<void>::Callback weak_callback,
1018 WeakCallbackType type) {
1019 i::GlobalHandles::MakeWeak(location, parameter, weak_callback, type);
1020 }
1021
MakeWeak(i::Address ** location_addr)1022 void V8::MakeWeak(i::Address** location_addr) {
1023 i::GlobalHandles::MakeWeak(location_addr);
1024 }
1025
ClearWeak(i::Address * location)1026 void* V8::ClearWeak(i::Address* location) {
1027 return i::GlobalHandles::ClearWeakness(location);
1028 }
1029
AnnotateStrongRetainer(i::Address * location,const char * label)1030 void V8::AnnotateStrongRetainer(i::Address* location, const char* label) {
1031 i::GlobalHandles::AnnotateStrongRetainer(location, label);
1032 }
1033
DisposeGlobal(i::Address * location)1034 void V8::DisposeGlobal(i::Address* location) {
1035 i::GlobalHandles::Destroy(location);
1036 }
1037
DisposeTracedGlobal(internal::Address * location)1038 void V8::DisposeTracedGlobal(internal::Address* location) {
1039 i::GlobalHandles::DestroyTraced(location);
1040 }
1041
SetFinalizationCallbackTraced(internal::Address * location,void * parameter,WeakCallbackInfo<void>::Callback callback)1042 void V8::SetFinalizationCallbackTraced(
1043 internal::Address* location, void* parameter,
1044 WeakCallbackInfo<void>::Callback callback) {
1045 i::GlobalHandles::SetFinalizationCallbackForTraced(location, parameter,
1046 callback);
1047 }
1048
Eternalize(Isolate * v8_isolate,Value * value)1049 Value* V8::Eternalize(Isolate* v8_isolate, Value* value) {
1050 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1051 i::Object object = *Utils::OpenHandle(value);
1052 int index = -1;
1053 isolate->eternal_handles()->Create(isolate, object, &index);
1054 return reinterpret_cast<Value*>(
1055 isolate->eternal_handles()->Get(index).location());
1056 }
1057
FromJustIsNothing()1058 void V8::FromJustIsNothing() {
1059 Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
1060 }
1061
ToLocalEmpty()1062 void V8::ToLocalEmpty() {
1063 Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
1064 }
1065
InternalFieldOutOfBounds(int index)1066 void V8::InternalFieldOutOfBounds(int index) {
1067 Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
1068 "WeakCallbackInfo::GetInternalField",
1069 "Internal field out of bounds.");
1070 }
1071
1072 // --- H a n d l e s ---
1073
HandleScope(Isolate * isolate)1074 HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); }
1075
Initialize(Isolate * isolate)1076 void HandleScope::Initialize(Isolate* isolate) {
1077 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
1078 // We do not want to check the correct usage of the Locker class all over the
1079 // place, so we do it only here: Without a HandleScope, an embedder can do
1080 // almost nothing, so it is enough to check in this central place.
1081 // We make an exception if the serializer is enabled, which means that the
1082 // Isolate is exclusively used to create a snapshot.
1083 Utils::ApiCheck(
1084 !v8::Locker::IsActive() ||
1085 internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
1086 internal_isolate->serializer_enabled(),
1087 "HandleScope::HandleScope",
1088 "Entering the V8 API without proper locking in place");
1089 i::HandleScopeData* current = internal_isolate->handle_scope_data();
1090 isolate_ = internal_isolate;
1091 prev_next_ = current->next;
1092 prev_limit_ = current->limit;
1093 current->level++;
1094 }
1095
~HandleScope()1096 HandleScope::~HandleScope() {
1097 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
1098 }
1099
operator new(size_t)1100 void* HandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1101 void* HandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1102 void HandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1103 void HandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1104
NumberOfHandles(Isolate * isolate)1105 int HandleScope::NumberOfHandles(Isolate* isolate) {
1106 return i::HandleScope::NumberOfHandles(
1107 reinterpret_cast<i::Isolate*>(isolate));
1108 }
1109
CreateHandle(i::Isolate * isolate,i::Address value)1110 i::Address* HandleScope::CreateHandle(i::Isolate* isolate, i::Address value) {
1111 return i::HandleScope::CreateHandle(isolate, value);
1112 }
1113
EscapableHandleScope(Isolate * v8_isolate)1114 EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
1115 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1116 escape_slot_ =
1117 CreateHandle(isolate, i::ReadOnlyRoots(isolate).the_hole_value().ptr());
1118 Initialize(v8_isolate);
1119 }
1120
Escape(i::Address * escape_value)1121 i::Address* EscapableHandleScope::Escape(i::Address* escape_value) {
1122 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
1123 Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()),
1124 "EscapableHandleScope::Escape", "Escape value set twice");
1125 if (escape_value == nullptr) {
1126 *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr();
1127 return nullptr;
1128 }
1129 *escape_slot_ = *escape_value;
1130 return escape_slot_;
1131 }
1132
operator new(size_t)1133 void* EscapableHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1134 void* EscapableHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1135 void EscapableHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1136 void EscapableHandleScope::operator delete[](void*, size_t) {
1137 base::OS::Abort();
1138 }
1139
SealHandleScope(Isolate * isolate)1140 SealHandleScope::SealHandleScope(Isolate* isolate)
1141 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
1142 i::HandleScopeData* current = isolate_->handle_scope_data();
1143 prev_limit_ = current->limit;
1144 current->limit = current->next;
1145 prev_sealed_level_ = current->sealed_level;
1146 current->sealed_level = current->level;
1147 }
1148
~SealHandleScope()1149 SealHandleScope::~SealHandleScope() {
1150 i::HandleScopeData* current = isolate_->handle_scope_data();
1151 DCHECK_EQ(current->next, current->limit);
1152 current->limit = prev_limit_;
1153 DCHECK_EQ(current->level, current->sealed_level);
1154 current->sealed_level = prev_sealed_level_;
1155 }
1156
operator new(size_t)1157 void* SealHandleScope::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)1158 void* SealHandleScope::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)1159 void SealHandleScope::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)1160 void SealHandleScope::operator delete[](void*, size_t) { base::OS::Abort(); }
1161
IsModule() const1162 bool Data::IsModule() const { return Utils::OpenHandle(this)->IsModule(); }
1163
IsValue() const1164 bool Data::IsValue() const {
1165 i::DisallowHeapAllocation no_gc;
1166 i::Handle<i::Object> self = Utils::OpenHandle(this);
1167 if (self->IsSmi()) {
1168 return true;
1169 }
1170 i::HeapObject heap_object = i::HeapObject::cast(*self);
1171 DCHECK(!heap_object.IsTheHole());
1172 if (heap_object.IsSymbol()) {
1173 return !i::Symbol::cast(heap_object).is_private();
1174 }
1175 return heap_object.IsPrimitiveHeapObject() || heap_object.IsJSReceiver();
1176 }
1177
IsPrivate() const1178 bool Data::IsPrivate() const {
1179 return Utils::OpenHandle(this)->IsPrivateSymbol();
1180 }
1181
IsObjectTemplate() const1182 bool Data::IsObjectTemplate() const {
1183 return Utils::OpenHandle(this)->IsObjectTemplateInfo();
1184 }
1185
IsFunctionTemplate() const1186 bool Data::IsFunctionTemplate() const {
1187 return Utils::OpenHandle(this)->IsFunctionTemplateInfo();
1188 }
1189
Enter()1190 void Context::Enter() {
1191 i::Handle<i::Context> env = Utils::OpenHandle(this);
1192 i::Isolate* isolate = env->GetIsolate();
1193 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1194 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1195 impl->EnterContext(*env);
1196 impl->SaveContext(isolate->context());
1197 isolate->set_context(*env);
1198 }
1199
Exit()1200 void Context::Exit() {
1201 i::Handle<i::Context> env = Utils::OpenHandle(this);
1202 i::Isolate* isolate = env->GetIsolate();
1203 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1204 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
1205 if (!Utils::ApiCheck(impl->LastEnteredContextWas(*env), "v8::Context::Exit()",
1206 "Cannot exit non-entered context")) {
1207 return;
1208 }
1209 impl->LeaveContext();
1210 isolate->set_context(impl->RestoreContext());
1211 }
1212
BackupIncumbentScope(Local<Context> backup_incumbent_context)1213 Context::BackupIncumbentScope::BackupIncumbentScope(
1214 Local<Context> backup_incumbent_context)
1215 : backup_incumbent_context_(backup_incumbent_context) {
1216 DCHECK(!backup_incumbent_context_.IsEmpty());
1217
1218 i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1219 i::Isolate* isolate = env->GetIsolate();
1220
1221 js_stack_comparable_address_ =
1222 i::SimulatorStack::RegisterJSStackComparableAddress(isolate);
1223
1224 prev_ = isolate->top_backup_incumbent_scope();
1225 isolate->set_top_backup_incumbent_scope(this);
1226 }
1227
~BackupIncumbentScope()1228 Context::BackupIncumbentScope::~BackupIncumbentScope() {
1229 i::Handle<i::Context> env = Utils::OpenHandle(*backup_incumbent_context_);
1230 i::Isolate* isolate = env->GetIsolate();
1231
1232 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate);
1233
1234 isolate->set_top_backup_incumbent_scope(prev_);
1235 }
1236
1237 STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
1238
EmbedderDataFor(Context * context,int index,bool can_grow,const char * location)1239 static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
1240 int index, bool can_grow,
1241 const char* location) {
1242 i::Handle<i::Context> env = Utils::OpenHandle(context);
1243 i::Isolate* isolate = env->GetIsolate();
1244 bool ok = Utils::ApiCheck(env->IsNativeContext(), location,
1245 "Not a native context") &&
1246 Utils::ApiCheck(index >= 0, location, "Negative index");
1247 if (!ok) return i::Handle<i::EmbedderDataArray>();
1248 // TODO(ishell): remove cast once embedder_data slot has a proper type.
1249 i::Handle<i::EmbedderDataArray> data(
1250 i::EmbedderDataArray::cast(env->embedder_data()), isolate);
1251 if (index < data->length()) return data;
1252 if (!Utils::ApiCheck(can_grow && index < i::EmbedderDataArray::kMaxLength,
1253 location, "Index too large")) {
1254 return i::Handle<i::EmbedderDataArray>();
1255 }
1256 data = i::EmbedderDataArray::EnsureCapacity(isolate, data, index);
1257 env->set_embedder_data(*data);
1258 return data;
1259 }
1260
GetNumberOfEmbedderDataFields()1261 uint32_t Context::GetNumberOfEmbedderDataFields() {
1262 i::Handle<i::Context> context = Utils::OpenHandle(this);
1263 CHECK(context->IsNativeContext());
1264 // TODO(ishell): remove cast once embedder_data slot has a proper type.
1265 return static_cast<uint32_t>(
1266 i::EmbedderDataArray::cast(context->embedder_data()).length());
1267 }
1268
SlowGetEmbedderData(int index)1269 v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
1270 const char* location = "v8::Context::GetEmbedderData()";
1271 i::Handle<i::EmbedderDataArray> data =
1272 EmbedderDataFor(this, index, false, location);
1273 if (data.is_null()) return Local<Value>();
1274 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1275 i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
1276 isolate);
1277 return Utils::ToLocal(result);
1278 }
1279
SetEmbedderData(int index,v8::Local<Value> value)1280 void Context::SetEmbedderData(int index, v8::Local<Value> value) {
1281 const char* location = "v8::Context::SetEmbedderData()";
1282 i::Handle<i::EmbedderDataArray> data =
1283 EmbedderDataFor(this, index, true, location);
1284 if (data.is_null()) return;
1285 i::Handle<i::Object> val = Utils::OpenHandle(*value);
1286 i::EmbedderDataSlot::store_tagged(*data, index, *val);
1287 DCHECK_EQ(*Utils::OpenHandle(*value),
1288 *Utils::OpenHandle(*GetEmbedderData(index)));
1289 }
1290
SlowGetAlignedPointerFromEmbedderData(int index)1291 void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
1292 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
1293 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1294 i::HandleScope handle_scope(isolate);
1295 i::Handle<i::EmbedderDataArray> data =
1296 EmbedderDataFor(this, index, false, location);
1297 if (data.is_null()) return nullptr;
1298 void* result;
1299 Utils::ApiCheck(
1300 i::EmbedderDataSlot(*data, index).ToAlignedPointer(isolate, &result),
1301 location, "Pointer is not aligned");
1302 return result;
1303 }
1304
SetAlignedPointerInEmbedderData(int index,void * value)1305 void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
1306 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
1307 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1308 i::Handle<i::EmbedderDataArray> data =
1309 EmbedderDataFor(this, index, true, location);
1310 bool ok =
1311 i::EmbedderDataSlot(*data, index).store_aligned_pointer(isolate, value);
1312 Utils::ApiCheck(ok, location, "Pointer is not aligned");
1313 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
1314 }
1315
1316 // --- T e m p l a t e ---
1317
InitializeTemplate(i::Handle<i::TemplateInfo> that,int type)1318 static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
1319 that->set_number_of_properties(0);
1320 that->set_tag(type);
1321 }
1322
Set(v8::Local<Name> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1323 void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
1324 v8::PropertyAttribute attribute) {
1325 auto templ = Utils::OpenHandle(this);
1326 i::Isolate* isolate = templ->GetIsolate();
1327 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1328 i::HandleScope scope(isolate);
1329 auto value_obj = Utils::OpenHandle(*value);
1330 CHECK(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo());
1331 if (value_obj->IsObjectTemplateInfo()) {
1332 templ->set_serial_number(0);
1333 if (templ->IsFunctionTemplateInfo()) {
1334 i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
1335 }
1336 }
1337 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1338 value_obj,
1339 static_cast<i::PropertyAttributes>(attribute));
1340 }
1341
SetPrivate(v8::Local<Private> name,v8::Local<Data> value,v8::PropertyAttribute attribute)1342 void Template::SetPrivate(v8::Local<Private> name, v8::Local<Data> value,
1343 v8::PropertyAttribute attribute) {
1344 Set(Utils::ToLocal(Utils::OpenHandle(reinterpret_cast<Name*>(*name))), value,
1345 attribute);
1346 }
1347
SetAccessorProperty(v8::Local<v8::Name> name,v8::Local<FunctionTemplate> getter,v8::Local<FunctionTemplate> setter,v8::PropertyAttribute attribute,v8::AccessControl access_control)1348 void Template::SetAccessorProperty(v8::Local<v8::Name> name,
1349 v8::Local<FunctionTemplate> getter,
1350 v8::Local<FunctionTemplate> setter,
1351 v8::PropertyAttribute attribute,
1352 v8::AccessControl access_control) {
1353 // TODO(verwaest): Remove |access_control|.
1354 DCHECK_EQ(v8::DEFAULT, access_control);
1355 auto templ = Utils::OpenHandle(this);
1356 auto isolate = templ->GetIsolate();
1357 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1358 DCHECK(!name.IsEmpty());
1359 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1360 i::HandleScope scope(isolate);
1361 i::ApiNatives::AddAccessorProperty(
1362 isolate, templ, Utils::OpenHandle(*name),
1363 Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1364 static_cast<i::PropertyAttributes>(attribute));
1365 }
1366
1367 // --- F u n c t i o n T e m p l a t e ---
InitializeFunctionTemplate(i::Handle<i::FunctionTemplateInfo> info)1368 static void InitializeFunctionTemplate(
1369 i::Handle<i::FunctionTemplateInfo> info) {
1370 InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
1371 info->set_flag(0);
1372 }
1373
1374 static Local<ObjectTemplate> ObjectTemplateNew(
1375 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1376 bool do_not_cache);
1377
PrototypeTemplate()1378 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
1379 auto self = Utils::OpenHandle(this);
1380 i::Isolate* i_isolate = self->GetIsolate();
1381 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1382 i::Handle<i::HeapObject> result(self->GetPrototypeTemplate(), i_isolate);
1383 if (result->IsUndefined(i_isolate)) {
1384 // Do not cache prototype objects.
1385 result = Utils::OpenHandle(
1386 *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
1387 i::FunctionTemplateInfo::SetPrototypeTemplate(i_isolate, self, result);
1388 }
1389 return ToApiHandle<ObjectTemplate>(result);
1390 }
1391
SetPrototypeProviderTemplate(Local<FunctionTemplate> prototype_provider)1392 void FunctionTemplate::SetPrototypeProviderTemplate(
1393 Local<FunctionTemplate> prototype_provider) {
1394 auto self = Utils::OpenHandle(this);
1395 i::Isolate* i_isolate = self->GetIsolate();
1396 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1397 i::Handle<i::FunctionTemplateInfo> result =
1398 Utils::OpenHandle(*prototype_provider);
1399 CHECK(self->GetPrototypeTemplate().IsUndefined(i_isolate));
1400 CHECK(self->GetParentTemplate().IsUndefined(i_isolate));
1401 i::FunctionTemplateInfo::SetPrototypeProviderTemplate(i_isolate, self,
1402 result);
1403 }
1404
EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,const char * func)1405 static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
1406 const char* func) {
1407 Utils::ApiCheck(!info->instantiated(), func,
1408 "FunctionTemplate already instantiated");
1409 }
1410
Inherit(v8::Local<FunctionTemplate> value)1411 void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1412 auto info = Utils::OpenHandle(this);
1413 EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
1414 i::Isolate* i_isolate = info->GetIsolate();
1415 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1416 CHECK(info->GetPrototypeProviderTemplate().IsUndefined(i_isolate));
1417 i::FunctionTemplateInfo::SetParentTemplate(i_isolate, info,
1418 Utils::OpenHandle(*value));
1419 }
1420
FunctionTemplateNew(i::Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,bool do_not_cache,v8::Local<Private> cached_property_name=v8::Local<Private> (),SideEffectType side_effect_type=SideEffectType::kHasSideEffect,const CFunction * c_function=nullptr)1421 static Local<FunctionTemplate> FunctionTemplateNew(
1422 i::Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1423 v8::Local<Signature> signature, int length, bool do_not_cache,
1424 v8::Local<Private> cached_property_name = v8::Local<Private>(),
1425 SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1426 const CFunction* c_function = nullptr) {
1427 i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1428 i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1429 i::Handle<i::FunctionTemplateInfo> obj =
1430 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1431 {
1432 // Disallow GC until all fields of obj have acceptable types.
1433 i::DisallowHeapAllocation no_gc;
1434 InitializeFunctionTemplate(obj);
1435 obj->set_length(length);
1436 obj->set_do_not_cache(do_not_cache);
1437 int next_serial_number = i::FunctionTemplateInfo::kInvalidSerialNumber;
1438 if (!do_not_cache) {
1439 next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1440 }
1441 obj->set_serial_number(next_serial_number);
1442 }
1443 if (callback != nullptr) {
1444 Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1445 c_function);
1446 }
1447 obj->set_undetectable(false);
1448 obj->set_needs_access_check(false);
1449 obj->set_accept_any_receiver(true);
1450 if (!signature.IsEmpty()) {
1451 obj->set_signature(*Utils::OpenHandle(*signature));
1452 }
1453 obj->set_cached_property_name(
1454 cached_property_name.IsEmpty()
1455 ? i::ReadOnlyRoots(isolate).the_hole_value()
1456 : *Utils::OpenHandle(*cached_property_name));
1457 return Utils::ToLocal(obj);
1458 }
1459
New(Isolate * isolate,FunctionCallback callback,v8::Local<Value> data,v8::Local<Signature> signature,int length,ConstructorBehavior behavior,SideEffectType side_effect_type,const CFunction * c_function)1460 Local<FunctionTemplate> FunctionTemplate::New(
1461 Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1462 v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1463 SideEffectType side_effect_type, const CFunction* c_function) {
1464 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1465 // Changes to the environment cannot be captured in the snapshot. Expect no
1466 // function templates when the isolate is created for serialization.
1467 LOG_API(i_isolate, FunctionTemplate, New);
1468 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1469 auto templ =
1470 FunctionTemplateNew(i_isolate, callback, data, signature, length, false,
1471 Local<Private>(), side_effect_type, c_function);
1472 if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
1473 return templ;
1474 }
1475
NewWithCache(Isolate * isolate,FunctionCallback callback,Local<Private> cache_property,Local<Value> data,Local<Signature> signature,int length,SideEffectType side_effect_type)1476 Local<FunctionTemplate> FunctionTemplate::NewWithCache(
1477 Isolate* isolate, FunctionCallback callback, Local<Private> cache_property,
1478 Local<Value> data, Local<Signature> signature, int length,
1479 SideEffectType side_effect_type) {
1480 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1481 LOG_API(i_isolate, FunctionTemplate, NewWithCache);
1482 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1483 return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1484 false, cache_property, side_effect_type);
1485 }
1486
New(Isolate * isolate,Local<FunctionTemplate> receiver)1487 Local<Signature> Signature::New(Isolate* isolate,
1488 Local<FunctionTemplate> receiver) {
1489 return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
1490 }
1491
New(Isolate * isolate,Local<FunctionTemplate> receiver)1492 Local<AccessorSignature> AccessorSignature::New(
1493 Isolate* isolate, Local<FunctionTemplate> receiver) {
1494 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1495 }
1496
1497 #define SET_FIELD_WRAPPED(isolate, obj, setter, cdata) \
1498 do { \
1499 i::Handle<i::Object> foreign = FromCData(isolate, cdata); \
1500 (obj)->setter(*foreign); \
1501 } while (false)
1502
SetCallHandler(FunctionCallback callback,v8::Local<Value> data,SideEffectType side_effect_type,const CFunction * c_function)1503 void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1504 v8::Local<Value> data,
1505 SideEffectType side_effect_type,
1506 const CFunction* c_function) {
1507 auto info = Utils::OpenHandle(this);
1508 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
1509 i::Isolate* isolate = info->GetIsolate();
1510 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1511 i::HandleScope scope(isolate);
1512 i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo(
1513 side_effect_type == SideEffectType::kHasNoSideEffect);
1514 SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1515 SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1516 if (data.IsEmpty()) {
1517 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1518 }
1519 obj->set_data(*Utils::OpenHandle(*data));
1520 // Blink passes CFunction's constructed with the default constructor
1521 // for non-fast calls, so we should check the address too.
1522 if (c_function != nullptr && c_function->GetAddress()) {
1523 i::FunctionTemplateInfo::SetCFunction(
1524 isolate, info,
1525 i::handle(*FromCData(isolate, c_function->GetAddress()), isolate));
1526 i::FunctionTemplateInfo::SetCSignature(
1527 isolate, info,
1528 i::handle(*FromCData(isolate, c_function->GetTypeInfo()), isolate));
1529 }
1530 info->set_call_code(*obj, kReleaseStore);
1531 }
1532
1533 namespace {
1534
1535 template <typename Getter, typename Setter>
MakeAccessorInfo(i::Isolate * isolate,v8::Local<Name> name,Getter getter,Setter setter,v8::Local<Value> data,v8::AccessControl settings,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access)1536 i::Handle<i::AccessorInfo> MakeAccessorInfo(
1537 i::Isolate* isolate, v8::Local<Name> name, Getter getter, Setter setter,
1538 v8::Local<Value> data, v8::AccessControl settings,
1539 v8::Local<AccessorSignature> signature, bool is_special_data_property,
1540 bool replace_on_access) {
1541 i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
1542 SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1543 DCHECK_IMPLIES(replace_on_access,
1544 is_special_data_property && setter == nullptr);
1545 if (is_special_data_property && setter == nullptr) {
1546 setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1547 }
1548 SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1549 i::Address redirected = obj->redirected_getter();
1550 if (redirected != i::kNullAddress) {
1551 SET_FIELD_WRAPPED(isolate, obj, set_js_getter, redirected);
1552 }
1553 if (data.IsEmpty()) {
1554 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1555 }
1556 obj->set_data(*Utils::OpenHandle(*data));
1557 obj->set_is_special_data_property(is_special_data_property);
1558 obj->set_replace_on_access(replace_on_access);
1559 i::Handle<i::Name> accessor_name = Utils::OpenHandle(*name);
1560 if (!accessor_name->IsUniqueName()) {
1561 accessor_name = isolate->factory()->InternalizeString(
1562 i::Handle<i::String>::cast(accessor_name));
1563 }
1564 obj->set_name(*accessor_name);
1565 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1566 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1567 obj->set_initial_property_attributes(i::NONE);
1568 if (!signature.IsEmpty()) {
1569 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1570 }
1571 return obj;
1572 }
1573
1574 } // namespace
1575
InstanceTemplate()1576 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1577 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1578 if (!Utils::ApiCheck(!handle.is_null(),
1579 "v8::FunctionTemplate::InstanceTemplate()",
1580 "Reading from empty handle")) {
1581 return Local<ObjectTemplate>();
1582 }
1583 i::Isolate* isolate = handle->GetIsolate();
1584 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1585 if (handle->GetInstanceTemplate().IsUndefined(isolate)) {
1586 Local<ObjectTemplate> templ =
1587 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1588 i::FunctionTemplateInfo::SetInstanceTemplate(isolate, handle,
1589 Utils::OpenHandle(*templ));
1590 }
1591 i::Handle<i::ObjectTemplateInfo> result(
1592 i::ObjectTemplateInfo::cast(handle->GetInstanceTemplate()), isolate);
1593 return Utils::ToLocal(result);
1594 }
1595
SetLength(int length)1596 void FunctionTemplate::SetLength(int length) {
1597 auto info = Utils::OpenHandle(this);
1598 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
1599 auto isolate = info->GetIsolate();
1600 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1601 info->set_length(length);
1602 }
1603
SetClassName(Local<String> name)1604 void FunctionTemplate::SetClassName(Local<String> name) {
1605 auto info = Utils::OpenHandle(this);
1606 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
1607 auto isolate = info->GetIsolate();
1608 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1609 info->set_class_name(*Utils::OpenHandle(*name));
1610 }
1611
SetAcceptAnyReceiver(bool value)1612 void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1613 auto info = Utils::OpenHandle(this);
1614 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1615 auto isolate = info->GetIsolate();
1616 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1617 info->set_accept_any_receiver(value);
1618 }
1619
ReadOnlyPrototype()1620 void FunctionTemplate::ReadOnlyPrototype() {
1621 auto info = Utils::OpenHandle(this);
1622 EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1623 auto isolate = info->GetIsolate();
1624 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1625 info->set_read_only_prototype(true);
1626 }
1627
RemovePrototype()1628 void FunctionTemplate::RemovePrototype() {
1629 auto info = Utils::OpenHandle(this);
1630 EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
1631 auto isolate = info->GetIsolate();
1632 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1633 info->set_remove_prototype(true);
1634 }
1635
1636 // --- O b j e c t T e m p l a t e ---
1637
New(Isolate * isolate,v8::Local<FunctionTemplate> constructor)1638 Local<ObjectTemplate> ObjectTemplate::New(
1639 Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1640 return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
1641 }
1642
ObjectTemplateNew(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor,bool do_not_cache)1643 static Local<ObjectTemplate> ObjectTemplateNew(
1644 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1645 bool do_not_cache) {
1646 LOG_API(isolate, ObjectTemplate, New);
1647 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1648 i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
1649 i::OBJECT_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
1650 i::Handle<i::ObjectTemplateInfo> obj =
1651 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1652 {
1653 // Disallow GC until all fields of obj have acceptable types.
1654 i::DisallowHeapAllocation no_gc;
1655 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1656 int next_serial_number = 0;
1657 if (!do_not_cache) {
1658 next_serial_number = isolate->heap()->GetNextTemplateSerialNumber();
1659 }
1660 obj->set_serial_number(next_serial_number);
1661 obj->set_data(0);
1662 }
1663 if (!constructor.IsEmpty())
1664 obj->set_constructor(*Utils::OpenHandle(*constructor));
1665 return Utils::ToLocal(obj);
1666 }
1667
New(i::Isolate * isolate,v8::Local<FunctionTemplate> constructor)1668 Local<ObjectTemplate> ObjectTemplate::New(
1669 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1670 return ObjectTemplateNew(isolate, constructor, false);
1671 }
1672
1673 // Ensure that the object template has a constructor. If no
1674 // constructor is available we create one.
EnsureConstructor(i::Isolate * isolate,ObjectTemplate * object_template)1675 static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1676 i::Isolate* isolate, ObjectTemplate* object_template) {
1677 i::Object obj = Utils::OpenHandle(object_template)->constructor();
1678 if (!obj.IsUndefined(isolate)) {
1679 i::FunctionTemplateInfo info = i::FunctionTemplateInfo::cast(obj);
1680 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1681 }
1682 Local<FunctionTemplate> templ =
1683 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1684 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1685 i::FunctionTemplateInfo::SetInstanceTemplate(
1686 isolate, constructor, Utils::OpenHandle(object_template));
1687 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1688 return constructor;
1689 }
1690
1691 template <typename Getter, typename Setter, typename Data, typename Template>
TemplateSetAccessor(Template * template_obj,v8::Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1692 static void TemplateSetAccessor(
1693 Template* template_obj, v8::Local<Name> name, Getter getter, Setter setter,
1694 Data data, AccessControl settings, PropertyAttribute attribute,
1695 v8::Local<AccessorSignature> signature, bool is_special_data_property,
1696 bool replace_on_access, SideEffectType getter_side_effect_type,
1697 SideEffectType setter_side_effect_type) {
1698 auto info = Utils::OpenHandle(template_obj);
1699 auto isolate = info->GetIsolate();
1700 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1701 i::HandleScope scope(isolate);
1702 i::Handle<i::AccessorInfo> accessor_info =
1703 MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
1704 is_special_data_property, replace_on_access);
1705 accessor_info->set_initial_property_attributes(
1706 static_cast<i::PropertyAttributes>(attribute));
1707 accessor_info->set_getter_side_effect_type(getter_side_effect_type);
1708 accessor_info->set_setter_side_effect_type(setter_side_effect_type);
1709 i::ApiNatives::AddNativeDataProperty(isolate, info, accessor_info);
1710 }
1711
SetNativeDataProperty(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1712 void Template::SetNativeDataProperty(
1713 v8::Local<String> name, AccessorGetterCallback getter,
1714 AccessorSetterCallback setter, v8::Local<Value> data,
1715 PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1716 AccessControl settings, SideEffectType getter_side_effect_type,
1717 SideEffectType setter_side_effect_type) {
1718 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1719 signature, true, false, getter_side_effect_type,
1720 setter_side_effect_type);
1721 }
1722
SetNativeDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,AccessControl settings,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1723 void Template::SetNativeDataProperty(
1724 v8::Local<Name> name, AccessorNameGetterCallback getter,
1725 AccessorNameSetterCallback setter, v8::Local<Value> data,
1726 PropertyAttribute attribute, v8::Local<AccessorSignature> signature,
1727 AccessControl settings, SideEffectType getter_side_effect_type,
1728 SideEffectType setter_side_effect_type) {
1729 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1730 signature, true, false, getter_side_effect_type,
1731 setter_side_effect_type);
1732 }
1733
SetLazyDataProperty(v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1734 void Template::SetLazyDataProperty(v8::Local<Name> name,
1735 AccessorNameGetterCallback getter,
1736 v8::Local<Value> data,
1737 PropertyAttribute attribute,
1738 SideEffectType getter_side_effect_type,
1739 SideEffectType setter_side_effect_type) {
1740 TemplateSetAccessor(this, name, getter,
1741 static_cast<AccessorNameSetterCallback>(nullptr), data,
1742 DEFAULT, attribute, Local<AccessorSignature>(), true,
1743 true, getter_side_effect_type, setter_side_effect_type);
1744 }
1745
SetIntrinsicDataProperty(Local<Name> name,Intrinsic intrinsic,PropertyAttribute attribute)1746 void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1747 PropertyAttribute attribute) {
1748 auto templ = Utils::OpenHandle(this);
1749 i::Isolate* isolate = templ->GetIsolate();
1750 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1751 i::HandleScope scope(isolate);
1752 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1753 intrinsic,
1754 static_cast<i::PropertyAttributes>(attribute));
1755 }
1756
SetAccessor(v8::Local<String> name,AccessorGetterCallback getter,AccessorSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1757 void ObjectTemplate::SetAccessor(v8::Local<String> name,
1758 AccessorGetterCallback getter,
1759 AccessorSetterCallback setter,
1760 v8::Local<Value> data, AccessControl settings,
1761 PropertyAttribute attribute,
1762 v8::Local<AccessorSignature> signature,
1763 SideEffectType getter_side_effect_type,
1764 SideEffectType setter_side_effect_type) {
1765 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1766 signature, i::FLAG_disable_old_api_accessors, false,
1767 getter_side_effect_type, setter_side_effect_type);
1768 }
1769
SetAccessor(v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,AccessControl settings,PropertyAttribute attribute,v8::Local<AccessorSignature> signature,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)1770 void ObjectTemplate::SetAccessor(v8::Local<Name> name,
1771 AccessorNameGetterCallback getter,
1772 AccessorNameSetterCallback setter,
1773 v8::Local<Value> data, AccessControl settings,
1774 PropertyAttribute attribute,
1775 v8::Local<AccessorSignature> signature,
1776 SideEffectType getter_side_effect_type,
1777 SideEffectType setter_side_effect_type) {
1778 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1779 signature, i::FLAG_disable_old_api_accessors, false,
1780 getter_side_effect_type, setter_side_effect_type);
1781 }
1782
1783 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1784 typename Deleter, typename Enumerator, typename Definer>
CreateInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1785 static i::Handle<i::InterceptorInfo> CreateInterceptorInfo(
1786 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1787 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1788 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1789 auto obj = i::Handle<i::InterceptorInfo>::cast(isolate->factory()->NewStruct(
1790 i::INTERCEPTOR_INFO_TYPE, i::AllocationType::kOld));
1791 obj->set_flags(0);
1792
1793 if (getter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_getter, getter);
1794 if (setter != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_setter, setter);
1795 if (query != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_query, query);
1796 if (descriptor != nullptr)
1797 SET_FIELD_WRAPPED(isolate, obj, set_descriptor, descriptor);
1798 if (remover != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_deleter, remover);
1799 if (enumerator != nullptr)
1800 SET_FIELD_WRAPPED(isolate, obj, set_enumerator, enumerator);
1801 if (definer != nullptr) SET_FIELD_WRAPPED(isolate, obj, set_definer, definer);
1802 obj->set_can_intercept_symbols(
1803 !(static_cast<int>(flags) &
1804 static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
1805 obj->set_all_can_read(static_cast<int>(flags) &
1806 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
1807 obj->set_non_masking(static_cast<int>(flags) &
1808 static_cast<int>(PropertyHandlerFlags::kNonMasking));
1809 obj->set_has_no_side_effect(
1810 static_cast<int>(flags) &
1811 static_cast<int>(PropertyHandlerFlags::kHasNoSideEffect));
1812
1813 if (data.IsEmpty()) {
1814 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1815 }
1816 obj->set_data(*Utils::OpenHandle(*data));
1817 return obj;
1818 }
1819
1820 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1821 typename Deleter, typename Enumerator, typename Definer>
CreateNamedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1822 static i::Handle<i::InterceptorInfo> CreateNamedInterceptorInfo(
1823 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1824 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1825 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1826 auto interceptor =
1827 CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1828 enumerator, definer, data, flags);
1829 interceptor->set_is_named(true);
1830 return interceptor;
1831 }
1832
1833 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1834 typename Deleter, typename Enumerator, typename Definer>
CreateIndexedInterceptorInfo(i::Isolate * isolate,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1835 static i::Handle<i::InterceptorInfo> CreateIndexedInterceptorInfo(
1836 i::Isolate* isolate, Getter getter, Setter setter, Query query,
1837 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1838 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1839 auto interceptor =
1840 CreateInterceptorInfo(isolate, getter, setter, query, descriptor, remover,
1841 enumerator, definer, data, flags);
1842 interceptor->set_is_named(false);
1843 return interceptor;
1844 }
1845
1846 template <typename Getter, typename Setter, typename Query, typename Descriptor,
1847 typename Deleter, typename Enumerator, typename Definer>
ObjectTemplateSetNamedPropertyHandler(ObjectTemplate * templ,Getter getter,Setter setter,Query query,Descriptor descriptor,Deleter remover,Enumerator enumerator,Definer definer,Local<Value> data,PropertyHandlerFlags flags)1848 static void ObjectTemplateSetNamedPropertyHandler(
1849 ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1850 Descriptor descriptor, Deleter remover, Enumerator enumerator,
1851 Definer definer, Local<Value> data, PropertyHandlerFlags flags) {
1852 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
1853 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1854 i::HandleScope scope(isolate);
1855 auto cons = EnsureConstructor(isolate, templ);
1856 EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
1857 auto obj =
1858 CreateNamedInterceptorInfo(isolate, getter, setter, query, descriptor,
1859 remover, enumerator, definer, data, flags);
1860 i::FunctionTemplateInfo::SetNamedPropertyHandler(isolate, cons, obj);
1861 }
1862
SetHandler(const NamedPropertyHandlerConfiguration & config)1863 void ObjectTemplate::SetHandler(
1864 const NamedPropertyHandlerConfiguration& config) {
1865 ObjectTemplateSetNamedPropertyHandler(
1866 this, config.getter, config.setter, config.query, config.descriptor,
1867 config.deleter, config.enumerator, config.definer, config.data,
1868 config.flags);
1869 }
1870
MarkAsUndetectable()1871 void ObjectTemplate::MarkAsUndetectable() {
1872 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1873 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1874 i::HandleScope scope(isolate);
1875 auto cons = EnsureConstructor(isolate, this);
1876 EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
1877 cons->set_undetectable(true);
1878 }
1879
SetAccessCheckCallback(AccessCheckCallback callback,Local<Value> data)1880 void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1881 Local<Value> data) {
1882 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1883 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1884 i::HandleScope scope(isolate);
1885 auto cons = EnsureConstructor(isolate, this);
1886 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
1887
1888 i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1889 i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1890 i::Handle<i::AccessCheckInfo> info =
1891 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1892
1893 SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1894 info->set_named_interceptor(i::Object());
1895 info->set_indexed_interceptor(i::Object());
1896
1897 if (data.IsEmpty()) {
1898 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1899 }
1900 info->set_data(*Utils::OpenHandle(*data));
1901
1902 i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1903 cons->set_needs_access_check(true);
1904 }
1905
SetAccessCheckCallbackAndHandler(AccessCheckCallback callback,const NamedPropertyHandlerConfiguration & named_handler,const IndexedPropertyHandlerConfiguration & indexed_handler,Local<Value> data)1906 void ObjectTemplate::SetAccessCheckCallbackAndHandler(
1907 AccessCheckCallback callback,
1908 const NamedPropertyHandlerConfiguration& named_handler,
1909 const IndexedPropertyHandlerConfiguration& indexed_handler,
1910 Local<Value> data) {
1911 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1912 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1913 i::HandleScope scope(isolate);
1914 auto cons = EnsureConstructor(isolate, this);
1915 EnsureNotInstantiated(
1916 cons, "v8::ObjectTemplate::SetAccessCheckCallbackWithHandler");
1917
1918 i::Handle<i::Struct> struct_info = isolate->factory()->NewStruct(
1919 i::ACCESS_CHECK_INFO_TYPE, i::AllocationType::kOld);
1920 i::Handle<i::AccessCheckInfo> info =
1921 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1922
1923 SET_FIELD_WRAPPED(isolate, info, set_callback, callback);
1924 auto named_interceptor = CreateNamedInterceptorInfo(
1925 isolate, named_handler.getter, named_handler.setter, named_handler.query,
1926 named_handler.descriptor, named_handler.deleter, named_handler.enumerator,
1927 named_handler.definer, named_handler.data, named_handler.flags);
1928 info->set_named_interceptor(*named_interceptor);
1929 auto indexed_interceptor = CreateIndexedInterceptorInfo(
1930 isolate, indexed_handler.getter, indexed_handler.setter,
1931 indexed_handler.query, indexed_handler.descriptor,
1932 indexed_handler.deleter, indexed_handler.enumerator,
1933 indexed_handler.definer, indexed_handler.data, indexed_handler.flags);
1934 info->set_indexed_interceptor(*indexed_interceptor);
1935
1936 if (data.IsEmpty()) {
1937 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1938 }
1939 info->set_data(*Utils::OpenHandle(*data));
1940
1941 i::FunctionTemplateInfo::SetAccessCheckInfo(isolate, cons, info);
1942 cons->set_needs_access_check(true);
1943 }
1944
SetHandler(const IndexedPropertyHandlerConfiguration & config)1945 void ObjectTemplate::SetHandler(
1946 const IndexedPropertyHandlerConfiguration& config) {
1947 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1948 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1949 i::HandleScope scope(isolate);
1950 auto cons = EnsureConstructor(isolate, this);
1951 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
1952 auto obj = CreateIndexedInterceptorInfo(
1953 isolate, config.getter, config.setter, config.query, config.descriptor,
1954 config.deleter, config.enumerator, config.definer, config.data,
1955 config.flags);
1956 i::FunctionTemplateInfo::SetIndexedPropertyHandler(isolate, cons, obj);
1957 }
1958
SetCallAsFunctionHandler(FunctionCallback callback,Local<Value> data)1959 void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1960 Local<Value> data) {
1961 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1962 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1963 i::HandleScope scope(isolate);
1964 auto cons = EnsureConstructor(isolate, this);
1965 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
1966 i::Handle<i::CallHandlerInfo> obj = isolate->factory()->NewCallHandlerInfo();
1967 SET_FIELD_WRAPPED(isolate, obj, set_callback, callback);
1968 SET_FIELD_WRAPPED(isolate, obj, set_js_callback, obj->redirected_callback());
1969 if (data.IsEmpty()) {
1970 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1971 }
1972 obj->set_data(*Utils::OpenHandle(*data));
1973 i::FunctionTemplateInfo::SetInstanceCallHandler(isolate, cons, obj);
1974 }
1975
InternalFieldCount()1976 int ObjectTemplate::InternalFieldCount() {
1977 return Utils::OpenHandle(this)->embedder_field_count();
1978 }
1979
SetInternalFieldCount(int value)1980 void ObjectTemplate::SetInternalFieldCount(int value) {
1981 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1982 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1983 "v8::ObjectTemplate::SetInternalFieldCount()",
1984 "Invalid embedder field count")) {
1985 return;
1986 }
1987 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
1988 if (value > 0) {
1989 // The embedder field count is set by the constructor function's
1990 // construct code, so we ensure that there is a constructor
1991 // function to do the setting.
1992 EnsureConstructor(isolate, this);
1993 }
1994 Utils::OpenHandle(this)->set_embedder_field_count(value);
1995 }
1996
IsImmutableProto()1997 bool ObjectTemplate::IsImmutableProto() {
1998 return Utils::OpenHandle(this)->immutable_proto();
1999 }
2000
SetImmutableProto()2001 void ObjectTemplate::SetImmutableProto() {
2002 auto self = Utils::OpenHandle(this);
2003 i::Isolate* isolate = self->GetIsolate();
2004 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2005 self->set_immutable_proto(true);
2006 }
2007
IsCodeLike()2008 bool ObjectTemplate::IsCodeLike() {
2009 return Utils::OpenHandle(this)->code_like();
2010 }
2011
SetCodeLike()2012 void ObjectTemplate::SetCodeLike() {
2013 auto self = Utils::OpenHandle(this);
2014 i::Isolate* isolate = self->GetIsolate();
2015 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2016 self->set_code_like(true);
2017 }
2018
2019 // --- S c r i p t s ---
2020
2021 // Internally, UnboundScript is a SharedFunctionInfo, and Script is a
2022 // JSFunction.
2023
CachedData(const uint8_t * data_,int length_,BufferPolicy buffer_policy_)2024 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
2025 BufferPolicy buffer_policy_)
2026 : data(data_),
2027 length(length_),
2028 rejected(false),
2029 buffer_policy(buffer_policy_) {}
2030
~CachedData()2031 ScriptCompiler::CachedData::~CachedData() {
2032 if (buffer_policy == BufferOwned) {
2033 delete[] data;
2034 }
2035 }
2036
SetBookmark()2037 bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
2038
ResetToBookmark()2039 void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
2040
StreamedSource(ExternalSourceStream * stream,Encoding encoding)2041 ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
2042 Encoding encoding)
2043 : StreamedSource(std::unique_ptr<ExternalSourceStream>(stream), encoding) {}
2044
StreamedSource(std::unique_ptr<ExternalSourceStream> stream,Encoding encoding)2045 ScriptCompiler::StreamedSource::StreamedSource(
2046 std::unique_ptr<ExternalSourceStream> stream, Encoding encoding)
2047 : impl_(new i::ScriptStreamingData(std::move(stream), encoding)) {}
2048
2049 ScriptCompiler::StreamedSource::~StreamedSource() = default;
2050
BindToCurrentContext()2051 Local<Script> UnboundScript::BindToCurrentContext() {
2052 auto function_info =
2053 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2054 i::Isolate* isolate = function_info->GetIsolate();
2055 i::Handle<i::JSFunction> function =
2056 isolate->factory()->NewFunctionFromSharedFunctionInfo(
2057 function_info, isolate->native_context());
2058 return ToApiHandle<Script>(function);
2059 }
2060
GetId()2061 int UnboundScript::GetId() {
2062 auto function_info =
2063 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2064 i::Isolate* isolate = function_info->GetIsolate();
2065 LOG_API(isolate, UnboundScript, GetId);
2066 i::HandleScope scope(isolate);
2067 i::Handle<i::Script> script(i::Script::cast(function_info->script()),
2068 isolate);
2069 return script->id();
2070 }
2071
GetLineNumber(int code_pos)2072 int UnboundScript::GetLineNumber(int code_pos) {
2073 i::Handle<i::SharedFunctionInfo> obj =
2074 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2075 i::Isolate* isolate = obj->GetIsolate();
2076 LOG_API(isolate, UnboundScript, GetLineNumber);
2077 if (obj->script().IsScript()) {
2078 i::Handle<i::Script> script(i::Script::cast(obj->script()), isolate);
2079 return i::Script::GetLineNumber(script, code_pos);
2080 } else {
2081 return -1;
2082 }
2083 }
2084
GetScriptName()2085 Local<Value> UnboundScript::GetScriptName() {
2086 i::Handle<i::SharedFunctionInfo> obj =
2087 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2088 i::Isolate* isolate = obj->GetIsolate();
2089 LOG_API(isolate, UnboundScript, GetName);
2090 if (obj->script().IsScript()) {
2091 i::Object name = i::Script::cast(obj->script()).name();
2092 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
2093 } else {
2094 return Local<String>();
2095 }
2096 }
2097
GetSourceURL()2098 Local<Value> UnboundScript::GetSourceURL() {
2099 i::Handle<i::SharedFunctionInfo> obj =
2100 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2101 i::Isolate* isolate = obj->GetIsolate();
2102 LOG_API(isolate, UnboundScript, GetSourceURL);
2103 if (obj->script().IsScript()) {
2104 i::Object url = i::Script::cast(obj->script()).source_url();
2105 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2106 } else {
2107 return Local<String>();
2108 }
2109 }
2110
GetSourceMappingURL()2111 Local<Value> UnboundScript::GetSourceMappingURL() {
2112 i::Handle<i::SharedFunctionInfo> obj =
2113 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
2114 i::Isolate* isolate = obj->GetIsolate();
2115 LOG_API(isolate, UnboundScript, GetSourceMappingURL);
2116 if (obj->script().IsScript()) {
2117 i::Object url = i::Script::cast(obj->script()).source_mapping_url();
2118 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
2119 } else {
2120 return Local<String>();
2121 }
2122 }
2123
Run(Local<Context> context)2124 MaybeLocal<Value> Script::Run(Local<Context> context) {
2125 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2126 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2127 ENTER_V8(isolate, context, Script, Run, MaybeLocal<Value>(),
2128 InternalEscapableScope);
2129 i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2130 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2131 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2132 auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
2133
2134 i::Handle<i::Object> receiver = isolate->global_proxy();
2135 Local<Value> result;
2136 has_pending_exception = !ToLocal<Value>(
2137 i::Execution::Call(isolate, fun, receiver, 0, nullptr), &result);
2138
2139 RETURN_ON_FAILED_EXECUTION(Value);
2140 RETURN_ESCAPED(result);
2141 }
2142
GetResourceName()2143 Local<Value> ScriptOrModule::GetResourceName() {
2144 i::Handle<i::Script> obj = Utils::OpenHandle(this);
2145 i::Isolate* isolate = obj->GetIsolate();
2146 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2147 i::Handle<i::Object> val(obj->name(), isolate);
2148 return ToApiHandle<Value>(val);
2149 }
2150
GetHostDefinedOptions()2151 Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2152 i::Handle<i::Script> obj = Utils::OpenHandle(this);
2153 i::Isolate* isolate = obj->GetIsolate();
2154 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2155 i::Handle<i::FixedArray> val(obj->host_defined_options(), isolate);
2156 return ToApiHandle<PrimitiveArray>(val);
2157 }
2158
GetUnboundScript()2159 Local<UnboundScript> Script::GetUnboundScript() {
2160 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2161 i::SharedFunctionInfo sfi = i::JSFunction::cast(*obj).shared();
2162 i::Isolate* isolate = sfi.GetIsolate();
2163 return ToApiHandle<UnboundScript>(i::handle(sfi, isolate));
2164 }
2165
2166 // static
New(Isolate * v8_isolate,int length)2167 Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2168 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2169 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2170 Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2171 "length must be equal or greater than zero");
2172 i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2173 return ToApiHandle<PrimitiveArray>(array);
2174 }
2175
Length() const2176 int PrimitiveArray::Length() const {
2177 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2178 return array->length();
2179 }
2180
Set(Isolate * v8_isolate,int index,Local<Primitive> item)2181 void PrimitiveArray::Set(Isolate* v8_isolate, int index,
2182 Local<Primitive> item) {
2183 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2184 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2185 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2186 Utils::ApiCheck(index >= 0 && index < array->length(),
2187 "v8::PrimitiveArray::Set",
2188 "index must be greater than or equal to 0 and less than the "
2189 "array length");
2190 i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2191 array->set(index, *i_item);
2192 }
2193
Get(Isolate * v8_isolate,int index)2194 Local<Primitive> PrimitiveArray::Get(Isolate* v8_isolate, int index) {
2195 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2196 i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2197 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2198 Utils::ApiCheck(index >= 0 && index < array->length(),
2199 "v8::PrimitiveArray::Get",
2200 "index must be greater than or equal to 0 and less than the "
2201 "array length");
2202 i::Handle<i::Object> i_item(array->get(index), isolate);
2203 return ToApiHandle<Primitive>(i_item);
2204 }
2205
GetStatus() const2206 Module::Status Module::GetStatus() const {
2207 i::Handle<i::Module> self = Utils::OpenHandle(this);
2208 switch (self->status()) {
2209 case i::Module::kUninstantiated:
2210 case i::Module::kPreInstantiating:
2211 return kUninstantiated;
2212 case i::Module::kInstantiating:
2213 return kInstantiating;
2214 case i::Module::kInstantiated:
2215 return kInstantiated;
2216 case i::Module::kEvaluating:
2217 return kEvaluating;
2218 case i::Module::kEvaluated:
2219 return kEvaluated;
2220 case i::Module::kErrored:
2221 return kErrored;
2222 }
2223 UNREACHABLE();
2224 }
2225
GetException() const2226 Local<Value> Module::GetException() const {
2227 Utils::ApiCheck(GetStatus() == kErrored, "v8::Module::GetException",
2228 "Module status must be kErrored");
2229 i::Handle<i::Module> self = Utils::OpenHandle(this);
2230 i::Isolate* isolate = self->GetIsolate();
2231 return ToApiHandle<Value>(i::handle(self->GetException(), isolate));
2232 }
2233
GetModuleRequestsLength() const2234 int Module::GetModuleRequestsLength() const {
2235 i::Handle<i::Module> self = Utils::OpenHandle(this);
2236 if (self->IsSyntheticModule()) return 0;
2237 return i::Handle<i::SourceTextModule>::cast(self)
2238 ->info()
2239 .module_requests()
2240 .length();
2241 }
2242
GetModuleRequest(int i) const2243 Local<String> Module::GetModuleRequest(int i) const {
2244 CHECK_GE(i, 0);
2245 i::Handle<i::Module> self = Utils::OpenHandle(this);
2246 CHECK(self->IsSourceTextModule());
2247 i::Isolate* isolate = self->GetIsolate();
2248 i::Handle<i::FixedArray> module_requests(
2249 i::Handle<i::SourceTextModule>::cast(self)->info().module_requests(),
2250 isolate);
2251 CHECK_LT(i, module_requests->length());
2252 i::Handle<i::ModuleRequest> module_request(
2253 i::ModuleRequest::cast(module_requests->get(i)), isolate);
2254 return ToApiHandle<String>(i::handle(module_request->specifier(), isolate));
2255 }
2256
GetModuleRequestLocation(int i) const2257 Location Module::GetModuleRequestLocation(int i) const {
2258 CHECK_GE(i, 0);
2259 i::Handle<i::Module> self = Utils::OpenHandle(this);
2260 i::Isolate* isolate = self->GetIsolate();
2261 i::HandleScope scope(isolate);
2262 CHECK(self->IsSourceTextModule());
2263 i::Handle<i::FixedArray> module_request_positions(
2264 i::Handle<i::SourceTextModule>::cast(self)
2265 ->info()
2266 .module_request_positions(),
2267 isolate);
2268 CHECK_LT(i, module_request_positions->length());
2269 int position = i::Smi::ToInt(module_request_positions->get(i));
2270 i::Handle<i::Script> script(
2271 i::Handle<i::SourceTextModule>::cast(self)->script(), isolate);
2272 i::Script::PositionInfo info;
2273 i::Script::GetPositionInfo(script, position, &info, i::Script::WITH_OFFSET);
2274 return v8::Location(info.line, info.column);
2275 }
2276
GetModuleNamespace()2277 Local<Value> Module::GetModuleNamespace() {
2278 Utils::ApiCheck(
2279 GetStatus() >= kInstantiated, "v8::Module::GetModuleNamespace",
2280 "v8::Module::GetModuleNamespace must be used on an instantiated module");
2281 i::Handle<i::Module> self = Utils::OpenHandle(this);
2282 i::Handle<i::JSModuleNamespace> module_namespace =
2283 i::Module::GetModuleNamespace(self->GetIsolate(), self);
2284 return ToApiHandle<Value>(module_namespace);
2285 }
2286
GetUnboundModuleScript()2287 Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
2288 Utils::ApiCheck(
2289 GetStatus() < kEvaluating, "v8::Module::GetUnboundScript",
2290 "v8::Module::GetUnboundScript must be used on an unevaluated module");
2291 i::Handle<i::Module> self = Utils::OpenHandle(this);
2292 CHECK(self->IsSourceTextModule());
2293 return ToApiHandle<UnboundModuleScript>(i::Handle<i::SharedFunctionInfo>(
2294 i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2295 self->GetIsolate()));
2296 }
2297
ScriptId()2298 int Module::ScriptId() {
2299 i::Handle<i::Module> self = Utils::OpenHandle(this);
2300 Utils::ApiCheck(self->IsSourceTextModule(), "v8::Module::ScriptId",
2301 "v8::Module::ScriptId must be used on an SourceTextModule");
2302
2303 // The SharedFunctionInfo is not available for errored modules.
2304 Utils::ApiCheck(GetStatus() != kErrored, "v8::Module::ScriptId",
2305 "v8::Module::ScriptId must not be used on an errored module");
2306 i::Handle<i::SharedFunctionInfo> sfi(
2307 i::Handle<i::SourceTextModule>::cast(self)->GetSharedFunctionInfo(),
2308 self->GetIsolate());
2309 return ToApiHandle<UnboundScript>(sfi)->GetId();
2310 }
2311
IsGraphAsync() const2312 bool Module::IsGraphAsync() const {
2313 Utils::ApiCheck(
2314 GetStatus() >= kInstantiated, "v8::Module::IsGraphAsync",
2315 "v8::Module::IsGraphAsync must be used on an instantiated module");
2316 i::Handle<i::Module> self = Utils::OpenHandle(this);
2317 auto isolate = reinterpret_cast<i::Isolate*>(self->GetIsolate());
2318 return self->IsGraphAsync(isolate);
2319 }
2320
IsSourceTextModule() const2321 bool Module::IsSourceTextModule() const {
2322 return Utils::OpenHandle(this)->IsSourceTextModule();
2323 }
2324
IsSyntheticModule() const2325 bool Module::IsSyntheticModule() const {
2326 return Utils::OpenHandle(this)->IsSyntheticModule();
2327 }
2328
GetIdentityHash() const2329 int Module::GetIdentityHash() const { return Utils::OpenHandle(this)->hash(); }
2330
InstantiateModule(Local<Context> context,Module::ResolveCallback callback)2331 Maybe<bool> Module::InstantiateModule(Local<Context> context,
2332 Module::ResolveCallback callback) {
2333 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2334 ENTER_V8(isolate, context, Module, InstantiateModule, Nothing<bool>(),
2335 i::HandleScope);
2336 has_pending_exception = !i::Module::Instantiate(
2337 isolate, Utils::OpenHandle(this), context, callback);
2338 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2339 return Just(true);
2340 }
2341
Evaluate(Local<Context> context)2342 MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
2343 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2344 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
2345 ENTER_V8(isolate, context, Module, Evaluate, MaybeLocal<Value>(),
2346 InternalEscapableScope);
2347 i::HistogramTimerScope execute_timer(isolate->counters()->execute(), true);
2348 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
2349 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
2350
2351 i::Handle<i::Module> self = Utils::OpenHandle(this);
2352 // It's an API error to call Evaluate before Instantiate.
2353 CHECK_GE(self->status(), i::Module::kInstantiated);
2354
2355 Local<Value> result;
2356 has_pending_exception = !ToLocal(i::Module::Evaluate(isolate, self), &result);
2357 RETURN_ON_FAILED_EXECUTION(Value);
2358 RETURN_ESCAPED(result);
2359 }
2360
CreateSyntheticModule(Isolate * isolate,Local<String> module_name,const std::vector<Local<v8::String>> & export_names,v8::Module::SyntheticModuleEvaluationSteps evaluation_steps)2361 Local<Module> Module::CreateSyntheticModule(
2362 Isolate* isolate, Local<String> module_name,
2363 const std::vector<Local<v8::String>>& export_names,
2364 v8::Module::SyntheticModuleEvaluationSteps evaluation_steps) {
2365 auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2366 i::Handle<i::String> i_module_name = Utils::OpenHandle(*module_name);
2367 i::Handle<i::FixedArray> i_export_names = i_isolate->factory()->NewFixedArray(
2368 static_cast<int>(export_names.size()));
2369 for (int i = 0; i < i_export_names->length(); ++i) {
2370 i::Handle<i::String> str = i_isolate->factory()->InternalizeString(
2371 Utils::OpenHandle(*export_names[i]));
2372 i_export_names->set(i, *str);
2373 }
2374 return v8::Utils::ToLocal(
2375 i::Handle<i::Module>(i_isolate->factory()->NewSyntheticModule(
2376 i_module_name, i_export_names, evaluation_steps)));
2377 }
2378
SetSyntheticModuleExport(Isolate * isolate,Local<String> export_name,Local<v8::Value> export_value)2379 Maybe<bool> Module::SetSyntheticModuleExport(Isolate* isolate,
2380 Local<String> export_name,
2381 Local<v8::Value> export_value) {
2382 auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2383 i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2384 i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2385 i::Handle<i::Module> self = Utils::OpenHandle(this);
2386 Utils::ApiCheck(self->IsSyntheticModule(),
2387 "v8::Module::SyntheticModuleSetExport",
2388 "v8::Module::SyntheticModuleSetExport must only be called on "
2389 "a SyntheticModule");
2390 ENTER_V8_NO_SCRIPT(i_isolate, isolate->GetCurrentContext(), Module,
2391 SetSyntheticModuleExport, Nothing<bool>(), i::HandleScope);
2392 has_pending_exception =
2393 i::SyntheticModule::SetExport(i_isolate,
2394 i::Handle<i::SyntheticModule>::cast(self),
2395 i_export_name, i_export_value)
2396 .IsNothing();
2397 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
2398 return Just(true);
2399 }
2400
SetSyntheticModuleExport(Local<String> export_name,Local<v8::Value> export_value)2401 void Module::SetSyntheticModuleExport(Local<String> export_name,
2402 Local<v8::Value> export_value) {
2403 i::Handle<i::String> i_export_name = Utils::OpenHandle(*export_name);
2404 i::Handle<i::Object> i_export_value = Utils::OpenHandle(*export_value);
2405 i::Handle<i::Module> self = Utils::OpenHandle(this);
2406 Utils::ApiCheck(self->IsSyntheticModule(),
2407 "v8::Module::SetSyntheticModuleExport",
2408 "v8::Module::SetSyntheticModuleExport must only be called on "
2409 "a SyntheticModule");
2410 i::SyntheticModule::SetExportStrict(self->GetIsolate(),
2411 i::Handle<i::SyntheticModule>::cast(self),
2412 i_export_name, i_export_value);
2413 }
2414
2415 namespace {
2416
GetScriptDetails(i::Isolate * isolate,Local<Value> resource_name,Local<Integer> resource_line_offset,Local<Integer> resource_column_offset,Local<Value> source_map_url,Local<PrimitiveArray> host_defined_options)2417 i::Compiler::ScriptDetails GetScriptDetails(
2418 i::Isolate* isolate, Local<Value> resource_name,
2419 Local<Integer> resource_line_offset, Local<Integer> resource_column_offset,
2420 Local<Value> source_map_url, Local<PrimitiveArray> host_defined_options) {
2421 i::Compiler::ScriptDetails script_details;
2422 if (!resource_name.IsEmpty()) {
2423 script_details.name_obj = Utils::OpenHandle(*(resource_name));
2424 }
2425 if (!resource_line_offset.IsEmpty()) {
2426 script_details.line_offset =
2427 static_cast<int>(resource_line_offset->Value());
2428 }
2429 if (!resource_column_offset.IsEmpty()) {
2430 script_details.column_offset =
2431 static_cast<int>(resource_column_offset->Value());
2432 }
2433 script_details.host_defined_options = isolate->factory()->empty_fixed_array();
2434 if (!host_defined_options.IsEmpty()) {
2435 script_details.host_defined_options =
2436 Utils::OpenHandle(*(host_defined_options));
2437 }
2438 if (!source_map_url.IsEmpty()) {
2439 script_details.source_map_url = Utils::OpenHandle(*(source_map_url));
2440 }
2441 return script_details;
2442 }
2443
2444 } // namespace
2445
CompileUnboundInternal(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2446 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
2447 Isolate* v8_isolate, Source* source, CompileOptions options,
2448 NoCacheReason no_cache_reason) {
2449 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2450 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2451 ENTER_V8_NO_SCRIPT(isolate, v8_isolate->GetCurrentContext(), ScriptCompiler,
2452 CompileUnbound, MaybeLocal<UnboundScript>(),
2453 InternalEscapableScope);
2454
2455 i::ScriptData* script_data = nullptr;
2456 if (options == kConsumeCodeCache) {
2457 DCHECK(source->cached_data);
2458 // ScriptData takes care of pointer-aligning the data.
2459 script_data = new i::ScriptData(source->cached_data->data,
2460 source->cached_data->length);
2461 }
2462
2463 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
2464 i::Handle<i::SharedFunctionInfo> result;
2465 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
2466 i::Compiler::ScriptDetails script_details = GetScriptDetails(
2467 isolate, source->resource_name, source->resource_line_offset,
2468 source->resource_column_offset, source->source_map_url,
2469 source->host_defined_options);
2470 i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info =
2471 i::Compiler::GetSharedFunctionInfoForScript(
2472 isolate, str, script_details, source->resource_options, nullptr,
2473 script_data, options, no_cache_reason, i::NOT_NATIVES_CODE);
2474 if (options == kConsumeCodeCache) {
2475 source->cached_data->rejected = script_data->rejected();
2476 }
2477 delete script_data;
2478 has_pending_exception = !maybe_function_info.ToHandle(&result);
2479 RETURN_ON_FAILED_EXECUTION(UnboundScript);
2480 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
2481 }
2482
CompileUnboundScript(Isolate * v8_isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2483 MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
2484 Isolate* v8_isolate, Source* source, CompileOptions options,
2485 NoCacheReason no_cache_reason) {
2486 Utils::ApiCheck(
2487 !source->GetResourceOptions().IsModule(),
2488 "v8::ScriptCompiler::CompileUnboundScript",
2489 "v8::ScriptCompiler::CompileModule must be used to compile modules");
2490 return CompileUnboundInternal(v8_isolate, source, options, no_cache_reason);
2491 }
2492
Compile(Local<Context> context,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2493 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2494 Source* source,
2495 CompileOptions options,
2496 NoCacheReason no_cache_reason) {
2497 Utils::ApiCheck(
2498 !source->GetResourceOptions().IsModule(), "v8::ScriptCompiler::Compile",
2499 "v8::ScriptCompiler::CompileModule must be used to compile modules");
2500 auto isolate = context->GetIsolate();
2501 auto maybe =
2502 CompileUnboundInternal(isolate, source, options, no_cache_reason);
2503 Local<UnboundScript> result;
2504 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
2505 v8::Context::Scope scope(context);
2506 return result->BindToCurrentContext();
2507 }
2508
CompileModule(Isolate * isolate,Source * source,CompileOptions options,NoCacheReason no_cache_reason)2509 MaybeLocal<Module> ScriptCompiler::CompileModule(
2510 Isolate* isolate, Source* source, CompileOptions options,
2511 NoCacheReason no_cache_reason) {
2512 CHECK(options == kNoCompileOptions || options == kConsumeCodeCache);
2513
2514 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2515
2516 Utils::ApiCheck(source->GetResourceOptions().IsModule(),
2517 "v8::ScriptCompiler::CompileModule",
2518 "Invalid ScriptOrigin: is_module must be true");
2519 auto maybe =
2520 CompileUnboundInternal(isolate, source, options, no_cache_reason);
2521 Local<UnboundScript> unbound;
2522 if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
2523
2524 i::Handle<i::SharedFunctionInfo> shared = Utils::OpenHandle(*unbound);
2525 return ToApiHandle<Module>(i_isolate->factory()->NewSourceTextModule(shared));
2526 }
2527
2528 namespace {
IsIdentifier(i::Isolate * isolate,i::Handle<i::String> string)2529 bool IsIdentifier(i::Isolate* isolate, i::Handle<i::String> string) {
2530 string = i::String::Flatten(isolate, string);
2531 const int length = string->length();
2532 if (length == 0) return false;
2533 if (!i::IsIdentifierStart(string->Get(0))) return false;
2534 i::DisallowHeapAllocation no_gc;
2535 i::String::FlatContent flat = string->GetFlatContent(no_gc);
2536 if (flat.IsOneByte()) {
2537 auto vector = flat.ToOneByteVector();
2538 for (int i = 1; i < length; i++) {
2539 if (!i::IsIdentifierPart(vector[i])) return false;
2540 }
2541 } else {
2542 auto vector = flat.ToUC16Vector();
2543 for (int i = 1; i < length; i++) {
2544 if (!i::IsIdentifierPart(vector[i])) return false;
2545 }
2546 }
2547 return true;
2548 }
2549 } // anonymous namespace
2550
CompileFunctionInContext(Local<Context> v8_context,Source * source,size_t arguments_count,Local<String> arguments[],size_t context_extension_count,Local<Object> context_extensions[],CompileOptions options,NoCacheReason no_cache_reason,Local<ScriptOrModule> * script_or_module_out)2551 MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
2552 Local<Context> v8_context, Source* source, size_t arguments_count,
2553 Local<String> arguments[], size_t context_extension_count,
2554 Local<Object> context_extensions[], CompileOptions options,
2555 NoCacheReason no_cache_reason,
2556 Local<ScriptOrModule>* script_or_module_out) {
2557 Local<Function> result;
2558
2559 {
2560 PREPARE_FOR_EXECUTION(v8_context, ScriptCompiler, CompileFunctionInContext,
2561 Function);
2562 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2563
2564 DCHECK(options == CompileOptions::kConsumeCodeCache ||
2565 options == CompileOptions::kEagerCompile ||
2566 options == CompileOptions::kNoCompileOptions);
2567
2568 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2569
2570 DCHECK(context->IsNativeContext());
2571
2572 i::Handle<i::FixedArray> arguments_list =
2573 isolate->factory()->NewFixedArray(static_cast<int>(arguments_count));
2574 for (int i = 0; i < static_cast<int>(arguments_count); i++) {
2575 i::Handle<i::String> argument = Utils::OpenHandle(*arguments[i]);
2576 if (!IsIdentifier(isolate, argument)) return Local<Function>();
2577 arguments_list->set(i, *argument);
2578 }
2579
2580 for (size_t i = 0; i < context_extension_count; ++i) {
2581 i::Handle<i::JSReceiver> extension =
2582 Utils::OpenHandle(*context_extensions[i]);
2583 if (!extension->IsJSObject()) return Local<Function>();
2584 context = isolate->factory()->NewWithContext(
2585 context,
2586 i::ScopeInfo::CreateForWithScope(
2587 isolate,
2588 context->IsNativeContext()
2589 ? i::Handle<i::ScopeInfo>::null()
2590 : i::Handle<i::ScopeInfo>(context->scope_info(), isolate)),
2591 extension);
2592 }
2593
2594 i::Compiler::ScriptDetails script_details = GetScriptDetails(
2595 isolate, source->resource_name, source->resource_line_offset,
2596 source->resource_column_offset, source->source_map_url,
2597 source->host_defined_options);
2598
2599 i::ScriptData* script_data = nullptr;
2600 if (options == kConsumeCodeCache) {
2601 DCHECK(source->cached_data);
2602 // ScriptData takes care of pointer-aligning the data.
2603 script_data = new i::ScriptData(source->cached_data->data,
2604 source->cached_data->length);
2605 }
2606
2607 i::Handle<i::JSFunction> scoped_result;
2608 has_pending_exception =
2609 !i::Compiler::GetWrappedFunction(
2610 Utils::OpenHandle(*source->source_string), arguments_list, context,
2611 script_details, source->resource_options, script_data, options,
2612 no_cache_reason)
2613 .ToHandle(&scoped_result);
2614 if (options == kConsumeCodeCache) {
2615 source->cached_data->rejected = script_data->rejected();
2616 }
2617 delete script_data;
2618 RETURN_ON_FAILED_EXECUTION(Function);
2619 result = handle_scope.Escape(Utils::CallableToLocal(scoped_result));
2620 }
2621
2622 if (script_or_module_out != nullptr) {
2623 i::Handle<i::JSFunction> function =
2624 i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*result));
2625 i::Isolate* isolate = function->GetIsolate();
2626 i::Handle<i::SharedFunctionInfo> shared(function->shared(), isolate);
2627 i::Handle<i::Script> script(i::Script::cast(shared->script()), isolate);
2628 *script_or_module_out = v8::Utils::ScriptOrModuleToLocal(script);
2629 }
2630
2631 return result;
2632 }
2633
Run()2634 void ScriptCompiler::ScriptStreamingTask::Run() { data_->task->Run(); }
2635
StartStreamingScript(Isolate * v8_isolate,StreamedSource * source,CompileOptions options)2636 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
2637 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
2638 // We don't support other compile options on streaming background compiles.
2639 // TODO(rmcilroy): remove CompileOptions from the API.
2640 CHECK(options == ScriptCompiler::kNoCompileOptions);
2641 return StartStreaming(v8_isolate, source);
2642 }
2643
StartStreaming(Isolate * v8_isolate,StreamedSource * source)2644 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreaming(
2645 Isolate* v8_isolate, StreamedSource* source) {
2646 if (!i::FLAG_script_streaming) return nullptr;
2647 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2648 i::ScriptStreamingData* data = source->impl();
2649 std::unique_ptr<i::BackgroundCompileTask> task =
2650 std::make_unique<i::BackgroundCompileTask>(data, isolate);
2651 data->task = std::move(task);
2652 return new ScriptCompiler::ScriptStreamingTask(data);
2653 }
2654
Compile(Local<Context> context,StreamedSource * v8_source,Local<String> full_source_string,const ScriptOrigin & origin)2655 MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2656 StreamedSource* v8_source,
2657 Local<String> full_source_string,
2658 const ScriptOrigin& origin) {
2659 PREPARE_FOR_EXECUTION(context, ScriptCompiler, Compile, Script);
2660 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.ScriptCompiler");
2661 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
2662 "V8.CompileStreamedScript");
2663
2664 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2665 i::Compiler::ScriptDetails script_details = GetScriptDetails(
2666 isolate, origin.ResourceName(), origin.ResourceLineOffset(),
2667 origin.ResourceColumnOffset(), origin.SourceMapUrl(),
2668 origin.HostDefinedOptions());
2669 i::ScriptStreamingData* data = v8_source->impl();
2670
2671 i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info =
2672 i::Compiler::GetSharedFunctionInfoForStreamedScript(
2673 isolate, str, script_details, origin.Options(), data);
2674
2675 i::Handle<i::SharedFunctionInfo> result;
2676 has_pending_exception = !maybe_function_info.ToHandle(&result);
2677 if (has_pending_exception) isolate->ReportPendingMessages();
2678
2679 RETURN_ON_FAILED_EXECUTION(Script);
2680
2681 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
2682 if (generic.IsEmpty()) return Local<Script>();
2683 Local<Script> bound = generic->BindToCurrentContext();
2684 if (bound.IsEmpty()) return Local<Script>();
2685 RETURN_ESCAPED(bound);
2686 }
2687
CachedDataVersionTag()2688 uint32_t ScriptCompiler::CachedDataVersionTag() {
2689 return static_cast<uint32_t>(base::hash_combine(
2690 internal::Version::Hash(), internal::FlagList::Hash(),
2691 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2692 }
2693
CreateCodeCache(Local<UnboundScript> unbound_script)2694 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2695 Local<UnboundScript> unbound_script) {
2696 i::Handle<i::SharedFunctionInfo> shared =
2697 i::Handle<i::SharedFunctionInfo>::cast(
2698 Utils::OpenHandle(*unbound_script));
2699 DCHECK(shared->is_toplevel());
2700 return i::CodeSerializer::Serialize(shared);
2701 }
2702
2703 // static
CreateCodeCache(Local<UnboundModuleScript> unbound_module_script)2704 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
2705 Local<UnboundModuleScript> unbound_module_script) {
2706 i::Handle<i::SharedFunctionInfo> shared =
2707 i::Handle<i::SharedFunctionInfo>::cast(
2708 Utils::OpenHandle(*unbound_module_script));
2709 DCHECK(shared->is_toplevel());
2710 return i::CodeSerializer::Serialize(shared);
2711 }
2712
CreateCodeCacheForFunction(Local<Function> function)2713 ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
2714 Local<Function> function) {
2715 auto js_function =
2716 i::Handle<i::JSFunction>::cast(Utils::OpenHandle(*function));
2717 i::Handle<i::SharedFunctionInfo> shared(js_function->shared(),
2718 js_function->GetIsolate());
2719 CHECK(shared->is_wrapped());
2720 return i::CodeSerializer::Serialize(shared);
2721 }
2722
Compile(Local<Context> context,Local<String> source,ScriptOrigin * origin)2723 MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2724 ScriptOrigin* origin) {
2725 if (origin) {
2726 ScriptCompiler::Source script_source(source, *origin);
2727 return ScriptCompiler::Compile(context, &script_source);
2728 }
2729 ScriptCompiler::Source script_source(source);
2730 return ScriptCompiler::Compile(context, &script_source);
2731 }
2732
2733 // --- E x c e p t i o n s ---
2734
TryCatch(v8::Isolate * isolate)2735 v8::TryCatch::TryCatch(v8::Isolate* isolate)
2736 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2737 next_(isolate_->try_catch_handler()),
2738 is_verbose_(false),
2739 can_continue_(true),
2740 capture_message_(true),
2741 rethrow_(false),
2742 has_terminated_(false) {
2743 ResetInternal();
2744 // Special handling for simulators which have a separate JS stack.
2745 js_stack_comparable_address_ = reinterpret_cast<void*>(
2746 i::SimulatorStack::RegisterJSStackComparableAddress(isolate_));
2747 isolate_->RegisterTryCatchHandler(this);
2748 }
2749
~TryCatch()2750 v8::TryCatch::~TryCatch() {
2751 if (rethrow_) {
2752 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2753 v8::HandleScope scope(isolate);
2754 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2755 if (HasCaught() && capture_message_) {
2756 // If an exception was caught and rethrow_ is indicated, the saved
2757 // message, script, and location need to be restored to Isolate TLS
2758 // for reuse. capture_message_ needs to be disabled so that Throw()
2759 // does not create a new message.
2760 isolate_->thread_local_top()->rethrowing_message_ = true;
2761 isolate_->RestorePendingMessageFromTryCatch(this);
2762 }
2763 isolate_->UnregisterTryCatchHandler(this);
2764 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2765 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2766 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
2767 } else {
2768 if (HasCaught() && isolate_->has_scheduled_exception()) {
2769 // If an exception was caught but is still scheduled because no API call
2770 // promoted it, then it is canceled to prevent it from being propagated.
2771 // Note that this will not cancel termination exceptions.
2772 isolate_->CancelScheduledExceptionFromTryCatch(this);
2773 }
2774 isolate_->UnregisterTryCatchHandler(this);
2775 i::SimulatorStack::UnregisterJSStackComparableAddress(isolate_);
2776 }
2777 }
2778
operator new(size_t)2779 void* v8::TryCatch::operator new(size_t) { base::OS::Abort(); }
operator new[](size_t)2780 void* v8::TryCatch::operator new[](size_t) { base::OS::Abort(); }
operator delete(void *,size_t)2781 void v8::TryCatch::operator delete(void*, size_t) { base::OS::Abort(); }
operator delete[](void *,size_t)2782 void v8::TryCatch::operator delete[](void*, size_t) { base::OS::Abort(); }
2783
HasCaught() const2784 bool v8::TryCatch::HasCaught() const {
2785 return !i::Object(reinterpret_cast<i::Address>(exception_))
2786 .IsTheHole(isolate_);
2787 }
2788
CanContinue() const2789 bool v8::TryCatch::CanContinue() const { return can_continue_; }
2790
HasTerminated() const2791 bool v8::TryCatch::HasTerminated() const { return has_terminated_; }
2792
ReThrow()2793 v8::Local<v8::Value> v8::TryCatch::ReThrow() {
2794 if (!HasCaught()) return v8::Local<v8::Value>();
2795 rethrow_ = true;
2796 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
2797 }
2798
Exception() const2799 v8::Local<Value> v8::TryCatch::Exception() const {
2800 if (HasCaught()) {
2801 // Check for out of memory exception.
2802 i::Object exception(reinterpret_cast<i::Address>(exception_));
2803 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
2804 } else {
2805 return v8::Local<Value>();
2806 }
2807 }
2808
StackTrace(Local<Context> context,Local<Value> exception)2809 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context,
2810 Local<Value> exception) {
2811 i::Handle<i::Object> i_exception = Utils::OpenHandle(*exception);
2812 if (!i_exception->IsJSObject()) return v8::Local<Value>();
2813 PREPARE_FOR_EXECUTION(context, TryCatch, StackTrace, Value);
2814 auto obj = i::Handle<i::JSObject>::cast(i_exception);
2815 i::Handle<i::String> name = isolate->factory()->stack_string();
2816 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2817 has_pending_exception = maybe.IsNothing();
2818 RETURN_ON_FAILED_EXECUTION(Value);
2819 if (!maybe.FromJust()) return v8::Local<Value>();
2820 Local<Value> result;
2821 has_pending_exception =
2822 !ToLocal<Value>(i::JSReceiver::GetProperty(isolate, obj, name), &result);
2823 RETURN_ON_FAILED_EXECUTION(Value);
2824 RETURN_ESCAPED(result);
2825 }
2826
StackTrace(Local<Context> context) const2827 MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2828 if (!HasCaught()) return v8::Local<Value>();
2829 return StackTrace(context, Exception());
2830 }
2831
Message() const2832 v8::Local<v8::Message> v8::TryCatch::Message() const {
2833 i::Object message(reinterpret_cast<i::Address>(message_obj_));
2834 DCHECK(message.IsJSMessageObject() || message.IsTheHole(isolate_));
2835 if (HasCaught() && !message.IsTheHole(isolate_)) {
2836 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2837 } else {
2838 return v8::Local<v8::Message>();
2839 }
2840 }
2841
Reset()2842 void v8::TryCatch::Reset() {
2843 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2844 // If an exception was caught but is still scheduled because no API call
2845 // promoted it, then it is canceled to prevent it from being propagated.
2846 // Note that this will not cancel termination exceptions.
2847 isolate_->CancelScheduledExceptionFromTryCatch(this);
2848 }
2849 ResetInternal();
2850 }
2851
ResetInternal()2852 void v8::TryCatch::ResetInternal() {
2853 i::Object the_hole = i::ReadOnlyRoots(isolate_).the_hole_value();
2854 exception_ = reinterpret_cast<void*>(the_hole.ptr());
2855 message_obj_ = reinterpret_cast<void*>(the_hole.ptr());
2856 }
2857
SetVerbose(bool value)2858 void v8::TryCatch::SetVerbose(bool value) { is_verbose_ = value; }
2859
IsVerbose() const2860 bool v8::TryCatch::IsVerbose() const { return is_verbose_; }
2861
SetCaptureMessage(bool value)2862 void v8::TryCatch::SetCaptureMessage(bool value) { capture_message_ = value; }
2863
2864 // --- M e s s a g e ---
2865
Get() const2866 Local<String> Message::Get() const {
2867 auto self = Utils::OpenHandle(this);
2868 i::Isolate* isolate = self->GetIsolate();
2869 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2870 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2871 i::Handle<i::String> raw_result =
2872 i::MessageHandler::GetMessage(isolate, self);
2873 Local<String> result = Utils::ToLocal(raw_result);
2874 return scope.Escape(result);
2875 }
2876
GetIsolate() const2877 v8::Isolate* Message::GetIsolate() const {
2878 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2879 return reinterpret_cast<Isolate*>(isolate);
2880 }
2881
GetScriptOrigin() const2882 ScriptOrigin Message::GetScriptOrigin() const {
2883 auto self = Utils::OpenHandle(this);
2884 i::Isolate* isolate = self->GetIsolate();
2885 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2886 i::Handle<i::Script> script(self->script(), isolate);
2887 return GetScriptOriginForScript(isolate, script);
2888 }
2889
GetScriptResourceName() const2890 v8::Local<Value> Message::GetScriptResourceName() const {
2891 return GetScriptOrigin().ResourceName();
2892 }
2893
GetStackTrace() const2894 v8::Local<v8::StackTrace> Message::GetStackTrace() const {
2895 auto self = Utils::OpenHandle(this);
2896 i::Isolate* isolate = self->GetIsolate();
2897 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2898 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2899 i::Handle<i::Object> stackFramesObj(self->stack_frames(), isolate);
2900 if (!stackFramesObj->IsFixedArray()) return v8::Local<v8::StackTrace>();
2901 auto stackTrace = i::Handle<i::FixedArray>::cast(stackFramesObj);
2902 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
2903 }
2904
GetLineNumber(Local<Context> context) const2905 Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2906 auto self = Utils::OpenHandle(this);
2907 i::Isolate* isolate = self->GetIsolate();
2908 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2909 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2910 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2911 return Just(self->GetLineNumber());
2912 }
2913
GetStartPosition() const2914 int Message::GetStartPosition() const {
2915 auto self = Utils::OpenHandle(this);
2916 i::Isolate* isolate = self->GetIsolate();
2917 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2918 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2919 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2920 return self->GetStartPosition();
2921 }
2922
GetEndPosition() const2923 int Message::GetEndPosition() const {
2924 auto self = Utils::OpenHandle(this);
2925 i::Isolate* isolate = self->GetIsolate();
2926 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2927 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2928 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2929 return self->GetEndPosition();
2930 }
2931
ErrorLevel() const2932 int Message::ErrorLevel() const {
2933 auto self = Utils::OpenHandle(this);
2934 return self->error_level();
2935 }
2936
GetStartColumn() const2937 int Message::GetStartColumn() const {
2938 auto self = Utils::OpenHandle(this);
2939 i::Isolate* isolate = self->GetIsolate();
2940 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2941 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2942 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2943 return self->GetColumnNumber();
2944 }
2945
GetWasmFunctionIndex() const2946 int Message::GetWasmFunctionIndex() const {
2947 auto self = Utils::OpenHandle(this);
2948 i::Isolate* isolate = self->GetIsolate();
2949 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2950 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2951 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2952 int start_position = self->GetColumnNumber();
2953 if (start_position == -1) return Message::kNoWasmFunctionIndexInfo;
2954
2955 i::Handle<i::Script> script(self->script(), isolate);
2956
2957 if (script->type() != i::Script::TYPE_WASM) {
2958 return Message::kNoWasmFunctionIndexInfo;
2959 }
2960
2961 auto debug_script = ToApiHandle<debug::Script>(script);
2962 return Local<debug::WasmScript>::Cast(debug_script)
2963 ->GetContainingFunction(start_position);
2964 }
2965
GetStartColumn(Local<Context> context) const2966 Maybe<int> Message::GetStartColumn(Local<Context> context) const {
2967 return Just(GetStartColumn());
2968 }
2969
GetEndColumn() const2970 int Message::GetEndColumn() const {
2971 auto self = Utils::OpenHandle(this);
2972 i::Isolate* isolate = self->GetIsolate();
2973 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2974 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
2975 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
2976 const int column_number = self->GetColumnNumber();
2977 if (column_number == -1) return -1;
2978 const int start = self->GetStartPosition();
2979 const int end = self->GetEndPosition();
2980 return column_number + (end - start);
2981 }
2982
GetEndColumn(Local<Context> context) const2983 Maybe<int> Message::GetEndColumn(Local<Context> context) const {
2984 return Just(GetEndColumn());
2985 }
2986
IsSharedCrossOrigin() const2987 bool Message::IsSharedCrossOrigin() const {
2988 auto self = Utils::OpenHandle(this);
2989 i::Isolate* isolate = self->GetIsolate();
2990 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2991 return self->script().origin_options().IsSharedCrossOrigin();
2992 }
2993
IsOpaque() const2994 bool Message::IsOpaque() const {
2995 auto self = Utils::OpenHandle(this);
2996 i::Isolate* isolate = self->GetIsolate();
2997 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2998 return self->script().origin_options().IsOpaque();
2999 }
3000
GetSourceLine(Local<Context> context) const3001 MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
3002 auto self = Utils::OpenHandle(this);
3003 i::Isolate* isolate = self->GetIsolate();
3004 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3005 EscapableHandleScope handle_scope(reinterpret_cast<Isolate*>(isolate));
3006 i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, self);
3007 RETURN_ESCAPED(Utils::ToLocal(self->GetSourceLine()));
3008 }
3009
PrintCurrentStackTrace(Isolate * isolate,FILE * out)3010 void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
3011 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3012 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3013 i_isolate->PrintCurrentStackTrace(out);
3014 }
3015
3016 // --- S t a c k T r a c e ---
3017
GetFrame(Isolate * v8_isolate,uint32_t index) const3018 Local<StackFrame> StackTrace::GetFrame(Isolate* v8_isolate,
3019 uint32_t index) const {
3020 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3021 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
3022 EscapableHandleScope scope(v8_isolate);
3023 auto obj = handle(Utils::OpenHandle(this)->get(index), isolate);
3024 auto frame = i::Handle<i::StackTraceFrame>::cast(obj);
3025 return scope.Escape(Utils::StackFrameToLocal(frame));
3026 }
3027
GetFrameCount() const3028 int StackTrace::GetFrameCount() const {
3029 return Utils::OpenHandle(this)->length();
3030 }
3031
CurrentStackTrace(Isolate * isolate,int frame_limit,StackTraceOptions options)3032 Local<StackTrace> StackTrace::CurrentStackTrace(Isolate* isolate,
3033 int frame_limit,
3034 StackTraceOptions options) {
3035 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3036 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3037 i::Handle<i::FixedArray> stackTrace =
3038 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
3039 return Utils::StackTraceToLocal(stackTrace);
3040 }
3041
3042 // --- S t a c k F r a m e ---
3043
GetLineNumber() const3044 int StackFrame::GetLineNumber() const {
3045 return i::StackTraceFrame::GetOneBasedLineNumber(Utils::OpenHandle(this));
3046 }
3047
GetColumn() const3048 int StackFrame::GetColumn() const {
3049 return i::StackTraceFrame::GetOneBasedColumnNumber(Utils::OpenHandle(this));
3050 }
3051
GetScriptId() const3052 int StackFrame::GetScriptId() const {
3053 return i::StackTraceFrame::GetScriptId(Utils::OpenHandle(this));
3054 }
3055
GetScriptName() const3056 Local<String> StackFrame::GetScriptName() const {
3057 auto self = Utils::OpenHandle(this);
3058 i::Isolate* isolate = self->GetIsolate();
3059 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3060 i::Handle<i::Object> name = i::StackTraceFrame::GetFileName(self);
3061 return name->IsString()
3062 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name)))
3063 : Local<String>();
3064 }
3065
GetScriptNameOrSourceURL() const3066 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
3067 auto self = Utils::OpenHandle(this);
3068 i::Isolate* isolate = self->GetIsolate();
3069 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3070 i::Handle<i::Object> name =
3071 i::StackTraceFrame::GetScriptNameOrSourceUrl(self);
3072 return name->IsString()
3073 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name)))
3074 : Local<String>();
3075 }
3076
GetFunctionName() const3077 Local<String> StackFrame::GetFunctionName() const {
3078 auto self = Utils::OpenHandle(this);
3079 i::Isolate* isolate = self->GetIsolate();
3080 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
3081 i::Handle<i::Object> name = i::StackTraceFrame::GetFunctionName(self);
3082 return name->IsString()
3083 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(name)))
3084 : Local<String>();
3085 }
3086
IsEval() const3087 bool StackFrame::IsEval() const {
3088 return i::StackTraceFrame::IsEval(Utils::OpenHandle(this));
3089 }
3090
IsConstructor() const3091 bool StackFrame::IsConstructor() const {
3092 return i::StackTraceFrame::IsConstructor(Utils::OpenHandle(this));
3093 }
3094
IsWasm() const3095 bool StackFrame::IsWasm() const {
3096 return i::StackTraceFrame::IsWasm(Utils::OpenHandle(this));
3097 }
3098
IsUserJavaScript() const3099 bool StackFrame::IsUserJavaScript() const {
3100 return i::StackTraceFrame::IsUserJavaScript(Utils::OpenHandle(this));
3101 }
3102
3103 // --- J S O N ---
3104
Parse(Local<Context> context,Local<String> json_string)3105 MaybeLocal<Value> JSON::Parse(Local<Context> context,
3106 Local<String> json_string) {
3107 PREPARE_FOR_EXECUTION(context, JSON, Parse, Value);
3108 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
3109 i::Handle<i::String> source = i::String::Flatten(isolate, string);
3110 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
3111 auto maybe = source->IsOneByteRepresentation()
3112 ? i::JsonParser<uint8_t>::Parse(isolate, source, undefined)
3113 : i::JsonParser<uint16_t>::Parse(isolate, source, undefined);
3114 Local<Value> result;
3115 has_pending_exception = !ToLocal<Value>(maybe, &result);
3116 RETURN_ON_FAILED_EXECUTION(Value);
3117 RETURN_ESCAPED(result);
3118 }
3119
Stringify(Local<Context> context,Local<Value> json_object,Local<String> gap)3120 MaybeLocal<String> JSON::Stringify(Local<Context> context,
3121 Local<Value> json_object,
3122 Local<String> gap) {
3123 PREPARE_FOR_EXECUTION(context, JSON, Stringify, String);
3124 i::Handle<i::Object> object = Utils::OpenHandle(*json_object);
3125 i::Handle<i::Object> replacer = isolate->factory()->undefined_value();
3126 i::Handle<i::String> gap_string = gap.IsEmpty()
3127 ? isolate->factory()->empty_string()
3128 : Utils::OpenHandle(*gap);
3129 i::Handle<i::Object> maybe;
3130 has_pending_exception =
3131 !i::JsonStringify(isolate, object, replacer, gap_string).ToHandle(&maybe);
3132 RETURN_ON_FAILED_EXECUTION(String);
3133 Local<String> result;
3134 has_pending_exception =
3135 !ToLocal<String>(i::Object::ToString(isolate, maybe), &result);
3136 RETURN_ON_FAILED_EXECUTION(String);
3137 RETURN_ESCAPED(result);
3138 }
3139
3140 // --- V a l u e S e r i a l i z a t i o n ---
3141
WriteHostObject(Isolate * v8_isolate,Local<Object> object)3142 Maybe<bool> ValueSerializer::Delegate::WriteHostObject(Isolate* v8_isolate,
3143 Local<Object> object) {
3144 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3145 isolate->ScheduleThrow(*isolate->factory()->NewError(
3146 isolate->error_function(), i::MessageTemplate::kDataCloneError,
3147 Utils::OpenHandle(*object)));
3148 return Nothing<bool>();
3149 }
3150
GetSharedArrayBufferId(Isolate * v8_isolate,Local<SharedArrayBuffer> shared_array_buffer)3151 Maybe<uint32_t> ValueSerializer::Delegate::GetSharedArrayBufferId(
3152 Isolate* v8_isolate, Local<SharedArrayBuffer> shared_array_buffer) {
3153 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3154 isolate->ScheduleThrow(*isolate->factory()->NewError(
3155 isolate->error_function(), i::MessageTemplate::kDataCloneError,
3156 Utils::OpenHandle(*shared_array_buffer)));
3157 return Nothing<uint32_t>();
3158 }
3159
GetWasmModuleTransferId(Isolate * v8_isolate,Local<WasmModuleObject> module)3160 Maybe<uint32_t> ValueSerializer::Delegate::GetWasmModuleTransferId(
3161 Isolate* v8_isolate, Local<WasmModuleObject> module) {
3162 return Nothing<uint32_t>();
3163 }
3164
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)3165 void* ValueSerializer::Delegate::ReallocateBufferMemory(void* old_buffer,
3166 size_t size,
3167 size_t* actual_size) {
3168 *actual_size = size;
3169 return realloc(old_buffer, size);
3170 }
3171
FreeBufferMemory(void * buffer)3172 void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
3173 return free(buffer);
3174 }
3175
3176 struct ValueSerializer::PrivateData {
PrivateDatav8::ValueSerializer::PrivateData3177 explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
3178 : isolate(i), serializer(i, delegate) {}
3179 i::Isolate* isolate;
3180 i::ValueSerializer serializer;
3181 };
3182
ValueSerializer(Isolate * isolate)3183 ValueSerializer::ValueSerializer(Isolate* isolate)
3184 : ValueSerializer(isolate, nullptr) {}
3185
ValueSerializer(Isolate * isolate,Delegate * delegate)3186 ValueSerializer::ValueSerializer(Isolate* isolate, Delegate* delegate)
3187 : private_(
3188 new PrivateData(reinterpret_cast<i::Isolate*>(isolate), delegate)) {}
3189
~ValueSerializer()3190 ValueSerializer::~ValueSerializer() { delete private_; }
3191
WriteHeader()3192 void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); }
3193
SetTreatArrayBufferViewsAsHostObjects(bool mode)3194 void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
3195 private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
3196 }
3197
WriteValue(Local<Context> context,Local<Value> value)3198 Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
3199 Local<Value> value) {
3200 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3201 ENTER_V8(isolate, context, ValueSerializer, WriteValue, Nothing<bool>(),
3202 i::HandleScope);
3203 i::Handle<i::Object> object = Utils::OpenHandle(*value);
3204 Maybe<bool> result = private_->serializer.WriteObject(object);
3205 has_pending_exception = result.IsNothing();
3206 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3207 return result;
3208 }
3209
Release()3210 std::pair<uint8_t*, size_t> ValueSerializer::Release() {
3211 return private_->serializer.Release();
3212 }
3213
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3214 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
3215 Local<ArrayBuffer> array_buffer) {
3216 private_->serializer.TransferArrayBuffer(transfer_id,
3217 Utils::OpenHandle(*array_buffer));
3218 }
3219
WriteUint32(uint32_t value)3220 void ValueSerializer::WriteUint32(uint32_t value) {
3221 private_->serializer.WriteUint32(value);
3222 }
3223
WriteUint64(uint64_t value)3224 void ValueSerializer::WriteUint64(uint64_t value) {
3225 private_->serializer.WriteUint64(value);
3226 }
3227
WriteDouble(double value)3228 void ValueSerializer::WriteDouble(double value) {
3229 private_->serializer.WriteDouble(value);
3230 }
3231
WriteRawBytes(const void * source,size_t length)3232 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
3233 private_->serializer.WriteRawBytes(source, length);
3234 }
3235
ReadHostObject(Isolate * v8_isolate)3236 MaybeLocal<Object> ValueDeserializer::Delegate::ReadHostObject(
3237 Isolate* v8_isolate) {
3238 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3239 isolate->ScheduleThrow(*isolate->factory()->NewError(
3240 isolate->error_function(),
3241 i::MessageTemplate::kDataCloneDeserializationError));
3242 return MaybeLocal<Object>();
3243 }
3244
GetWasmModuleFromId(Isolate * v8_isolate,uint32_t id)3245 MaybeLocal<WasmModuleObject> ValueDeserializer::Delegate::GetWasmModuleFromId(
3246 Isolate* v8_isolate, uint32_t id) {
3247 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3248 isolate->ScheduleThrow(*isolate->factory()->NewError(
3249 isolate->error_function(),
3250 i::MessageTemplate::kDataCloneDeserializationError));
3251 return MaybeLocal<WasmModuleObject>();
3252 }
3253
3254 MaybeLocal<SharedArrayBuffer>
GetSharedArrayBufferFromId(Isolate * v8_isolate,uint32_t id)3255 ValueDeserializer::Delegate::GetSharedArrayBufferFromId(Isolate* v8_isolate,
3256 uint32_t id) {
3257 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3258 isolate->ScheduleThrow(*isolate->factory()->NewError(
3259 isolate->error_function(),
3260 i::MessageTemplate::kDataCloneDeserializationError));
3261 return MaybeLocal<SharedArrayBuffer>();
3262 }
3263
3264 struct ValueDeserializer::PrivateData {
PrivateDatav8::ValueDeserializer::PrivateData3265 PrivateData(i::Isolate* i, i::Vector<const uint8_t> data, Delegate* delegate)
3266 : isolate(i), deserializer(i, data, delegate) {}
3267 i::Isolate* isolate;
3268 i::ValueDeserializer deserializer;
3269 bool has_aborted = false;
3270 bool supports_legacy_wire_format = false;
3271 };
3272
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size)3273 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3274 size_t size)
3275 : ValueDeserializer(isolate, data, size, nullptr) {}
3276
ValueDeserializer(Isolate * isolate,const uint8_t * data,size_t size,Delegate * delegate)3277 ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data,
3278 size_t size, Delegate* delegate) {
3279 if (base::IsValueInRangeForNumericType<int>(size)) {
3280 private_ = new PrivateData(
3281 reinterpret_cast<i::Isolate*>(isolate),
3282 i::Vector<const uint8_t>(data, static_cast<int>(size)), delegate);
3283 } else {
3284 private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate),
3285 i::Vector<const uint8_t>(nullptr, 0), nullptr);
3286 private_->has_aborted = true;
3287 }
3288 }
3289
~ValueDeserializer()3290 ValueDeserializer::~ValueDeserializer() { delete private_; }
3291
ReadHeader(Local<Context> context)3292 Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) {
3293 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3294 ENTER_V8_NO_SCRIPT(isolate, context, ValueDeserializer, ReadHeader,
3295 Nothing<bool>(), i::HandleScope);
3296
3297 // We could have aborted during the constructor.
3298 // If so, ReadHeader is where we report it.
3299 if (private_->has_aborted) {
3300 isolate->Throw(*isolate->factory()->NewError(
3301 i::MessageTemplate::kDataCloneDeserializationError));
3302 has_pending_exception = true;
3303 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3304 }
3305
3306 bool read_header = false;
3307 has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header);
3308 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3309 DCHECK(read_header);
3310
3311 static const uint32_t kMinimumNonLegacyVersion = 13;
3312 if (GetWireFormatVersion() < kMinimumNonLegacyVersion &&
3313 !private_->supports_legacy_wire_format) {
3314 isolate->Throw(*isolate->factory()->NewError(
3315 i::MessageTemplate::kDataCloneDeserializationVersionError));
3316 has_pending_exception = true;
3317 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3318 }
3319
3320 return Just(true);
3321 }
3322
SetSupportsLegacyWireFormat(bool supports_legacy_wire_format)3323 void ValueDeserializer::SetSupportsLegacyWireFormat(
3324 bool supports_legacy_wire_format) {
3325 private_->supports_legacy_wire_format = supports_legacy_wire_format;
3326 }
3327
GetWireFormatVersion() const3328 uint32_t ValueDeserializer::GetWireFormatVersion() const {
3329 CHECK(!private_->has_aborted);
3330 return private_->deserializer.GetWireFormatVersion();
3331 }
3332
ReadValue(Local<Context> context)3333 MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) {
3334 CHECK(!private_->has_aborted);
3335 PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value);
3336 i::MaybeHandle<i::Object> result;
3337 if (GetWireFormatVersion() > 0) {
3338 result = private_->deserializer.ReadObject();
3339 } else {
3340 result =
3341 private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat();
3342 }
3343 Local<Value> value;
3344 has_pending_exception = !ToLocal(result, &value);
3345 RETURN_ON_FAILED_EXECUTION(Value);
3346 RETURN_ESCAPED(value);
3347 }
3348
TransferArrayBuffer(uint32_t transfer_id,Local<ArrayBuffer> array_buffer)3349 void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id,
3350 Local<ArrayBuffer> array_buffer) {
3351 CHECK(!private_->has_aborted);
3352 private_->deserializer.TransferArrayBuffer(transfer_id,
3353 Utils::OpenHandle(*array_buffer));
3354 }
3355
TransferSharedArrayBuffer(uint32_t transfer_id,Local<SharedArrayBuffer> shared_array_buffer)3356 void ValueDeserializer::TransferSharedArrayBuffer(
3357 uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) {
3358 CHECK(!private_->has_aborted);
3359 private_->deserializer.TransferArrayBuffer(
3360 transfer_id, Utils::OpenHandle(*shared_array_buffer));
3361 }
3362
ReadUint32(uint32_t * value)3363 bool ValueDeserializer::ReadUint32(uint32_t* value) {
3364 return private_->deserializer.ReadUint32(value);
3365 }
3366
ReadUint64(uint64_t * value)3367 bool ValueDeserializer::ReadUint64(uint64_t* value) {
3368 return private_->deserializer.ReadUint64(value);
3369 }
3370
ReadDouble(double * value)3371 bool ValueDeserializer::ReadDouble(double* value) {
3372 return private_->deserializer.ReadDouble(value);
3373 }
3374
ReadRawBytes(size_t length,const void ** data)3375 bool ValueDeserializer::ReadRawBytes(size_t length, const void** data) {
3376 return private_->deserializer.ReadRawBytes(length, data);
3377 }
3378
3379 // --- D a t a ---
3380
FullIsUndefined() const3381 bool Value::FullIsUndefined() const {
3382 i::Handle<i::Object> object = Utils::OpenHandle(this);
3383 bool result = object->IsUndefined();
3384 DCHECK_EQ(result, QuickIsUndefined());
3385 return result;
3386 }
3387
FullIsNull() const3388 bool Value::FullIsNull() const {
3389 i::Handle<i::Object> object = Utils::OpenHandle(this);
3390 bool result = object->IsNull();
3391 DCHECK_EQ(result, QuickIsNull());
3392 return result;
3393 }
3394
IsTrue() const3395 bool Value::IsTrue() const {
3396 i::Handle<i::Object> object = Utils::OpenHandle(this);
3397 if (object->IsSmi()) return false;
3398 return object->IsTrue();
3399 }
3400
IsFalse() const3401 bool Value::IsFalse() const {
3402 i::Handle<i::Object> object = Utils::OpenHandle(this);
3403 if (object->IsSmi()) return false;
3404 return object->IsFalse();
3405 }
3406
IsFunction() const3407 bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
3408
IsName() const3409 bool Value::IsName() const { return Utils::OpenHandle(this)->IsName(); }
3410
FullIsString() const3411 bool Value::FullIsString() const {
3412 bool result = Utils::OpenHandle(this)->IsString();
3413 DCHECK_EQ(result, QuickIsString());
3414 return result;
3415 }
3416
IsSymbol() const3417 bool Value::IsSymbol() const {
3418 return Utils::OpenHandle(this)->IsPublicSymbol();
3419 }
3420
IsArray() const3421 bool Value::IsArray() const { return Utils::OpenHandle(this)->IsJSArray(); }
3422
IsArrayBuffer() const3423 bool Value::IsArrayBuffer() const {
3424 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3425 return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared();
3426 }
3427
IsArrayBufferView() const3428 bool Value::IsArrayBufferView() const {
3429 return Utils::OpenHandle(this)->IsJSArrayBufferView();
3430 }
3431
IsTypedArray() const3432 bool Value::IsTypedArray() const {
3433 return Utils::OpenHandle(this)->IsJSTypedArray();
3434 }
3435
3436 #define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype) \
3437 bool Value::Is##Type##Array() const { \
3438 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3439 return obj->IsJSTypedArray() && \
3440 i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array; \
3441 }
3442
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)3443 TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
3444
3445 #undef VALUE_IS_TYPED_ARRAY
3446
3447 bool Value::IsDataView() const {
3448 return Utils::OpenHandle(this)->IsJSDataView();
3449 }
3450
IsSharedArrayBuffer() const3451 bool Value::IsSharedArrayBuffer() const {
3452 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3453 return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared();
3454 }
3455
IsObject() const3456 bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
3457
IsNumber() const3458 bool Value::IsNumber() const { return Utils::OpenHandle(this)->IsNumber(); }
3459
IsBigInt() const3460 bool Value::IsBigInt() const { return Utils::OpenHandle(this)->IsBigInt(); }
3461
IsProxy() const3462 bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
3463
3464 #define VALUE_IS_SPECIFIC_TYPE(Type, Check) \
3465 bool Value::Is##Type() const { \
3466 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
3467 return obj->Is##Check(); \
3468 }
3469
VALUE_IS_SPECIFIC_TYPE(ArgumentsObject,JSArgumentsObject)3470 VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, JSArgumentsObject)
3471 VALUE_IS_SPECIFIC_TYPE(BigIntObject, BigIntWrapper)
3472 VALUE_IS_SPECIFIC_TYPE(BooleanObject, BooleanWrapper)
3473 VALUE_IS_SPECIFIC_TYPE(NumberObject, NumberWrapper)
3474 VALUE_IS_SPECIFIC_TYPE(StringObject, StringWrapper)
3475 VALUE_IS_SPECIFIC_TYPE(SymbolObject, SymbolWrapper)
3476 VALUE_IS_SPECIFIC_TYPE(Date, JSDate)
3477 VALUE_IS_SPECIFIC_TYPE(Map, JSMap)
3478 VALUE_IS_SPECIFIC_TYPE(Set, JSSet)
3479 VALUE_IS_SPECIFIC_TYPE(WasmModuleObject, WasmModuleObject)
3480 VALUE_IS_SPECIFIC_TYPE(WeakMap, JSWeakMap)
3481 VALUE_IS_SPECIFIC_TYPE(WeakSet, JSWeakSet)
3482
3483 #undef VALUE_IS_SPECIFIC_TYPE
3484
3485 bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
3486
IsExternal() const3487 bool Value::IsExternal() const {
3488 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3489 if (!obj->IsHeapObject()) return false;
3490 i::Handle<i::HeapObject> heap_obj = i::Handle<i::HeapObject>::cast(obj);
3491 // Check the instance type is JS_OBJECT (instance type of Externals) before
3492 // attempting to get the Isolate since that guarantees the object is writable
3493 // and GetIsolate will work.
3494 if (heap_obj->map().instance_type() != i::JS_OBJECT_TYPE) return false;
3495 i::Isolate* isolate = i::JSObject::cast(*heap_obj).GetIsolate();
3496 return heap_obj->IsExternal(isolate);
3497 }
3498
IsInt32() const3499 bool Value::IsInt32() const {
3500 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3501 if (obj->IsSmi()) return true;
3502 if (obj->IsNumber()) {
3503 return i::IsInt32Double(obj->Number());
3504 }
3505 return false;
3506 }
3507
IsUint32() const3508 bool Value::IsUint32() const {
3509 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3510 if (obj->IsSmi()) return i::Smi::ToInt(*obj) >= 0;
3511 if (obj->IsNumber()) {
3512 double value = obj->Number();
3513 return !i::IsMinusZero(value) && value >= 0 && value <= i::kMaxUInt32 &&
3514 value == i::FastUI2D(i::FastD2UI(value));
3515 }
3516 return false;
3517 }
3518
IsNativeError() const3519 bool Value::IsNativeError() const {
3520 return Utils::OpenHandle(this)->IsJSError();
3521 }
3522
IsRegExp() const3523 bool Value::IsRegExp() const {
3524 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3525 return obj->IsJSRegExp();
3526 }
3527
IsAsyncFunction() const3528 bool Value::IsAsyncFunction() const {
3529 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3530 if (!obj->IsJSFunction()) return false;
3531 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3532 return i::IsAsyncFunction(func->shared().kind());
3533 }
3534
IsGeneratorFunction() const3535 bool Value::IsGeneratorFunction() const {
3536 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3537 if (!obj->IsJSFunction()) return false;
3538 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
3539 return i::IsGeneratorFunction(func->shared().kind());
3540 }
3541
IsGeneratorObject() const3542 bool Value::IsGeneratorObject() const {
3543 return Utils::OpenHandle(this)->IsJSGeneratorObject();
3544 }
3545
IsMapIterator() const3546 bool Value::IsMapIterator() const {
3547 return Utils::OpenHandle(this)->IsJSMapIterator();
3548 }
3549
IsSetIterator() const3550 bool Value::IsSetIterator() const {
3551 return Utils::OpenHandle(this)->IsJSSetIterator();
3552 }
3553
IsPromise() const3554 bool Value::IsPromise() const { return Utils::OpenHandle(this)->IsJSPromise(); }
3555
IsModuleNamespaceObject() const3556 bool Value::IsModuleNamespaceObject() const {
3557 return Utils::OpenHandle(this)->IsJSModuleNamespace();
3558 }
3559
ToString(Local<Context> context) const3560 MaybeLocal<String> Value::ToString(Local<Context> context) const {
3561 auto obj = Utils::OpenHandle(this);
3562 if (obj->IsString()) return ToApiHandle<String>(obj);
3563 PREPARE_FOR_EXECUTION(context, Object, ToString, String);
3564 Local<String> result;
3565 has_pending_exception =
3566 !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
3567 RETURN_ON_FAILED_EXECUTION(String);
3568 RETURN_ESCAPED(result);
3569 }
3570
ToDetailString(Local<Context> context) const3571 MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
3572 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3573 if (obj->IsString()) return ToApiHandle<String>(obj);
3574 PREPARE_FOR_EXECUTION(context, Object, ToDetailString, String);
3575 Local<String> result =
3576 Utils::ToLocal(i::Object::NoSideEffectsToString(isolate, obj));
3577 RETURN_ON_FAILED_EXECUTION(String);
3578 RETURN_ESCAPED(result);
3579 }
3580
ToObject(Local<Context> context) const3581 MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3582 auto obj = Utils::OpenHandle(this);
3583 if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
3584 PREPARE_FOR_EXECUTION(context, Object, ToObject, Object);
3585 Local<Object> result;
3586 has_pending_exception =
3587 !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
3588 RETURN_ON_FAILED_EXECUTION(Object);
3589 RETURN_ESCAPED(result);
3590 }
3591
ToBigInt(Local<Context> context) const3592 MaybeLocal<BigInt> Value::ToBigInt(Local<Context> context) const {
3593 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3594 if (obj->IsBigInt()) return ToApiHandle<BigInt>(obj);
3595 PREPARE_FOR_EXECUTION(context, Object, ToBigInt, BigInt);
3596 Local<BigInt> result;
3597 has_pending_exception =
3598 !ToLocal<BigInt>(i::BigInt::FromObject(isolate, obj), &result);
3599 RETURN_ON_FAILED_EXECUTION(BigInt);
3600 RETURN_ESCAPED(result);
3601 }
3602
BooleanValue(Isolate * v8_isolate) const3603 bool Value::BooleanValue(Isolate* v8_isolate) const {
3604 return Utils::OpenHandle(this)->BooleanValue(
3605 reinterpret_cast<i::Isolate*>(v8_isolate));
3606 }
3607
ToBoolean(Isolate * v8_isolate) const3608 Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
3609 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
3610 return ToApiHandle<Boolean>(
3611 isolate->factory()->ToBoolean(BooleanValue(v8_isolate)));
3612 }
3613
ToNumber(Local<Context> context) const3614 MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3615 auto obj = Utils::OpenHandle(this);
3616 if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3617 PREPARE_FOR_EXECUTION(context, Object, ToNumber, Number);
3618 Local<Number> result;
3619 has_pending_exception =
3620 !ToLocal<Number>(i::Object::ToNumber(isolate, obj), &result);
3621 RETURN_ON_FAILED_EXECUTION(Number);
3622 RETURN_ESCAPED(result);
3623 }
3624
ToInteger(Local<Context> context) const3625 MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3626 auto obj = Utils::OpenHandle(this);
3627 if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3628 PREPARE_FOR_EXECUTION(context, Object, ToInteger, Integer);
3629 Local<Integer> result;
3630 has_pending_exception =
3631 !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3632 RETURN_ON_FAILED_EXECUTION(Integer);
3633 RETURN_ESCAPED(result);
3634 }
3635
ToInt32(Local<Context> context) const3636 MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3637 auto obj = Utils::OpenHandle(this);
3638 if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3639 Local<Int32> result;
3640 PREPARE_FOR_EXECUTION(context, Object, ToInt32, Int32);
3641 has_pending_exception =
3642 !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3643 RETURN_ON_FAILED_EXECUTION(Int32);
3644 RETURN_ESCAPED(result);
3645 }
3646
ToUint32(Local<Context> context) const3647 MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3648 auto obj = Utils::OpenHandle(this);
3649 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3650 Local<Uint32> result;
3651 PREPARE_FOR_EXECUTION(context, Object, ToUint32, Uint32);
3652 has_pending_exception =
3653 !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3654 RETURN_ON_FAILED_EXECUTION(Uint32);
3655 RETURN_ESCAPED(result);
3656 }
3657
DecodeExternalPointerImpl(const i::Isolate * isolate,i::ExternalPointer_t encoded_pointer,ExternalPointerTag tag)3658 i::Address i::DecodeExternalPointerImpl(const i::Isolate* isolate,
3659 i::ExternalPointer_t encoded_pointer,
3660 ExternalPointerTag tag) {
3661 return i::DecodeExternalPointer(isolate, encoded_pointer, tag);
3662 }
3663
IsolateFromNeverReadOnlySpaceObject(i::Address obj)3664 i::Isolate* i::IsolateFromNeverReadOnlySpaceObject(i::Address obj) {
3665 return i::GetIsolateFromWritableObject(i::HeapObject::cast(i::Object(obj)));
3666 }
3667
ShouldThrowOnError(i::Isolate * isolate)3668 bool i::ShouldThrowOnError(i::Isolate* isolate) {
3669 return i::GetShouldThrow(isolate, Nothing<i::ShouldThrow>()) ==
3670 i::ShouldThrow::kThrowOnError;
3671 }
3672
CheckInitializedImpl(v8::Isolate * external_isolate)3673 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3674 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3675 Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
3676 "v8::internal::Internals::CheckInitialized",
3677 "Isolate is not initialized or V8 has died");
3678 }
3679
CheckCast(Data * that)3680 void v8::Value::CheckCast(Data* that) {
3681 Utils::ApiCheck(that->IsValue(), "v8::Value::Cast", "Data is not a Value");
3682 }
3683
CheckCast(v8::Value * that)3684 void External::CheckCast(v8::Value* that) {
3685 Utils::ApiCheck(that->IsExternal(), "v8::External::Cast",
3686 "Value is not an External");
3687 }
3688
CheckCast(Value * that)3689 void v8::Object::CheckCast(Value* that) {
3690 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3691 Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast",
3692 "Value is not an Object");
3693 }
3694
CheckCast(Value * that)3695 void v8::Function::CheckCast(Value* that) {
3696 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3697 Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast",
3698 "Value is not a Function");
3699 }
3700
CheckCast(v8::Value * that)3701 void v8::Boolean::CheckCast(v8::Value* that) {
3702 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3703 Utils::ApiCheck(obj->IsBoolean(), "v8::Boolean::Cast",
3704 "Value is not a Boolean");
3705 }
3706
CheckCast(v8::Value * that)3707 void v8::Name::CheckCast(v8::Value* that) {
3708 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3709 Utils::ApiCheck(obj->IsName(), "v8::Name::Cast", "Value is not a Name");
3710 }
3711
CheckCast(v8::Value * that)3712 void v8::String::CheckCast(v8::Value* that) {
3713 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3714 Utils::ApiCheck(obj->IsString(), "v8::String::Cast", "Value is not a String");
3715 }
3716
CheckCast(v8::Value * that)3717 void v8::Symbol::CheckCast(v8::Value* that) {
3718 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3719 Utils::ApiCheck(obj->IsSymbol(), "v8::Symbol::Cast", "Value is not a Symbol");
3720 }
3721
CheckCast(v8::Data * that)3722 void v8::Private::CheckCast(v8::Data* that) {
3723 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3724 Utils::ApiCheck(
3725 obj->IsSymbol() && i::Handle<i::Symbol>::cast(obj)->is_private(),
3726 "v8::Private::Cast", "Value is not a Private");
3727 }
3728
CheckCast(v8::Data * that)3729 void v8::Module::CheckCast(v8::Data* that) {
3730 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3731 Utils::ApiCheck(obj->IsModule(), "v8::Module::Cast", "Value is not a Module");
3732 }
3733
CheckCast(v8::Value * that)3734 void v8::Number::CheckCast(v8::Value* that) {
3735 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3736 Utils::ApiCheck(obj->IsNumber(), "v8::Number::Cast()",
3737 "Value is not a Number");
3738 }
3739
CheckCast(v8::Value * that)3740 void v8::Integer::CheckCast(v8::Value* that) {
3741 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3742 Utils::ApiCheck(obj->IsNumber(), "v8::Integer::Cast",
3743 "Value is not an Integer");
3744 }
3745
CheckCast(v8::Value * that)3746 void v8::Int32::CheckCast(v8::Value* that) {
3747 Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast",
3748 "Value is not a 32-bit signed integer");
3749 }
3750
CheckCast(v8::Value * that)3751 void v8::Uint32::CheckCast(v8::Value* that) {
3752 Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast",
3753 "Value is not a 32-bit unsigned integer");
3754 }
3755
CheckCast(v8::Value * that)3756 void v8::BigInt::CheckCast(v8::Value* that) {
3757 Utils::ApiCheck(that->IsBigInt(), "v8::BigInt::Cast",
3758 "Value is not a BigInt");
3759 }
3760
CheckCast(Value * that)3761 void v8::Array::CheckCast(Value* that) {
3762 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3763 Utils::ApiCheck(obj->IsJSArray(), "v8::Array::Cast", "Value is not an Array");
3764 }
3765
CheckCast(Value * that)3766 void v8::Map::CheckCast(Value* that) {
3767 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3768 Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast", "Value is not a Map");
3769 }
3770
CheckCast(Value * that)3771 void v8::Set::CheckCast(Value* that) {
3772 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3773 Utils::ApiCheck(obj->IsJSSet(), "v8_Set_Cast", "Value is not a Set");
3774 }
3775
CheckCast(Value * that)3776 void v8::Promise::CheckCast(Value* that) {
3777 Utils::ApiCheck(that->IsPromise(), "v8::Promise::Cast",
3778 "Value is not a Promise");
3779 }
3780
CheckCast(Value * that)3781 void v8::Promise::Resolver::CheckCast(Value* that) {
3782 Utils::ApiCheck(that->IsPromise(), "v8::Promise::Resolver::Cast",
3783 "Value is not a Promise::Resolver");
3784 }
3785
CheckCast(Value * that)3786 void v8::Proxy::CheckCast(Value* that) {
3787 Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast", "Value is not a Proxy");
3788 }
3789
CheckCast(Value * that)3790 void v8::WasmModuleObject::CheckCast(Value* that) {
3791 Utils::ApiCheck(that->IsWasmModuleObject(), "v8::WasmModuleObject::Cast",
3792 "Value is not a WasmModuleObject");
3793 }
3794
CheckCast(Value * that)3795 void v8::debug::AccessorPair::CheckCast(Value* that) {
3796 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3797 Utils::ApiCheck(obj->IsAccessorPair(), "v8::AccessorPair::Cast",
3798 "Value is not a debug::AccessorPair");
3799 }
3800
CheckCast(Value * that)3801 void v8::debug::WasmValue::CheckCast(Value* that) {
3802 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3803 Utils::ApiCheck(obj->IsWasmValue(), "v8::WasmValue::Cast",
3804 "Value is not a debug::WasmValue");
3805 }
3806
~BackingStore()3807 v8::BackingStore::~BackingStore() {
3808 auto i_this = reinterpret_cast<const i::BackingStore*>(this);
3809 i_this->~BackingStore(); // manually call internal destructor
3810 }
3811
Data() const3812 void* v8::BackingStore::Data() const {
3813 return reinterpret_cast<const i::BackingStore*>(this)->buffer_start();
3814 }
3815
ByteLength() const3816 size_t v8::BackingStore::ByteLength() const {
3817 return reinterpret_cast<const i::BackingStore*>(this)->byte_length();
3818 }
3819
IsShared() const3820 bool v8::BackingStore::IsShared() const {
3821 return reinterpret_cast<const i::BackingStore*>(this)->is_shared();
3822 }
3823
3824 // static
Reallocate(v8::Isolate * isolate,std::unique_ptr<v8::BackingStore> backing_store,size_t byte_length)3825 std::unique_ptr<v8::BackingStore> v8::BackingStore::Reallocate(
3826 v8::Isolate* isolate, std::unique_ptr<v8::BackingStore> backing_store,
3827 size_t byte_length) {
3828 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
3829 LOG_API(i_isolate, ArrayBuffer, BackingStore_Reallocate);
3830 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
3831 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
3832 i::BackingStore* i_backing_store =
3833 reinterpret_cast<i::BackingStore*>(backing_store.get());
3834 if (!i_backing_store->Reallocate(i_isolate, byte_length)) {
3835 i::FatalProcessOutOfMemory(i_isolate, "v8::BackingStore::Reallocate");
3836 }
3837 return backing_store;
3838 }
3839
3840 // static
EmptyDeleter(void * data,size_t length,void * deleter_data)3841 void v8::BackingStore::EmptyDeleter(void* data, size_t length,
3842 void* deleter_data) {
3843 DCHECK_NULL(deleter_data);
3844 }
3845
GetBackingStore()3846 std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() {
3847 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
3848 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
3849 if (!backing_store) {
3850 backing_store =
3851 i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared);
3852 }
3853 i::GlobalBackingStoreRegistry::Register(backing_store);
3854 std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
3855 return std::static_pointer_cast<v8::BackingStore>(bs_base);
3856 }
3857
GetBackingStore()3858 std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() {
3859 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
3860 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
3861 if (!backing_store) {
3862 backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared);
3863 }
3864 i::GlobalBackingStoreRegistry::Register(backing_store);
3865 std::shared_ptr<i::BackingStoreBase> bs_base = backing_store;
3866 return std::static_pointer_cast<v8::BackingStore>(bs_base);
3867 }
3868
CheckCast(Value * that)3869 void v8::ArrayBuffer::CheckCast(Value* that) {
3870 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3871 Utils::ApiCheck(
3872 obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj).is_shared(),
3873 "v8::ArrayBuffer::Cast()", "Value is not an ArrayBuffer");
3874 }
3875
CheckCast(Value * that)3876 void v8::ArrayBufferView::CheckCast(Value* that) {
3877 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3878 Utils::ApiCheck(obj->IsJSArrayBufferView(), "v8::ArrayBufferView::Cast()",
3879 "Value is not an ArrayBufferView");
3880 }
3881
3882 constexpr size_t v8::TypedArray::kMaxLength;
3883
CheckCast(Value * that)3884 void v8::TypedArray::CheckCast(Value* that) {
3885 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3886 Utils::ApiCheck(obj->IsJSTypedArray(), "v8::TypedArray::Cast()",
3887 "Value is not a TypedArray");
3888 }
3889
3890 #define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype) \
3891 void v8::Type##Array::CheckCast(Value* that) { \
3892 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
3893 Utils::ApiCheck( \
3894 obj->IsJSTypedArray() && \
3895 i::JSTypedArray::cast(*obj).type() == i::kExternal##Type##Array, \
3896 "v8::" #Type "Array::Cast()", "Value is not a " #Type "Array"); \
3897 }
3898
TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)3899 TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
3900
3901 #undef CHECK_TYPED_ARRAY_CAST
3902
3903 void v8::DataView::CheckCast(Value* that) {
3904 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3905 Utils::ApiCheck(obj->IsJSDataView(), "v8::DataView::Cast()",
3906 "Value is not a DataView");
3907 }
3908
CheckCast(Value * that)3909 void v8::SharedArrayBuffer::CheckCast(Value* that) {
3910 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3911 Utils::ApiCheck(
3912 obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj).is_shared(),
3913 "v8::SharedArrayBuffer::Cast()", "Value is not a SharedArrayBuffer");
3914 }
3915
CheckCast(v8::Value * that)3916 void v8::Date::CheckCast(v8::Value* that) {
3917 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3918 Utils::ApiCheck(obj->IsJSDate(), "v8::Date::Cast()", "Value is not a Date");
3919 }
3920
CheckCast(v8::Value * that)3921 void v8::StringObject::CheckCast(v8::Value* that) {
3922 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3923 Utils::ApiCheck(obj->IsStringWrapper(), "v8::StringObject::Cast()",
3924 "Value is not a StringObject");
3925 }
3926
CheckCast(v8::Value * that)3927 void v8::SymbolObject::CheckCast(v8::Value* that) {
3928 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3929 Utils::ApiCheck(obj->IsSymbolWrapper(), "v8::SymbolObject::Cast()",
3930 "Value is not a SymbolObject");
3931 }
3932
CheckCast(v8::Value * that)3933 void v8::NumberObject::CheckCast(v8::Value* that) {
3934 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3935 Utils::ApiCheck(obj->IsNumberWrapper(), "v8::NumberObject::Cast()",
3936 "Value is not a NumberObject");
3937 }
3938
CheckCast(v8::Value * that)3939 void v8::BigIntObject::CheckCast(v8::Value* that) {
3940 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3941 Utils::ApiCheck(obj->IsBigIntWrapper(), "v8::BigIntObject::Cast()",
3942 "Value is not a BigIntObject");
3943 }
3944
CheckCast(v8::Value * that)3945 void v8::BooleanObject::CheckCast(v8::Value* that) {
3946 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3947 Utils::ApiCheck(obj->IsBooleanWrapper(), "v8::BooleanObject::Cast()",
3948 "Value is not a BooleanObject");
3949 }
3950
CheckCast(v8::Value * that)3951 void v8::RegExp::CheckCast(v8::Value* that) {
3952 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3953 Utils::ApiCheck(obj->IsJSRegExp(), "v8::RegExp::Cast()",
3954 "Value is not a RegExp");
3955 }
3956
NumberValue(Local<Context> context) const3957 Maybe<double> Value::NumberValue(Local<Context> context) const {
3958 auto obj = Utils::OpenHandle(this);
3959 if (obj->IsNumber()) return Just(obj->Number());
3960 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3961 ENTER_V8(isolate, context, Value, NumberValue, Nothing<double>(),
3962 i::HandleScope);
3963 i::Handle<i::Object> num;
3964 has_pending_exception = !i::Object::ToNumber(isolate, obj).ToHandle(&num);
3965 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
3966 return Just(num->Number());
3967 }
3968
IntegerValue(Local<Context> context) const3969 Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
3970 auto obj = Utils::OpenHandle(this);
3971 if (obj->IsNumber()) {
3972 return Just(NumberToInt64(*obj));
3973 }
3974 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3975 ENTER_V8(isolate, context, Value, IntegerValue, Nothing<int64_t>(),
3976 i::HandleScope);
3977 i::Handle<i::Object> num;
3978 has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
3979 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
3980 return Just(NumberToInt64(*num));
3981 }
3982
Int32Value(Local<Context> context) const3983 Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
3984 auto obj = Utils::OpenHandle(this);
3985 if (obj->IsNumber()) return Just(NumberToInt32(*obj));
3986 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3987 ENTER_V8(isolate, context, Value, Int32Value, Nothing<int32_t>(),
3988 i::HandleScope);
3989 i::Handle<i::Object> num;
3990 has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
3991 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
3992 return Just(num->IsSmi() ? i::Smi::ToInt(*num)
3993 : static_cast<int32_t>(num->Number()));
3994 }
3995
Uint32Value(Local<Context> context) const3996 Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
3997 auto obj = Utils::OpenHandle(this);
3998 if (obj->IsNumber()) return Just(NumberToUint32(*obj));
3999 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4000 ENTER_V8(isolate, context, Value, Uint32Value, Nothing<uint32_t>(),
4001 i::HandleScope);
4002 i::Handle<i::Object> num;
4003 has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
4004 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
4005 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::ToInt(*num))
4006 : static_cast<uint32_t>(num->Number()));
4007 }
4008
ToArrayIndex(Local<Context> context) const4009 MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
4010 auto self = Utils::OpenHandle(this);
4011 if (self->IsSmi()) {
4012 if (i::Smi::ToInt(*self) >= 0) return Utils::Uint32ToLocal(self);
4013 return Local<Uint32>();
4014 }
4015 PREPARE_FOR_EXECUTION(context, Object, ToArrayIndex, Uint32);
4016 i::Handle<i::Object> string_obj;
4017 has_pending_exception =
4018 !i::Object::ToString(isolate, self).ToHandle(&string_obj);
4019 RETURN_ON_FAILED_EXECUTION(Uint32);
4020 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
4021 uint32_t index;
4022 if (str->AsArrayIndex(&index)) {
4023 i::Handle<i::Object> value;
4024 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
4025 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
4026 } else {
4027 value = isolate->factory()->NewNumber(index);
4028 }
4029 RETURN_ESCAPED(Utils::Uint32ToLocal(value));
4030 }
4031 return Local<Uint32>();
4032 }
4033
Equals(Local<Context> context,Local<Value> that) const4034 Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
4035 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4036 auto self = Utils::OpenHandle(this);
4037 auto other = Utils::OpenHandle(*that);
4038 return i::Object::Equals(isolate, self, other);
4039 }
4040
StrictEquals(Local<Value> that) const4041 bool Value::StrictEquals(Local<Value> that) const {
4042 auto self = Utils::OpenHandle(this);
4043 auto other = Utils::OpenHandle(*that);
4044 return self->StrictEquals(*other);
4045 }
4046
SameValue(Local<Value> that) const4047 bool Value::SameValue(Local<Value> that) const {
4048 auto self = Utils::OpenHandle(this);
4049 auto other = Utils::OpenHandle(*that);
4050 return self->SameValue(*other);
4051 }
4052
TypeOf(v8::Isolate * external_isolate)4053 Local<String> Value::TypeOf(v8::Isolate* external_isolate) {
4054 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
4055 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4056 LOG_API(isolate, Value, TypeOf);
4057 return Utils::ToLocal(i::Object::TypeOf(isolate, Utils::OpenHandle(this)));
4058 }
4059
InstanceOf(v8::Local<v8::Context> context,v8::Local<v8::Object> object)4060 Maybe<bool> Value::InstanceOf(v8::Local<v8::Context> context,
4061 v8::Local<v8::Object> object) {
4062 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4063 ENTER_V8(isolate, context, Value, InstanceOf, Nothing<bool>(),
4064 i::HandleScope);
4065 auto left = Utils::OpenHandle(this);
4066 auto right = Utils::OpenHandle(*object);
4067 i::Handle<i::Object> result;
4068 has_pending_exception =
4069 !i::Object::InstanceOf(isolate, left, right).ToHandle(&result);
4070 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4071 return Just(result->IsTrue(isolate));
4072 }
4073
Set(v8::Local<v8::Context> context,v8::Local<Value> key,v8::Local<Value> value)4074 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
4075 v8::Local<Value> key, v8::Local<Value> value) {
4076 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4077 ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4078 auto self = Utils::OpenHandle(this);
4079 auto key_obj = Utils::OpenHandle(*key);
4080 auto value_obj = Utils::OpenHandle(*value);
4081 has_pending_exception =
4082 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
4083 i::StoreOrigin::kMaybeKeyed,
4084 Just(i::ShouldThrow::kDontThrow))
4085 .is_null();
4086 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4087 return Just(true);
4088 }
4089
Set(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4090 Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
4091 v8::Local<Value> value) {
4092 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4093 ENTER_V8(isolate, context, Object, Set, Nothing<bool>(), i::HandleScope);
4094 auto self = Utils::OpenHandle(this);
4095 auto value_obj = Utils::OpenHandle(*value);
4096 has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
4097 i::ShouldThrow::kDontThrow)
4098 .is_null();
4099 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4100 return Just(true);
4101 }
4102
CreateDataProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value)4103 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4104 v8::Local<Name> key,
4105 v8::Local<Value> value) {
4106 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4107 ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4108 i::HandleScope);
4109 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4110 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4111 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4112
4113 Maybe<bool> result = i::JSReceiver::CreateDataProperty(
4114 isolate, self, key_obj, value_obj, Just(i::kDontThrow));
4115 has_pending_exception = result.IsNothing();
4116 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4117 return result;
4118 }
4119
CreateDataProperty(v8::Local<v8::Context> context,uint32_t index,v8::Local<Value> value)4120 Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
4121 uint32_t index,
4122 v8::Local<Value> value) {
4123 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4124 ENTER_V8(isolate, context, Object, CreateDataProperty, Nothing<bool>(),
4125 i::HandleScope);
4126 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4127 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4128
4129 i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
4130 Maybe<bool> result =
4131 i::JSReceiver::CreateDataProperty(&it, value_obj, Just(i::kDontThrow));
4132 has_pending_exception = result.IsNothing();
4133 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4134 return result;
4135 }
4136
4137 struct v8::PropertyDescriptor::PrivateData {
PrivateDatav8::v8::PropertyDescriptor::PrivateData4138 PrivateData() : desc() {}
4139 i::PropertyDescriptor desc;
4140 };
4141
PropertyDescriptor()4142 v8::PropertyDescriptor::PropertyDescriptor() : private_(new PrivateData()) {}
4143
4144 // DataDescriptor
PropertyDescriptor(v8::Local<v8::Value> value)4145 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value)
4146 : private_(new PrivateData()) {
4147 private_->desc.set_value(Utils::OpenHandle(*value, true));
4148 }
4149
4150 // DataDescriptor with writable field
PropertyDescriptor(v8::Local<v8::Value> value,bool writable)4151 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> value,
4152 bool writable)
4153 : private_(new PrivateData()) {
4154 private_->desc.set_value(Utils::OpenHandle(*value, true));
4155 private_->desc.set_writable(writable);
4156 }
4157
4158 // AccessorDescriptor
PropertyDescriptor(v8::Local<v8::Value> get,v8::Local<v8::Value> set)4159 v8::PropertyDescriptor::PropertyDescriptor(v8::Local<v8::Value> get,
4160 v8::Local<v8::Value> set)
4161 : private_(new PrivateData()) {
4162 DCHECK(get.IsEmpty() || get->IsUndefined() || get->IsFunction());
4163 DCHECK(set.IsEmpty() || set->IsUndefined() || set->IsFunction());
4164 private_->desc.set_get(Utils::OpenHandle(*get, true));
4165 private_->desc.set_set(Utils::OpenHandle(*set, true));
4166 }
4167
~PropertyDescriptor()4168 v8::PropertyDescriptor::~PropertyDescriptor() { delete private_; }
4169
value() const4170 v8::Local<Value> v8::PropertyDescriptor::value() const {
4171 DCHECK(private_->desc.has_value());
4172 return Utils::ToLocal(private_->desc.value());
4173 }
4174
get() const4175 v8::Local<Value> v8::PropertyDescriptor::get() const {
4176 DCHECK(private_->desc.has_get());
4177 return Utils::ToLocal(private_->desc.get());
4178 }
4179
set() const4180 v8::Local<Value> v8::PropertyDescriptor::set() const {
4181 DCHECK(private_->desc.has_set());
4182 return Utils::ToLocal(private_->desc.set());
4183 }
4184
has_value() const4185 bool v8::PropertyDescriptor::has_value() const {
4186 return private_->desc.has_value();
4187 }
has_get() const4188 bool v8::PropertyDescriptor::has_get() const {
4189 return private_->desc.has_get();
4190 }
has_set() const4191 bool v8::PropertyDescriptor::has_set() const {
4192 return private_->desc.has_set();
4193 }
4194
writable() const4195 bool v8::PropertyDescriptor::writable() const {
4196 DCHECK(private_->desc.has_writable());
4197 return private_->desc.writable();
4198 }
4199
has_writable() const4200 bool v8::PropertyDescriptor::has_writable() const {
4201 return private_->desc.has_writable();
4202 }
4203
set_enumerable(bool enumerable)4204 void v8::PropertyDescriptor::set_enumerable(bool enumerable) {
4205 private_->desc.set_enumerable(enumerable);
4206 }
4207
enumerable() const4208 bool v8::PropertyDescriptor::enumerable() const {
4209 DCHECK(private_->desc.has_enumerable());
4210 return private_->desc.enumerable();
4211 }
4212
has_enumerable() const4213 bool v8::PropertyDescriptor::has_enumerable() const {
4214 return private_->desc.has_enumerable();
4215 }
4216
set_configurable(bool configurable)4217 void v8::PropertyDescriptor::set_configurable(bool configurable) {
4218 private_->desc.set_configurable(configurable);
4219 }
4220
configurable() const4221 bool v8::PropertyDescriptor::configurable() const {
4222 DCHECK(private_->desc.has_configurable());
4223 return private_->desc.configurable();
4224 }
4225
has_configurable() const4226 bool v8::PropertyDescriptor::has_configurable() const {
4227 return private_->desc.has_configurable();
4228 }
4229
DefineOwnProperty(v8::Local<v8::Context> context,v8::Local<Name> key,v8::Local<Value> value,v8::PropertyAttribute attributes)4230 Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
4231 v8::Local<Name> key,
4232 v8::Local<Value> value,
4233 v8::PropertyAttribute attributes) {
4234 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4235 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4236 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4237 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
4238
4239 i::PropertyDescriptor desc;
4240 desc.set_writable(!(attributes & v8::ReadOnly));
4241 desc.set_enumerable(!(attributes & v8::DontEnum));
4242 desc.set_configurable(!(attributes & v8::DontDelete));
4243 desc.set_value(value_obj);
4244
4245 if (self->IsJSProxy()) {
4246 ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4247 i::HandleScope);
4248 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4249 isolate, self, key_obj, &desc, Just(i::kDontThrow));
4250 // Even though we said kDontThrow, there might be accessors that do throw.
4251 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4252 return success;
4253 } else {
4254 // If it's not a JSProxy, i::JSReceiver::DefineOwnProperty should never run
4255 // a script.
4256 ENTER_V8_NO_SCRIPT(isolate, context, Object, DefineOwnProperty,
4257 Nothing<bool>(), i::HandleScope);
4258 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4259 isolate, self, key_obj, &desc, Just(i::kDontThrow));
4260 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4261 return success;
4262 }
4263 }
4264
DefineProperty(v8::Local<v8::Context> context,v8::Local<Name> key,PropertyDescriptor & descriptor)4265 Maybe<bool> v8::Object::DefineProperty(v8::Local<v8::Context> context,
4266 v8::Local<Name> key,
4267 PropertyDescriptor& descriptor) {
4268 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4269 ENTER_V8(isolate, context, Object, DefineOwnProperty, Nothing<bool>(),
4270 i::HandleScope);
4271 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4272 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4273
4274 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
4275 isolate, self, key_obj, &descriptor.get_private()->desc,
4276 Just(i::kDontThrow));
4277 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4278 return success;
4279 }
4280
SetPrivate(Local<Context> context,Local<Private> key,Local<Value> value)4281 Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
4282 Local<Value> value) {
4283 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4284 ENTER_V8_NO_SCRIPT(isolate, context, Object, SetPrivate, Nothing<bool>(),
4285 i::HandleScope);
4286 auto self = Utils::OpenHandle(this);
4287 auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
4288 auto value_obj = Utils::OpenHandle(*value);
4289 if (self->IsJSProxy()) {
4290 i::PropertyDescriptor desc;
4291 desc.set_writable(true);
4292 desc.set_enumerable(false);
4293 desc.set_configurable(true);
4294 desc.set_value(value_obj);
4295 return i::JSProxy::SetPrivateSymbol(
4296 isolate, i::Handle<i::JSProxy>::cast(self),
4297 i::Handle<i::Symbol>::cast(key_obj), &desc, Just(i::kDontThrow));
4298 }
4299 auto js_object = i::Handle<i::JSObject>::cast(self);
4300 i::LookupIterator it(isolate, js_object, key_obj, js_object);
4301 has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
4302 &it, value_obj, i::DONT_ENUM)
4303 .is_null();
4304 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4305 return Just(true);
4306 }
4307
Get(Local<v8::Context> context,Local<Value> key)4308 MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
4309 Local<Value> key) {
4310 PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4311 auto self = Utils::OpenHandle(this);
4312 auto key_obj = Utils::OpenHandle(*key);
4313 i::Handle<i::Object> result;
4314 has_pending_exception =
4315 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
4316 RETURN_ON_FAILED_EXECUTION(Value);
4317 RETURN_ESCAPED(Utils::ToLocal(result));
4318 }
4319
Get(Local<Context> context,uint32_t index)4320 MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
4321 PREPARE_FOR_EXECUTION(context, Object, Get, Value);
4322 auto self = Utils::OpenHandle(this);
4323 i::Handle<i::Object> result;
4324 has_pending_exception =
4325 !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
4326 RETURN_ON_FAILED_EXECUTION(Value);
4327 RETURN_ESCAPED(Utils::ToLocal(result));
4328 }
4329
GetPrivate(Local<Context> context,Local<Private> key)4330 MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
4331 Local<Private> key) {
4332 return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
4333 }
4334
GetPropertyAttributes(Local<Context> context,Local<Value> key)4335 Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
4336 Local<Context> context, Local<Value> key) {
4337 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4338 ENTER_V8(isolate, context, Object, GetPropertyAttributes,
4339 Nothing<PropertyAttribute>(), i::HandleScope);
4340 auto self = Utils::OpenHandle(this);
4341 auto key_obj = Utils::OpenHandle(*key);
4342 if (!key_obj->IsName()) {
4343 has_pending_exception =
4344 !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
4345 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4346 }
4347 auto key_name = i::Handle<i::Name>::cast(key_obj);
4348 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
4349 has_pending_exception = result.IsNothing();
4350 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4351 if (result.FromJust() == i::ABSENT) {
4352 return Just(static_cast<PropertyAttribute>(i::NONE));
4353 }
4354 return Just(static_cast<PropertyAttribute>(result.FromJust()));
4355 }
4356
GetOwnPropertyDescriptor(Local<Context> context,Local<Name> key)4357 MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
4358 Local<Name> key) {
4359 PREPARE_FOR_EXECUTION(context, Object, GetOwnPropertyDescriptor, Value);
4360 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
4361 i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
4362
4363 i::PropertyDescriptor desc;
4364 Maybe<bool> found =
4365 i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
4366 has_pending_exception = found.IsNothing();
4367 RETURN_ON_FAILED_EXECUTION(Value);
4368 if (!found.FromJust()) {
4369 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
4370 }
4371 RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
4372 }
4373
GetPrototype()4374 Local<Value> v8::Object::GetPrototype() {
4375 auto self = Utils::OpenHandle(this);
4376 auto isolate = self->GetIsolate();
4377 i::PrototypeIterator iter(isolate, self);
4378 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
4379 }
4380
SetPrototype(Local<Context> context,Local<Value> value)4381 Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
4382 Local<Value> value) {
4383 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4384 ENTER_V8(isolate, context, Object, SetPrototype, Nothing<bool>(),
4385 i::HandleScope);
4386 auto self = Utils::OpenHandle(this);
4387 auto value_obj = Utils::OpenHandle(*value);
4388 // We do not allow exceptions thrown while setting the prototype
4389 // to propagate outside.
4390 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
4391 auto result =
4392 i::JSReceiver::SetPrototype(self, value_obj, false, i::kThrowOnError);
4393 has_pending_exception = result.IsNothing();
4394 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4395 return Just(true);
4396 }
4397
FindInstanceInPrototypeChain(v8::Local<FunctionTemplate> tmpl)4398 Local<Object> v8::Object::FindInstanceInPrototypeChain(
4399 v8::Local<FunctionTemplate> tmpl) {
4400 auto self = Utils::OpenHandle(this);
4401 auto isolate = self->GetIsolate();
4402 i::PrototypeIterator iter(isolate, *self, i::kStartAtReceiver);
4403 auto tmpl_info = *Utils::OpenHandle(*tmpl);
4404 while (!tmpl_info.IsTemplateFor(iter.GetCurrent<i::JSObject>())) {
4405 iter.Advance();
4406 if (iter.IsAtEnd()) return Local<Object>();
4407 if (!iter.GetCurrent().IsJSObject()) return Local<Object>();
4408 }
4409 // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
4410 return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
4411 }
4412
GetPropertyNames(Local<Context> context)4413 MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
4414 return GetPropertyNames(
4415 context, v8::KeyCollectionMode::kIncludePrototypes,
4416 static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS),
4417 v8::IndexFilter::kIncludeIndices);
4418 }
4419
GetPropertyNames(Local<Context> context,KeyCollectionMode mode,PropertyFilter property_filter,IndexFilter index_filter,KeyConversionMode key_conversion)4420 MaybeLocal<Array> v8::Object::GetPropertyNames(
4421 Local<Context> context, KeyCollectionMode mode,
4422 PropertyFilter property_filter, IndexFilter index_filter,
4423 KeyConversionMode key_conversion) {
4424 PREPARE_FOR_EXECUTION(context, Object, GetPropertyNames, Array);
4425 auto self = Utils::OpenHandle(this);
4426 i::Handle<i::FixedArray> value;
4427 i::KeyAccumulator accumulator(
4428 isolate, static_cast<i::KeyCollectionMode>(mode),
4429 static_cast<i::PropertyFilter>(property_filter));
4430 accumulator.set_skip_indices(index_filter == IndexFilter::kSkipIndices);
4431 has_pending_exception = accumulator.CollectKeys(self, self).IsNothing();
4432 RETURN_ON_FAILED_EXECUTION(Array);
4433 value =
4434 accumulator.GetKeys(static_cast<i::GetKeysConversion>(key_conversion));
4435 DCHECK(self->map().EnumLength() == i::kInvalidEnumCacheSentinel ||
4436 self->map().EnumLength() == 0 ||
4437 self->map().instance_descriptors(kRelaxedLoad).enum_cache().keys() !=
4438 *value);
4439 auto result = isolate->factory()->NewJSArrayWithElements(value);
4440 RETURN_ESCAPED(Utils::ToLocal(result));
4441 }
4442
GetOwnPropertyNames(Local<Context> context)4443 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
4444 return GetOwnPropertyNames(
4445 context, static_cast<v8::PropertyFilter>(ONLY_ENUMERABLE | SKIP_SYMBOLS));
4446 }
4447
GetOwnPropertyNames(Local<Context> context,PropertyFilter filter,KeyConversionMode key_conversion)4448 MaybeLocal<Array> v8::Object::GetOwnPropertyNames(
4449 Local<Context> context, PropertyFilter filter,
4450 KeyConversionMode key_conversion) {
4451 return GetPropertyNames(context, KeyCollectionMode::kOwnOnly, filter,
4452 v8::IndexFilter::kIncludeIndices, key_conversion);
4453 }
4454
ObjectProtoToString(Local<Context> context)4455 MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
4456 PREPARE_FOR_EXECUTION(context, Object, ObjectProtoToString, String);
4457 auto self = Utils::OpenHandle(this);
4458 Local<Value> result;
4459 has_pending_exception = !ToLocal<Value>(
4460 i::Execution::CallBuiltin(isolate, isolate->object_to_string(), self, 0,
4461 nullptr),
4462 &result);
4463 RETURN_ON_FAILED_EXECUTION(String);
4464 RETURN_ESCAPED(Local<String>::Cast(result));
4465 }
4466
GetConstructorName()4467 Local<String> v8::Object::GetConstructorName() {
4468 auto self = Utils::OpenHandle(this);
4469 i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
4470 return Utils::ToLocal(name);
4471 }
4472
SetIntegrityLevel(Local<Context> context,IntegrityLevel level)4473 Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
4474 IntegrityLevel level) {
4475 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4476 ENTER_V8(isolate, context, Object, SetIntegrityLevel, Nothing<bool>(),
4477 i::HandleScope);
4478 auto self = Utils::OpenHandle(this);
4479 i::JSReceiver::IntegrityLevel i_level =
4480 level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
4481 Maybe<bool> result =
4482 i::JSReceiver::SetIntegrityLevel(self, i_level, i::kThrowOnError);
4483 has_pending_exception = result.IsNothing();
4484 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4485 return result;
4486 }
4487
Delete(Local<Context> context,Local<Value> key)4488 Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
4489 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4490 auto self = Utils::OpenHandle(this);
4491 auto key_obj = Utils::OpenHandle(*key);
4492 if (self->IsJSProxy()) {
4493 ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4494 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4495 isolate, self, key_obj, i::LanguageMode::kSloppy);
4496 has_pending_exception = result.IsNothing();
4497 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4498 return result;
4499 } else {
4500 // If it's not a JSProxy, i::Runtime::DeleteObjectProperty should never run
4501 // a script.
4502 ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4503 i::HandleScope);
4504 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4505 isolate, self, key_obj, i::LanguageMode::kSloppy);
4506 has_pending_exception = result.IsNothing();
4507 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4508 return result;
4509 }
4510 }
4511
DeletePrivate(Local<Context> context,Local<Private> key)4512 Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
4513 Local<Private> key) {
4514 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4515 // In case of private symbols, i::Runtime::DeleteObjectProperty does not run
4516 // any author script.
4517 ENTER_V8_NO_SCRIPT(isolate, context, Object, Delete, Nothing<bool>(),
4518 i::HandleScope);
4519 auto self = Utils::OpenHandle(this);
4520 auto key_obj = Utils::OpenHandle(*key);
4521 Maybe<bool> result = i::Runtime::DeleteObjectProperty(
4522 isolate, self, key_obj, i::LanguageMode::kSloppy);
4523 has_pending_exception = result.IsNothing();
4524 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4525 return result;
4526 }
4527
Has(Local<Context> context,Local<Value> key)4528 Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
4529 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4530 ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4531 auto self = Utils::OpenHandle(this);
4532 auto key_obj = Utils::OpenHandle(*key);
4533 Maybe<bool> maybe = Nothing<bool>();
4534 // Check if the given key is an array index.
4535 uint32_t index = 0;
4536 if (key_obj->ToArrayIndex(&index)) {
4537 maybe = i::JSReceiver::HasElement(self, index);
4538 } else {
4539 // Convert the key to a name - possibly by calling back into JavaScript.
4540 i::Handle<i::Name> name;
4541 if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
4542 maybe = i::JSReceiver::HasProperty(self, name);
4543 }
4544 }
4545 has_pending_exception = maybe.IsNothing();
4546 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4547 return maybe;
4548 }
4549
HasPrivate(Local<Context> context,Local<Private> key)4550 Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
4551 return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
4552 }
4553
Delete(Local<Context> context,uint32_t index)4554 Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
4555 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4556 ENTER_V8(isolate, context, Object, Delete, Nothing<bool>(), i::HandleScope);
4557 auto self = Utils::OpenHandle(this);
4558 Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
4559 has_pending_exception = result.IsNothing();
4560 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4561 return result;
4562 }
4563
Has(Local<Context> context,uint32_t index)4564 Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4565 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4566 ENTER_V8(isolate, context, Object, Has, Nothing<bool>(), i::HandleScope);
4567 auto self = Utils::OpenHandle(this);
4568 auto maybe = i::JSReceiver::HasElement(self, index);
4569 has_pending_exception = maybe.IsNothing();
4570 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4571 return maybe;
4572 }
4573
4574 template <typename Getter, typename Setter, typename Data>
ObjectSetAccessor(Local<Context> context,Object * self,Local<Name> name,Getter getter,Setter setter,Data data,AccessControl settings,PropertyAttribute attributes,bool is_special_data_property,bool replace_on_access,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4575 static Maybe<bool> ObjectSetAccessor(
4576 Local<Context> context, Object* self, Local<Name> name, Getter getter,
4577 Setter setter, Data data, AccessControl settings,
4578 PropertyAttribute attributes, bool is_special_data_property,
4579 bool replace_on_access, SideEffectType getter_side_effect_type,
4580 SideEffectType setter_side_effect_type) {
4581 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4582 ENTER_V8_NO_SCRIPT(isolate, context, Object, SetAccessor, Nothing<bool>(),
4583 i::HandleScope);
4584 if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4585 i::Handle<i::JSObject> obj =
4586 i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4587 v8::Local<AccessorSignature> signature;
4588 i::Handle<i::AccessorInfo> info =
4589 MakeAccessorInfo(isolate, name, getter, setter, data, settings, signature,
4590 is_special_data_property, replace_on_access);
4591 info->set_getter_side_effect_type(getter_side_effect_type);
4592 info->set_setter_side_effect_type(setter_side_effect_type);
4593 if (info.is_null()) return Nothing<bool>();
4594 bool fast = obj->HasFastProperties();
4595 i::Handle<i::Object> result;
4596
4597 i::Handle<i::Name> accessor_name(info->name(), isolate);
4598 i::PropertyAttributes attrs = static_cast<i::PropertyAttributes>(attributes);
4599 has_pending_exception =
4600 !i::JSObject::SetAccessor(obj, accessor_name, info, attrs)
4601 .ToHandle(&result);
4602 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4603 if (result->IsUndefined(isolate)) return Just(false);
4604 if (fast) {
4605 i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
4606 }
4607 return Just(true);
4608 }
4609
SetAccessor(Local<Context> context,Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,MaybeLocal<Value> data,AccessControl settings,PropertyAttribute attribute,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4610 Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4611 AccessorNameGetterCallback getter,
4612 AccessorNameSetterCallback setter,
4613 MaybeLocal<Value> data, AccessControl settings,
4614 PropertyAttribute attribute,
4615 SideEffectType getter_side_effect_type,
4616 SideEffectType setter_side_effect_type) {
4617 return ObjectSetAccessor(context, this, name, getter, setter,
4618 data.FromMaybe(Local<Value>()), settings, attribute,
4619 i::FLAG_disable_old_api_accessors, false,
4620 getter_side_effect_type, setter_side_effect_type);
4621 }
4622
SetAccessorProperty(Local<Name> name,Local<Function> getter,Local<Function> setter,PropertyAttribute attribute,AccessControl settings)4623 void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4624 Local<Function> setter,
4625 PropertyAttribute attribute,
4626 AccessControl settings) {
4627 // TODO(verwaest): Remove |settings|.
4628 DCHECK_EQ(v8::DEFAULT, settings);
4629 auto self = Utils::OpenHandle(this);
4630 i::Isolate* isolate = self->GetIsolate();
4631 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4632 i::HandleScope scope(isolate);
4633 if (!self->IsJSObject()) return;
4634 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4635 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4636 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
4637 i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4638 v8::Utils::OpenHandle(*name), getter_i, setter_i,
4639 static_cast<i::PropertyAttributes>(attribute));
4640 }
4641
SetNativeDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,AccessorNameSetterCallback setter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4642 Maybe<bool> Object::SetNativeDataProperty(
4643 v8::Local<v8::Context> context, v8::Local<Name> name,
4644 AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
4645 v8::Local<Value> data, PropertyAttribute attributes,
4646 SideEffectType getter_side_effect_type,
4647 SideEffectType setter_side_effect_type) {
4648 return ObjectSetAccessor(context, this, name, getter, setter, data, DEFAULT,
4649 attributes, true, false, getter_side_effect_type,
4650 setter_side_effect_type);
4651 }
4652
SetLazyDataProperty(v8::Local<v8::Context> context,v8::Local<Name> name,AccessorNameGetterCallback getter,v8::Local<Value> data,PropertyAttribute attributes,SideEffectType getter_side_effect_type,SideEffectType setter_side_effect_type)4653 Maybe<bool> Object::SetLazyDataProperty(
4654 v8::Local<v8::Context> context, v8::Local<Name> name,
4655 AccessorNameGetterCallback getter, v8::Local<Value> data,
4656 PropertyAttribute attributes, SideEffectType getter_side_effect_type,
4657 SideEffectType setter_side_effect_type) {
4658 return ObjectSetAccessor(context, this, name, getter,
4659 static_cast<AccessorNameSetterCallback>(nullptr),
4660 data, DEFAULT, attributes, true, true,
4661 getter_side_effect_type, setter_side_effect_type);
4662 }
4663
HasOwnProperty(Local<Context> context,Local<Name> key)4664 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4665 Local<Name> key) {
4666 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4667 ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4668 i::HandleScope);
4669 auto self = Utils::OpenHandle(this);
4670 auto key_val = Utils::OpenHandle(*key);
4671 auto result = i::JSReceiver::HasOwnProperty(self, key_val);
4672 has_pending_exception = result.IsNothing();
4673 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4674 return result;
4675 }
4676
HasOwnProperty(Local<Context> context,uint32_t index)4677 Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, uint32_t index) {
4678 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4679 ENTER_V8(isolate, context, Object, HasOwnProperty, Nothing<bool>(),
4680 i::HandleScope);
4681 auto self = Utils::OpenHandle(this);
4682 auto result = i::JSReceiver::HasOwnProperty(self, index);
4683 has_pending_exception = result.IsNothing();
4684 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4685 return result;
4686 }
4687
HasRealNamedProperty(Local<Context> context,Local<Name> key)4688 Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4689 Local<Name> key) {
4690 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4691 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedProperty,
4692 Nothing<bool>(), i::HandleScope);
4693 auto self = Utils::OpenHandle(this);
4694 if (!self->IsJSObject()) return Just(false);
4695 auto key_val = Utils::OpenHandle(*key);
4696 auto result = i::JSObject::HasRealNamedProperty(
4697 i::Handle<i::JSObject>::cast(self), key_val);
4698 has_pending_exception = result.IsNothing();
4699 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4700 return result;
4701 }
4702
HasRealIndexedProperty(Local<Context> context,uint32_t index)4703 Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4704 uint32_t index) {
4705 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4706 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealIndexedProperty,
4707 Nothing<bool>(), i::HandleScope);
4708 auto self = Utils::OpenHandle(this);
4709 if (!self->IsJSObject()) return Just(false);
4710 auto result = i::JSObject::HasRealElementProperty(
4711 i::Handle<i::JSObject>::cast(self), index);
4712 has_pending_exception = result.IsNothing();
4713 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4714 return result;
4715 }
4716
HasRealNamedCallbackProperty(Local<Context> context,Local<Name> key)4717 Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4718 Local<Name> key) {
4719 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4720 ENTER_V8_NO_SCRIPT(isolate, context, Object, HasRealNamedCallbackProperty,
4721 Nothing<bool>(), i::HandleScope);
4722 auto self = Utils::OpenHandle(this);
4723 if (!self->IsJSObject()) return Just(false);
4724 auto key_val = Utils::OpenHandle(*key);
4725 auto result = i::JSObject::HasRealNamedCallbackProperty(
4726 i::Handle<i::JSObject>::cast(self), key_val);
4727 has_pending_exception = result.IsNothing();
4728 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4729 return result;
4730 }
4731
HasNamedLookupInterceptor()4732 bool v8::Object::HasNamedLookupInterceptor() {
4733 auto self = Utils::OpenHandle(this);
4734 return self->IsJSObject() &&
4735 i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
4736 }
4737
HasIndexedLookupInterceptor()4738 bool v8::Object::HasIndexedLookupInterceptor() {
4739 auto self = Utils::OpenHandle(this);
4740 return self->IsJSObject() &&
4741 i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
4742 }
4743
GetRealNamedPropertyInPrototypeChain(Local<Context> context,Local<Name> key)4744 MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4745 Local<Context> context, Local<Name> key) {
4746 PREPARE_FOR_EXECUTION(context, Object, GetRealNamedPropertyInPrototypeChain,
4747 Value);
4748 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4749 if (!self->IsJSObject()) return MaybeLocal<Value>();
4750 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4751 i::PrototypeIterator iter(isolate, self);
4752 if (iter.IsAtEnd()) return MaybeLocal<Value>();
4753 i::Handle<i::JSReceiver> proto =
4754 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4755 i::LookupIterator::Key lookup_key(isolate, key_obj);
4756 i::LookupIterator it(isolate, self, lookup_key, proto,
4757 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4758 Local<Value> result;
4759 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4760 RETURN_ON_FAILED_EXECUTION(Value);
4761 if (!it.IsFound()) return MaybeLocal<Value>();
4762 RETURN_ESCAPED(result);
4763 }
4764
4765 Maybe<PropertyAttribute>
GetRealNamedPropertyAttributesInPrototypeChain(Local<Context> context,Local<Name> key)4766 v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
4767 Local<Context> context, Local<Name> key) {
4768 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4769 ENTER_V8(isolate, context, Object,
4770 GetRealNamedPropertyAttributesInPrototypeChain,
4771 Nothing<PropertyAttribute>(), i::HandleScope);
4772 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4773 if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
4774 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4775 i::PrototypeIterator iter(isolate, self);
4776 if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
4777 i::Handle<i::JSReceiver> proto =
4778 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4779 i::LookupIterator::Key lookup_key(isolate, key_obj);
4780 i::LookupIterator it(isolate, self, lookup_key, proto,
4781 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4782 Maybe<i::PropertyAttributes> result =
4783 i::JSReceiver::GetPropertyAttributes(&it);
4784 has_pending_exception = result.IsNothing();
4785 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4786 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4787 if (result.FromJust() == i::ABSENT) return Just(None);
4788 return Just(static_cast<PropertyAttribute>(result.FromJust()));
4789 }
4790
GetRealNamedProperty(Local<Context> context,Local<Name> key)4791 MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
4792 Local<Name> key) {
4793 PREPARE_FOR_EXECUTION(context, Object, GetRealNamedProperty, Value);
4794 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4795 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4796 i::LookupIterator::Key lookup_key(isolate, key_obj);
4797 i::LookupIterator it(isolate, self, lookup_key, self,
4798 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4799 Local<Value> result;
4800 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4801 RETURN_ON_FAILED_EXECUTION(Value);
4802 if (!it.IsFound()) return MaybeLocal<Value>();
4803 RETURN_ESCAPED(result);
4804 }
4805
GetRealNamedPropertyAttributes(Local<Context> context,Local<Name> key)4806 Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4807 Local<Context> context, Local<Name> key) {
4808 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4809 ENTER_V8(isolate, context, Object, GetRealNamedPropertyAttributes,
4810 Nothing<PropertyAttribute>(), i::HandleScope);
4811 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4812 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4813 i::LookupIterator::Key lookup_key(isolate, key_obj);
4814 i::LookupIterator it(isolate, self, lookup_key, self,
4815 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4816 auto result = i::JSReceiver::GetPropertyAttributes(&it);
4817 has_pending_exception = result.IsNothing();
4818 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4819 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4820 if (result.FromJust() == i::ABSENT) {
4821 return Just(static_cast<PropertyAttribute>(i::NONE));
4822 }
4823 return Just<PropertyAttribute>(
4824 static_cast<PropertyAttribute>(result.FromJust()));
4825 }
4826
Clone()4827 Local<v8::Object> v8::Object::Clone() {
4828 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4829 auto isolate = self->GetIsolate();
4830 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4831 auto result = isolate->factory()->CopyJSObject(self);
4832 CHECK(!result.is_null());
4833 return Utils::ToLocal(result);
4834 }
4835
CreationContext()4836 Local<v8::Context> v8::Object::CreationContext() {
4837 auto self = Utils::OpenHandle(this);
4838 i::Handle<i::Context> context = self->GetCreationContext();
4839 return Utils::ToLocal(context);
4840 }
4841
GetIdentityHash()4842 int v8::Object::GetIdentityHash() {
4843 i::DisallowHeapAllocation no_gc;
4844 auto self = Utils::OpenHandle(this);
4845 auto isolate = self->GetIsolate();
4846 i::HandleScope scope(isolate);
4847 return self->GetOrCreateIdentityHash(isolate).value();
4848 }
4849
IsCallable()4850 bool v8::Object::IsCallable() {
4851 auto self = Utils::OpenHandle(this);
4852 return self->IsCallable();
4853 }
4854
IsConstructor()4855 bool v8::Object::IsConstructor() {
4856 auto self = Utils::OpenHandle(this);
4857 return self->IsConstructor();
4858 }
4859
IsApiWrapper()4860 bool v8::Object::IsApiWrapper() {
4861 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4862 return self->IsApiWrapper();
4863 }
4864
IsUndetectable()4865 bool v8::Object::IsUndetectable() {
4866 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4867 return self->IsUndetectable();
4868 }
4869
CallAsFunction(Local<Context> context,Local<Value> recv,int argc,Local<Value> argv[])4870 MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
4871 Local<Value> recv, int argc,
4872 Local<Value> argv[]) {
4873 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4874 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
4875 ENTER_V8(isolate, context, Object, CallAsFunction, MaybeLocal<Value>(),
4876 InternalEscapableScope);
4877 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4878 auto self = Utils::OpenHandle(this);
4879 auto recv_obj = Utils::OpenHandle(*recv);
4880 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
4881 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4882 Local<Value> result;
4883 has_pending_exception = !ToLocal<Value>(
4884 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4885 RETURN_ON_FAILED_EXECUTION(Value);
4886 RETURN_ESCAPED(result);
4887 }
4888
CallAsConstructor(Local<Context> context,int argc,Local<Value> argv[])4889 MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
4890 Local<Value> argv[]) {
4891 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4892 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
4893 ENTER_V8(isolate, context, Object, CallAsConstructor, MaybeLocal<Value>(),
4894 InternalEscapableScope);
4895 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4896 auto self = Utils::OpenHandle(this);
4897 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
4898 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4899 Local<Value> result;
4900 has_pending_exception = !ToLocal<Value>(
4901 i::Execution::New(isolate, self, self, argc, args), &result);
4902 RETURN_ON_FAILED_EXECUTION(Value);
4903 RETURN_ESCAPED(result);
4904 }
4905
New(Local<Context> context,FunctionCallback callback,Local<Value> data,int length,ConstructorBehavior behavior,SideEffectType side_effect_type)4906 MaybeLocal<Function> Function::New(Local<Context> context,
4907 FunctionCallback callback, Local<Value> data,
4908 int length, ConstructorBehavior behavior,
4909 SideEffectType side_effect_type) {
4910 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
4911 LOG_API(isolate, Function, New);
4912 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
4913 auto templ =
4914 FunctionTemplateNew(isolate, callback, data, Local<Signature>(), length,
4915 true, Local<Private>(), side_effect_type);
4916 if (behavior == ConstructorBehavior::kThrow) templ->RemovePrototype();
4917 return templ->GetFunction(context);
4918 }
4919
NewInstance(Local<Context> context,int argc,v8::Local<v8::Value> argv[]) const4920 MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
4921 v8::Local<v8::Value> argv[]) const {
4922 return NewInstanceWithSideEffectType(context, argc, argv,
4923 SideEffectType::kHasSideEffect);
4924 }
4925
NewInstanceWithSideEffectType(Local<Context> context,int argc,v8::Local<v8::Value> argv[],SideEffectType side_effect_type) const4926 MaybeLocal<Object> Function::NewInstanceWithSideEffectType(
4927 Local<Context> context, int argc, v8::Local<v8::Value> argv[],
4928 SideEffectType side_effect_type) const {
4929 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4930 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
4931 ENTER_V8(isolate, context, Function, NewInstance, MaybeLocal<Object>(),
4932 InternalEscapableScope);
4933 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4934 auto self = Utils::OpenHandle(this);
4935 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
4936 bool should_set_has_no_side_effect =
4937 side_effect_type == SideEffectType::kHasNoSideEffect &&
4938 isolate->debug_execution_mode() == i::DebugInfo::kSideEffects;
4939 if (should_set_has_no_side_effect) {
4940 CHECK(self->IsJSFunction() &&
4941 i::JSFunction::cast(*self).shared().IsApiFunction());
4942 i::Object obj =
4943 i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
4944 kAcquireLoad);
4945 if (obj.IsCallHandlerInfo()) {
4946 i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
4947 if (!handler_info.IsSideEffectFreeCallHandlerInfo()) {
4948 handler_info.SetNextCallHasNoSideEffect();
4949 }
4950 }
4951 }
4952 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4953 Local<Object> result;
4954 has_pending_exception = !ToLocal<Object>(
4955 i::Execution::New(isolate, self, self, argc, args), &result);
4956 if (should_set_has_no_side_effect) {
4957 i::Object obj =
4958 i::JSFunction::cast(*self).shared().get_api_func_data().call_code(
4959 kAcquireLoad);
4960 if (obj.IsCallHandlerInfo()) {
4961 i::CallHandlerInfo handler_info = i::CallHandlerInfo::cast(obj);
4962 if (has_pending_exception) {
4963 // Restore the map if an exception prevented restoration.
4964 handler_info.NextCallHasNoSideEffect();
4965 } else {
4966 DCHECK(handler_info.IsSideEffectCallHandlerInfo() ||
4967 handler_info.IsSideEffectFreeCallHandlerInfo());
4968 }
4969 }
4970 }
4971 RETURN_ON_FAILED_EXECUTION(Object);
4972 RETURN_ESCAPED(result);
4973 }
4974
Call(Local<Context> context,v8::Local<v8::Value> recv,int argc,v8::Local<v8::Value> argv[])4975 MaybeLocal<v8::Value> Function::Call(Local<Context> context,
4976 v8::Local<v8::Value> recv, int argc,
4977 v8::Local<v8::Value> argv[]) {
4978 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
4979 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.Execute");
4980 ENTER_V8(isolate, context, Function, Call, MaybeLocal<Value>(),
4981 InternalEscapableScope);
4982 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4983 auto self = Utils::OpenHandle(this);
4984 Utils::ApiCheck(!self.is_null(), "v8::Function::Call",
4985 "Function to be called is a null pointer");
4986 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4987 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Handle<i::Object>));
4988 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4989 Local<Value> result;
4990 has_pending_exception = !ToLocal<Value>(
4991 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4992 RETURN_ON_FAILED_EXECUTION(Value);
4993 RETURN_ESCAPED(result);
4994 }
4995
SetName(v8::Local<v8::String> name)4996 void Function::SetName(v8::Local<v8::String> name) {
4997 auto self = Utils::OpenHandle(this);
4998 if (!self->IsJSFunction()) return;
4999 auto func = i::Handle<i::JSFunction>::cast(self);
5000 func->shared().SetName(*Utils::OpenHandle(*name));
5001 }
5002
GetName() const5003 Local<Value> Function::GetName() const {
5004 auto self = Utils::OpenHandle(this);
5005 i::Isolate* isolate = self->GetIsolate();
5006 if (self->IsJSBoundFunction()) {
5007 auto func = i::Handle<i::JSBoundFunction>::cast(self);
5008 i::Handle<i::Object> name;
5009 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
5010 i::JSBoundFunction::GetName(isolate, func),
5011 Local<Value>());
5012 return Utils::ToLocal(name);
5013 }
5014 if (self->IsJSFunction()) {
5015 auto func = i::Handle<i::JSFunction>::cast(self);
5016 return Utils::ToLocal(handle(func->shared().Name(), isolate));
5017 }
5018 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5019 }
5020
GetInferredName() const5021 Local<Value> Function::GetInferredName() const {
5022 auto self = Utils::OpenHandle(this);
5023 if (!self->IsJSFunction()) {
5024 return ToApiHandle<Primitive>(
5025 self->GetIsolate()->factory()->undefined_value());
5026 }
5027 auto func = i::Handle<i::JSFunction>::cast(self);
5028 return Utils::ToLocal(
5029 i::Handle<i::Object>(func->shared().inferred_name(), func->GetIsolate()));
5030 }
5031
GetDebugName() const5032 Local<Value> Function::GetDebugName() const {
5033 auto self = Utils::OpenHandle(this);
5034 if (!self->IsJSFunction()) {
5035 return ToApiHandle<Primitive>(
5036 self->GetIsolate()->factory()->undefined_value());
5037 }
5038 auto func = i::Handle<i::JSFunction>::cast(self);
5039 i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
5040 return Utils::ToLocal(i::Handle<i::Object>(*name, self->GetIsolate()));
5041 }
5042
GetDisplayName() const5043 Local<Value> Function::GetDisplayName() const {
5044 auto self = Utils::OpenHandle(this);
5045 i::Isolate* isolate = self->GetIsolate();
5046 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5047 if (!self->IsJSFunction()) {
5048 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5049 }
5050 auto func = i::Handle<i::JSFunction>::cast(self);
5051 i::Handle<i::String> property_name =
5052 isolate->factory()->display_name_string();
5053 i::Handle<i::Object> value =
5054 i::JSReceiver::GetDataProperty(func, property_name);
5055 if (value->IsString()) {
5056 i::Handle<i::String> name = i::Handle<i::String>::cast(value);
5057 if (name->length() > 0) return Utils::ToLocal(name);
5058 }
5059 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
5060 }
5061
GetScriptOrigin() const5062 ScriptOrigin Function::GetScriptOrigin() const {
5063 auto self = Utils::OpenHandle(this);
5064 if (!self->IsJSFunction()) {
5065 return v8::ScriptOrigin(Local<Value>());
5066 }
5067 auto func = i::Handle<i::JSFunction>::cast(self);
5068 if (func->shared().script().IsScript()) {
5069 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5070 func->GetIsolate());
5071 return GetScriptOriginForScript(func->GetIsolate(), script);
5072 }
5073 return v8::ScriptOrigin(Local<Value>());
5074 }
5075
5076 const int Function::kLineOffsetNotFound = -1;
5077
GetScriptLineNumber() const5078 int Function::GetScriptLineNumber() const {
5079 auto self = Utils::OpenHandle(this);
5080 if (!self->IsJSFunction()) {
5081 return kLineOffsetNotFound;
5082 }
5083 auto func = i::Handle<i::JSFunction>::cast(self);
5084 if (func->shared().script().IsScript()) {
5085 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5086 func->GetIsolate());
5087 return i::Script::GetLineNumber(script, func->shared().StartPosition());
5088 }
5089 return kLineOffsetNotFound;
5090 }
5091
GetScriptColumnNumber() const5092 int Function::GetScriptColumnNumber() const {
5093 auto self = Utils::OpenHandle(this);
5094 if (!self->IsJSFunction()) {
5095 return kLineOffsetNotFound;
5096 }
5097 auto func = i::Handle<i::JSFunction>::cast(self);
5098 if (func->shared().script().IsScript()) {
5099 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5100 func->GetIsolate());
5101 return i::Script::GetColumnNumber(script, func->shared().StartPosition());
5102 }
5103 return kLineOffsetNotFound;
5104 }
5105
ScriptId() const5106 int Function::ScriptId() const {
5107 auto self = Utils::OpenHandle(this);
5108 if (!self->IsJSFunction()) {
5109 return v8::UnboundScript::kNoScriptId;
5110 }
5111 auto func = i::Handle<i::JSFunction>::cast(self);
5112 if (!func->shared().script().IsScript()) {
5113 return v8::UnboundScript::kNoScriptId;
5114 }
5115 i::Handle<i::Script> script(i::Script::cast(func->shared().script()),
5116 func->GetIsolate());
5117 return script->id();
5118 }
5119
GetBoundFunction() const5120 Local<v8::Value> Function::GetBoundFunction() const {
5121 auto self = Utils::OpenHandle(this);
5122 if (self->IsJSBoundFunction()) {
5123 auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
5124 auto bound_target_function = i::handle(
5125 bound_function->bound_target_function(), bound_function->GetIsolate());
5126 return Utils::CallableToLocal(bound_target_function);
5127 }
5128 return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
5129 }
5130
FunctionProtoToString(Local<Context> context)5131 MaybeLocal<String> v8::Function::FunctionProtoToString(Local<Context> context) {
5132 PREPARE_FOR_EXECUTION(context, Function, FunctionProtoToString, String);
5133 auto self = Utils::OpenHandle(this);
5134 Local<Value> result;
5135 has_pending_exception = !ToLocal<Value>(
5136 i::Execution::CallBuiltin(isolate, isolate->function_to_string(), self, 0,
5137 nullptr),
5138 &result);
5139 RETURN_ON_FAILED_EXECUTION(String);
5140 RETURN_ESCAPED(Local<String>::Cast(result));
5141 }
5142
GetIdentityHash()5143 int Name::GetIdentityHash() {
5144 auto self = Utils::OpenHandle(this);
5145 return static_cast<int>(self->Hash());
5146 }
5147
Length() const5148 int String::Length() const {
5149 i::Handle<i::String> str = Utils::OpenHandle(this);
5150 return str->length();
5151 }
5152
IsOneByte() const5153 bool String::IsOneByte() const {
5154 i::Handle<i::String> str = Utils::OpenHandle(this);
5155 return str->IsOneByteRepresentation();
5156 }
5157
5158 // Helpers for ContainsOnlyOneByteHelper
5159 template <size_t size>
5160 struct OneByteMask;
5161 template <>
5162 struct OneByteMask<4> {
5163 static const uint32_t value = 0xFF00FF00;
5164 };
5165 template <>
5166 struct OneByteMask<8> {
5167 static const uint64_t value = 0xFF00'FF00'FF00'FF00;
5168 };
5169 static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
5170 static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
Unaligned(const uint16_t * chars)5171 static inline bool Unaligned(const uint16_t* chars) {
5172 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
5173 }
5174
Align(const uint16_t * chars)5175 static inline const uint16_t* Align(const uint16_t* chars) {
5176 return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(chars) &
5177 ~kAlignmentMask);
5178 }
5179
5180 class ContainsOnlyOneByteHelper {
5181 public:
ContainsOnlyOneByteHelper()5182 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
Check(i::String string)5183 bool Check(i::String string) {
5184 i::ConsString cons_string = i::String::VisitFlat(this, string, 0);
5185 if (cons_string.is_null()) return is_one_byte_;
5186 return CheckCons(cons_string);
5187 }
VisitOneByteString(const uint8_t * chars,int length)5188 void VisitOneByteString(const uint8_t* chars, int length) {
5189 // Nothing to do.
5190 }
VisitTwoByteString(const uint16_t * chars,int length)5191 void VisitTwoByteString(const uint16_t* chars, int length) {
5192 // Accumulated bits.
5193 uintptr_t acc = 0;
5194 // Align to uintptr_t.
5195 const uint16_t* end = chars + length;
5196 while (Unaligned(chars) && chars != end) {
5197 acc |= *chars++;
5198 }
5199 // Read word aligned in blocks,
5200 // checking the return value at the end of each block.
5201 const uint16_t* aligned_end = Align(end);
5202 const int increment = sizeof(uintptr_t) / sizeof(uint16_t);
5203 const int inner_loops = 16;
5204 while (chars + inner_loops * increment < aligned_end) {
5205 for (int i = 0; i < inner_loops; i++) {
5206 acc |= *reinterpret_cast<const uintptr_t*>(chars);
5207 chars += increment;
5208 }
5209 // Check for early return.
5210 if ((acc & kOneByteMask) != 0) {
5211 is_one_byte_ = false;
5212 return;
5213 }
5214 }
5215 // Read the rest.
5216 while (chars != end) {
5217 acc |= *chars++;
5218 }
5219 // Check result.
5220 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
5221 }
5222
5223 private:
CheckCons(i::ConsString cons_string)5224 bool CheckCons(i::ConsString cons_string) {
5225 while (true) {
5226 // Check left side if flat.
5227 i::String left = cons_string.first();
5228 i::ConsString left_as_cons = i::String::VisitFlat(this, left, 0);
5229 if (!is_one_byte_) return false;
5230 // Check right side if flat.
5231 i::String right = cons_string.second();
5232 i::ConsString right_as_cons = i::String::VisitFlat(this, right, 0);
5233 if (!is_one_byte_) return false;
5234 // Standard recurse/iterate trick.
5235 if (!left_as_cons.is_null() && !right_as_cons.is_null()) {
5236 if (left.length() < right.length()) {
5237 CheckCons(left_as_cons);
5238 cons_string = right_as_cons;
5239 } else {
5240 CheckCons(right_as_cons);
5241 cons_string = left_as_cons;
5242 }
5243 // Check fast return.
5244 if (!is_one_byte_) return false;
5245 continue;
5246 }
5247 // Descend left in place.
5248 if (!left_as_cons.is_null()) {
5249 cons_string = left_as_cons;
5250 continue;
5251 }
5252 // Descend right in place.
5253 if (!right_as_cons.is_null()) {
5254 cons_string = right_as_cons;
5255 continue;
5256 }
5257 // Terminate.
5258 break;
5259 }
5260 return is_one_byte_;
5261 }
5262 bool is_one_byte_;
5263 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
5264 };
5265
ContainsOnlyOneByte() const5266 bool String::ContainsOnlyOneByte() const {
5267 i::Handle<i::String> str = Utils::OpenHandle(this);
5268 if (str->IsOneByteRepresentation()) return true;
5269 ContainsOnlyOneByteHelper helper;
5270 return helper.Check(*str);
5271 }
5272
Utf8Length(Isolate * isolate) const5273 int String::Utf8Length(Isolate* isolate) const {
5274 i::Handle<i::String> str = Utils::OpenHandle(this);
5275 str = i::String::Flatten(reinterpret_cast<i::Isolate*>(isolate), str);
5276 int length = str->length();
5277 if (length == 0) return 0;
5278 i::DisallowHeapAllocation no_gc;
5279 i::String::FlatContent flat = str->GetFlatContent(no_gc);
5280 DCHECK(flat.IsFlat());
5281 int utf8_length = 0;
5282 if (flat.IsOneByte()) {
5283 for (uint8_t c : flat.ToOneByteVector()) {
5284 utf8_length += c >> 7;
5285 }
5286 utf8_length += length;
5287 } else {
5288 int last_character = unibrow::Utf16::kNoPreviousCharacter;
5289 for (uint16_t c : flat.ToUC16Vector()) {
5290 utf8_length += unibrow::Utf8::Length(c, last_character);
5291 last_character = c;
5292 }
5293 }
5294 return utf8_length;
5295 }
5296
5297 namespace {
5298 // Writes the flat content of a string to a buffer. This is done in two phases.
5299 // The first phase calculates a pessimistic estimate (writable_length) on how
5300 // many code units can be safely written without exceeding the buffer capacity
5301 // and without leaving at a lone surrogate. The estimated number of code units
5302 // is then written out in one go, and the reported byte usage is used to
5303 // correct the estimate. This is repeated until the estimate becomes <= 0 or
5304 // all code units have been written out. The second phase writes out code
5305 // units until the buffer capacity is reached, would be exceeded by the next
5306 // unit, or all code units have been written out.
5307 template <typename Char>
WriteUtf8Impl(i::Vector<const Char> string,char * write_start,int write_capacity,int options,int * utf16_chars_read_out)5308 static int WriteUtf8Impl(i::Vector<const Char> string, char* write_start,
5309 int write_capacity, int options,
5310 int* utf16_chars_read_out) {
5311 bool write_null = !(options & v8::String::NO_NULL_TERMINATION);
5312 bool replace_invalid_utf8 = (options & v8::String::REPLACE_INVALID_UTF8);
5313 char* current_write = write_start;
5314 const Char* read_start = string.begin();
5315 int read_index = 0;
5316 int read_length = string.length();
5317 int prev_char = unibrow::Utf16::kNoPreviousCharacter;
5318 // Do a fast loop where there is no exit capacity check.
5319 // Need enough space to write everything but one character.
5320 STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
5321 static const int kMaxSizePerChar = sizeof(Char) == 1 ? 2 : 3;
5322 while (read_index < read_length) {
5323 int up_to = read_length;
5324 if (write_capacity != -1) {
5325 int remaining_capacity =
5326 write_capacity - static_cast<int>(current_write - write_start);
5327 int writable_length =
5328 (remaining_capacity - kMaxSizePerChar) / kMaxSizePerChar;
5329 // Need to drop into slow loop.
5330 if (writable_length <= 0) break;
5331 up_to = std::min(up_to, read_index + writable_length);
5332 }
5333 // Write the characters to the stream.
5334 if (sizeof(Char) == 1) {
5335 // Simply memcpy if we only have ASCII characters.
5336 uint8_t char_mask = 0;
5337 for (int i = read_index; i < up_to; i++) char_mask |= read_start[i];
5338 if ((char_mask & 0x80) == 0) {
5339 int copy_length = up_to - read_index;
5340 memcpy(current_write, read_start + read_index, copy_length);
5341 current_write += copy_length;
5342 read_index = up_to;
5343 } else {
5344 for (; read_index < up_to; read_index++) {
5345 current_write += unibrow::Utf8::EncodeOneByte(
5346 current_write, static_cast<uint8_t>(read_start[read_index]));
5347 DCHECK(write_capacity == -1 ||
5348 (current_write - write_start) <= write_capacity);
5349 }
5350 }
5351 } else {
5352 for (; read_index < up_to; read_index++) {
5353 uint16_t character = read_start[read_index];
5354 current_write += unibrow::Utf8::Encode(current_write, character,
5355 prev_char, replace_invalid_utf8);
5356 prev_char = character;
5357 DCHECK(write_capacity == -1 ||
5358 (current_write - write_start) <= write_capacity);
5359 }
5360 }
5361 }
5362 if (read_index < read_length) {
5363 DCHECK_NE(-1, write_capacity);
5364 // Aborted due to limited capacity. Check capacity on each iteration.
5365 int remaining_capacity =
5366 write_capacity - static_cast<int>(current_write - write_start);
5367 DCHECK_GE(remaining_capacity, 0);
5368 for (; read_index < read_length && remaining_capacity > 0; read_index++) {
5369 uint32_t character = read_start[read_index];
5370 int written = 0;
5371 // We can't use a local buffer here because Encode needs to modify
5372 // previous characters in the stream. We know, however, that
5373 // exactly one character will be advanced.
5374 if (unibrow::Utf16::IsSurrogatePair(prev_char, character)) {
5375 written = unibrow::Utf8::Encode(current_write, character, prev_char,
5376 replace_invalid_utf8);
5377 DCHECK_EQ(written, 1);
5378 } else {
5379 // Use a scratch buffer to check the required characters.
5380 char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
5381 // Encoding a surrogate pair to Utf8 always takes 4 bytes.
5382 static const int kSurrogatePairEncodedSize =
5383 static_cast<int>(unibrow::Utf8::kMaxEncodedSize);
5384 // For REPLACE_INVALID_UTF8, catch the case where we cut off in the
5385 // middle of a surrogate pair. Abort before encoding the pair instead.
5386 if (replace_invalid_utf8 &&
5387 remaining_capacity < kSurrogatePairEncodedSize &&
5388 unibrow::Utf16::IsLeadSurrogate(character) &&
5389 read_index + 1 < read_length &&
5390 unibrow::Utf16::IsTrailSurrogate(read_start[read_index + 1])) {
5391 write_null = false;
5392 break;
5393 }
5394 // Can't encode using prev_char as gcc has array bounds issues.
5395 written = unibrow::Utf8::Encode(temp_buffer, character,
5396 unibrow::Utf16::kNoPreviousCharacter,
5397 replace_invalid_utf8);
5398 if (written > remaining_capacity) {
5399 // Won't fit. Abort and do not null-terminate the result.
5400 write_null = false;
5401 break;
5402 }
5403 // Copy over the character from temp_buffer.
5404 for (int i = 0; i < written; i++) current_write[i] = temp_buffer[i];
5405 }
5406
5407 current_write += written;
5408 remaining_capacity -= written;
5409 prev_char = character;
5410 }
5411 }
5412
5413 // Write out number of utf16 characters written to the stream.
5414 if (utf16_chars_read_out != nullptr) *utf16_chars_read_out = read_index;
5415
5416 // Only null-terminate if there's space.
5417 if (write_null && (write_capacity == -1 ||
5418 (current_write - write_start) < write_capacity)) {
5419 *current_write++ = '\0';
5420 }
5421 return static_cast<int>(current_write - write_start);
5422 }
5423 } // anonymous namespace
5424
WriteUtf8(Isolate * v8_isolate,char * buffer,int capacity,int * nchars_ref,int options) const5425 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity,
5426 int* nchars_ref, int options) const {
5427 i::Handle<i::String> str = Utils::OpenHandle(this);
5428 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5429 LOG_API(isolate, String, WriteUtf8);
5430 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5431 str = i::String::Flatten(isolate, str);
5432 i::DisallowHeapAllocation no_gc;
5433 i::String::FlatContent content = str->GetFlatContent(no_gc);
5434 if (content.IsOneByte()) {
5435 return WriteUtf8Impl<uint8_t>(content.ToOneByteVector(), buffer, capacity,
5436 options, nchars_ref);
5437 } else {
5438 return WriteUtf8Impl<uint16_t>(content.ToUC16Vector(), buffer, capacity,
5439 options, nchars_ref);
5440 }
5441 }
5442
5443 template <typename CharType>
WriteHelper(i::Isolate * isolate,const String * string,CharType * buffer,int start,int length,int options)5444 static inline int WriteHelper(i::Isolate* isolate, const String* string,
5445 CharType* buffer, int start, int length,
5446 int options) {
5447 LOG_API(isolate, String, Write);
5448 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
5449 DCHECK(start >= 0 && length >= -1);
5450 i::Handle<i::String> str = Utils::OpenHandle(string);
5451 str = i::String::Flatten(isolate, str);
5452 int end = start + length;
5453 if ((length == -1) || (length > str->length() - start)) end = str->length();
5454 if (end < 0) return 0;
5455 if (start < end) i::String::WriteToFlat(*str, buffer, start, end);
5456 if (!(options & String::NO_NULL_TERMINATION) &&
5457 (length == -1 || end - start < length)) {
5458 buffer[end - start] = '\0';
5459 }
5460 return end - start;
5461 }
5462
WriteOneByte(Isolate * isolate,uint8_t * buffer,int start,int length,int options) const5463 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start,
5464 int length, int options) const {
5465 return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5466 start, length, options);
5467 }
5468
Write(Isolate * isolate,uint16_t * buffer,int start,int length,int options) const5469 int String::Write(Isolate* isolate, uint16_t* buffer, int start, int length,
5470 int options) const {
5471 return WriteHelper(reinterpret_cast<i::Isolate*>(isolate), this, buffer,
5472 start, length, options);
5473 }
5474
IsExternal() const5475 bool v8::String::IsExternal() const {
5476 return IsExternalTwoByte();
5477 }
5478
IsExternalTwoByte() const5479 bool v8::String::IsExternalTwoByte() const {
5480 i::Handle<i::String> str = Utils::OpenHandle(this);
5481 return i::StringShape(*str).IsExternalTwoByte();
5482 }
5483
IsExternalOneByte() const5484 bool v8::String::IsExternalOneByte() const {
5485 i::Handle<i::String> str = Utils::OpenHandle(this);
5486 return i::StringShape(*str).IsExternalOneByte();
5487 }
5488
VerifyExternalStringResource(v8::String::ExternalStringResource * value) const5489 void v8::String::VerifyExternalStringResource(
5490 v8::String::ExternalStringResource* value) const {
5491 i::DisallowHeapAllocation no_allocation;
5492 i::String str = *Utils::OpenHandle(this);
5493 const v8::String::ExternalStringResource* expected;
5494
5495 if (str.IsThinString()) {
5496 str = i::ThinString::cast(str).actual();
5497 }
5498
5499 if (i::StringShape(str).IsExternalTwoByte()) {
5500 const void* resource = i::ExternalTwoByteString::cast(str).resource();
5501 expected = reinterpret_cast<const ExternalStringResource*>(resource);
5502 } else {
5503 expected = nullptr;
5504 }
5505 CHECK_EQ(expected, value);
5506 }
5507
VerifyExternalStringResourceBase(v8::String::ExternalStringResourceBase * value,Encoding encoding) const5508 void v8::String::VerifyExternalStringResourceBase(
5509 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
5510 i::DisallowHeapAllocation no_allocation;
5511 i::String str = *Utils::OpenHandle(this);
5512 const v8::String::ExternalStringResourceBase* expected;
5513 Encoding expectedEncoding;
5514
5515 if (str.IsThinString()) {
5516 str = i::ThinString::cast(str).actual();
5517 }
5518
5519 if (i::StringShape(str).IsExternalOneByte()) {
5520 const void* resource = i::ExternalOneByteString::cast(str).resource();
5521 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5522 expectedEncoding = ONE_BYTE_ENCODING;
5523 } else if (i::StringShape(str).IsExternalTwoByte()) {
5524 const void* resource = i::ExternalTwoByteString::cast(str).resource();
5525 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5526 expectedEncoding = TWO_BYTE_ENCODING;
5527 } else {
5528 expected = nullptr;
5529 expectedEncoding =
5530 str.IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5531 }
5532 CHECK_EQ(expected, value);
5533 CHECK_EQ(expectedEncoding, encoding);
5534 }
5535
GetExternalStringResourceSlow() const5536 String::ExternalStringResource* String::GetExternalStringResourceSlow() const {
5537 i::DisallowHeapAllocation no_allocation;
5538 using I = internal::Internals;
5539 i::String str = *Utils::OpenHandle(this);
5540
5541 if (str.IsThinString()) {
5542 str = i::ThinString::cast(str).actual();
5543 }
5544
5545 if (i::StringShape(str).IsExternalTwoByte()) {
5546 internal::Isolate* isolate = I::GetIsolateForHeapSandbox(str.ptr());
5547 internal::Address value = I::ReadExternalPointerField(
5548 isolate, str.ptr(), I::kStringResourceOffset,
5549 internal::kExternalStringResourceTag);
5550 return reinterpret_cast<String::ExternalStringResource*>(value);
5551 }
5552 return nullptr;
5553 }
5554
GetExternalStringResourceBaseSlow(String::Encoding * encoding_out) const5555 String::ExternalStringResourceBase* String::GetExternalStringResourceBaseSlow(
5556 String::Encoding* encoding_out) const {
5557 i::DisallowHeapAllocation no_allocation;
5558 using I = internal::Internals;
5559 ExternalStringResourceBase* resource = nullptr;
5560 i::String str = *Utils::OpenHandle(this);
5561
5562 if (str.IsThinString()) {
5563 str = i::ThinString::cast(str).actual();
5564 }
5565
5566 internal::Address string = str.ptr();
5567 int type = I::GetInstanceType(string) & I::kFullStringRepresentationMask;
5568 *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
5569 if (i::StringShape(str).IsExternalOneByte() ||
5570 i::StringShape(str).IsExternalTwoByte()) {
5571 internal::Isolate* isolate = I::GetIsolateForHeapSandbox(string);
5572 internal::Address value =
5573 I::ReadExternalPointerField(isolate, string, I::kStringResourceOffset,
5574 internal::kExternalStringResourceTag);
5575 resource = reinterpret_cast<ExternalStringResourceBase*>(value);
5576 }
5577 return resource;
5578 }
5579
5580 const v8::String::ExternalOneByteStringResource*
GetExternalOneByteStringResource() const5581 v8::String::GetExternalOneByteStringResource() const {
5582 i::DisallowHeapAllocation no_allocation;
5583 i::String str = *Utils::OpenHandle(this);
5584 if (i::StringShape(str).IsExternalOneByte()) {
5585 return i::ExternalOneByteString::cast(str).resource();
5586 } else if (str.IsThinString()) {
5587 str = i::ThinString::cast(str).actual();
5588 if (i::StringShape(str).IsExternalOneByte()) {
5589 return i::ExternalOneByteString::cast(str).resource();
5590 }
5591 }
5592 return nullptr;
5593 }
5594
Description() const5595 Local<Value> Symbol::Description() const {
5596 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5597
5598 i::Isolate* isolate;
5599 if (!i::GetIsolateFromHeapObject(*sym, &isolate)) {
5600 // Symbol is in RO_SPACE, which means that its description is also in
5601 // RO_SPACE. Since RO_SPACE objects are immovable we can use the
5602 // Handle(Address*) constructor with the address of the description
5603 // field in the Symbol object without needing an isolate.
5604 DCHECK(!COMPRESS_POINTERS_BOOL);
5605 i::Handle<i::HeapObject> ro_description(reinterpret_cast<i::Address*>(
5606 sym->GetFieldAddress(i::Symbol::kDescriptionOffset)));
5607 return Utils::ToLocal(ro_description);
5608 }
5609
5610 i::Handle<i::Object> description(sym->description(), isolate);
5611
5612 return Utils::ToLocal(description);
5613 }
5614
Name() const5615 Local<Value> Private::Name() const {
5616 return reinterpret_cast<const Symbol*>(this)->Description();
5617 }
5618
Value() const5619 double Number::Value() const {
5620 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5621 return obj->Number();
5622 }
5623
Value() const5624 bool Boolean::Value() const {
5625 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5626 return obj->IsTrue();
5627 }
5628
Value() const5629 int64_t Integer::Value() const {
5630 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5631 if (obj->IsSmi()) {
5632 return i::Smi::ToInt(*obj);
5633 } else {
5634 return static_cast<int64_t>(obj->Number());
5635 }
5636 }
5637
Value() const5638 int32_t Int32::Value() const {
5639 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5640 if (obj->IsSmi()) {
5641 return i::Smi::ToInt(*obj);
5642 } else {
5643 return static_cast<int32_t>(obj->Number());
5644 }
5645 }
5646
Value() const5647 uint32_t Uint32::Value() const {
5648 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5649 if (obj->IsSmi()) {
5650 return i::Smi::ToInt(*obj);
5651 } else {
5652 return static_cast<uint32_t>(obj->Number());
5653 }
5654 }
5655
InternalFieldCount()5656 int v8::Object::InternalFieldCount() {
5657 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5658 if (!self->IsJSObject()) return 0;
5659 return i::Handle<i::JSObject>::cast(self)->GetEmbedderFieldCount();
5660 }
5661
InternalFieldOK(i::Handle<i::JSReceiver> obj,int index,const char * location)5662 static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
5663 const char* location) {
5664 return Utils::ApiCheck(
5665 obj->IsJSObject() &&
5666 (index < i::Handle<i::JSObject>::cast(obj)->GetEmbedderFieldCount()),
5667 location, "Internal field out of bounds");
5668 }
5669
SlowGetInternalField(int index)5670 Local<Value> v8::Object::SlowGetInternalField(int index) {
5671 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5672 const char* location = "v8::Object::GetInternalField()";
5673 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5674 i::Handle<i::Object> value(i::JSObject::cast(*obj).GetEmbedderField(index),
5675 obj->GetIsolate());
5676 return Utils::ToLocal(value);
5677 }
5678
SetInternalField(int index,v8::Local<Value> value)5679 void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5680 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5681 const char* location = "v8::Object::SetInternalField()";
5682 if (!InternalFieldOK(obj, index, location)) return;
5683 i::Handle<i::Object> val = Utils::OpenHandle(*value);
5684 i::Handle<i::JSObject>::cast(obj)->SetEmbedderField(index, *val);
5685 }
5686
SlowGetAlignedPointerFromInternalField(int index)5687 void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5688 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5689 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5690 if (!InternalFieldOK(obj, index, location)) return nullptr;
5691 void* result;
5692 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5693 .ToAlignedPointer(obj->GetIsolate(), &result),
5694 location, "Unaligned pointer");
5695 return result;
5696 }
5697
SetAlignedPointerInInternalField(int index,void * value)5698 void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5699 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5700 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5701 if (!InternalFieldOK(obj, index, location)) return;
5702 Utils::ApiCheck(i::EmbedderDataSlot(i::JSObject::cast(*obj), index)
5703 .store_aligned_pointer(obj->GetIsolate(), value),
5704 location, "Unaligned pointer");
5705 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5706 }
5707
SetAlignedPointerInInternalFields(int argc,int indices[],void * values[])5708 void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
5709 void* values[]) {
5710 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
5711 const char* location = "v8::Object::SetAlignedPointerInInternalFields()";
5712 i::DisallowHeapAllocation no_gc;
5713 i::JSObject js_obj = i::JSObject::cast(*obj);
5714 int nof_embedder_fields = js_obj.GetEmbedderFieldCount();
5715 for (int i = 0; i < argc; i++) {
5716 int index = indices[i];
5717 if (!Utils::ApiCheck(index < nof_embedder_fields, location,
5718 "Internal field out of bounds")) {
5719 return;
5720 }
5721 void* value = values[i];
5722 Utils::ApiCheck(i::EmbedderDataSlot(js_obj, index)
5723 .store_aligned_pointer(obj->GetIsolate(), value),
5724 location, "Unaligned pointer");
5725 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5726 }
5727 }
5728
ExternalValue(i::Object obj)5729 static void* ExternalValue(i::Object obj) {
5730 // Obscure semantics for undefined, but somehow checked in our unit tests...
5731 if (obj.IsUndefined()) {
5732 return nullptr;
5733 }
5734 i::Object foreign = i::JSObject::cast(obj).GetEmbedderField(0);
5735 return reinterpret_cast<void*>(i::Foreign::cast(foreign).foreign_address());
5736 }
5737
5738 // --- E n v i r o n m e n t ---
5739
InitializePlatform(Platform * platform)5740 void v8::V8::InitializePlatform(Platform* platform) {
5741 i::V8::InitializePlatform(platform);
5742 }
5743
ShutdownPlatform()5744 void v8::V8::ShutdownPlatform() { i::V8::ShutdownPlatform(); }
5745
Initialize(const int build_config)5746 bool v8::V8::Initialize(const int build_config) {
5747 const bool kEmbedderPointerCompression =
5748 (build_config & kPointerCompression) != 0;
5749 if (kEmbedderPointerCompression != COMPRESS_POINTERS_BOOL) {
5750 FATAL(
5751 "Embedder-vs-V8 build configuration mismatch. On embedder side "
5752 "pointer compression is %s while on V8 side it's %s.",
5753 kEmbedderPointerCompression ? "ENABLED" : "DISABLED",
5754 COMPRESS_POINTERS_BOOL ? "ENABLED" : "DISABLED");
5755 }
5756
5757 const int kEmbedderSmiValueSize = (build_config & k31BitSmis) ? 31 : 32;
5758 if (kEmbedderSmiValueSize != internal::kSmiValueSize) {
5759 FATAL(
5760 "Embedder-vs-V8 build configuration mismatch. On embedder side "
5761 "Smi value size is %d while on V8 side it's %d.",
5762 kEmbedderSmiValueSize, internal::kSmiValueSize);
5763 }
5764
5765 const bool kEmbedderHeapSandbox = (build_config & kHeapSandbox) != 0;
5766 if (kEmbedderHeapSandbox != V8_HEAP_SANDBOX_BOOL) {
5767 FATAL(
5768 "Embedder-vs-V8 build configuration mismatch. On embedder side "
5769 "heap sandbox is %s while on V8 side it's %s.",
5770 kEmbedderHeapSandbox ? "ENABLED" : "DISABLED",
5771 V8_HEAP_SANDBOX_BOOL ? "ENABLED" : "DISABLED");
5772 }
5773
5774 i::V8::Initialize();
5775 return true;
5776 }
5777
5778 #if V8_OS_LINUX || V8_OS_MACOSX
TryHandleWebAssemblyTrapPosix(int sig_code,siginfo_t * info,void * context)5779 bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info,
5780 void* context) {
5781 #if V8_TARGET_ARCH_X64 && !V8_OS_ANDROID
5782 return i::trap_handler::TryHandleSignal(sig_code, info, context);
5783 #else
5784 return false;
5785 #endif
5786 }
5787
TryHandleSignal(int signum,void * info,void * context)5788 bool V8::TryHandleSignal(int signum, void* info, void* context) {
5789 return TryHandleWebAssemblyTrapPosix(
5790 signum, reinterpret_cast<siginfo_t*>(info), context);
5791 }
5792 #endif
5793
5794 #if V8_OS_WIN
TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS * exception)5795 bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception) {
5796 #if V8_TARGET_ARCH_X64
5797 return i::trap_handler::TryHandleWasmTrap(exception);
5798 #endif
5799 return false;
5800 }
5801 #endif
5802
EnableWebAssemblyTrapHandler(bool use_v8_signal_handler)5803 bool V8::EnableWebAssemblyTrapHandler(bool use_v8_signal_handler) {
5804 return v8::internal::trap_handler::EnableTrapHandler(use_v8_signal_handler);
5805 }
5806
5807 #if defined(V8_OS_WIN)
SetUnhandledExceptionCallback(UnhandledExceptionCallback unhandled_exception_callback)5808 void V8::SetUnhandledExceptionCallback(
5809 UnhandledExceptionCallback unhandled_exception_callback) {
5810 #if defined(V8_OS_WIN64)
5811 v8::internal::win64_unwindinfo::SetUnhandledExceptionCallback(
5812 unhandled_exception_callback);
5813 #else
5814 // Not implemented, port needed.
5815 #endif // V8_OS_WIN64
5816 }
5817 #endif // V8_OS_WIN
5818
SetEntropySource(EntropySource entropy_source)5819 void v8::V8::SetEntropySource(EntropySource entropy_source) {
5820 base::RandomNumberGenerator::SetEntropySource(entropy_source);
5821 }
5822
SetReturnAddressLocationResolver(ReturnAddressLocationResolver return_address_resolver)5823 void v8::V8::SetReturnAddressLocationResolver(
5824 ReturnAddressLocationResolver return_address_resolver) {
5825 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
5826 }
5827
Dispose()5828 bool v8::V8::Dispose() {
5829 i::V8::TearDown();
5830 return true;
5831 }
5832
SharedMemoryStatistics()5833 SharedMemoryStatistics::SharedMemoryStatistics()
5834 : read_only_space_size_(0),
5835 read_only_space_used_size_(0),
5836 read_only_space_physical_size_(0) {}
5837
HeapStatistics()5838 HeapStatistics::HeapStatistics()
5839 : total_heap_size_(0),
5840 total_heap_size_executable_(0),
5841 total_physical_size_(0),
5842 total_available_size_(0),
5843 used_heap_size_(0),
5844 heap_size_limit_(0),
5845 malloced_memory_(0),
5846 external_memory_(0),
5847 peak_malloced_memory_(0),
5848 does_zap_garbage_(false),
5849 number_of_native_contexts_(0),
5850 number_of_detached_contexts_(0) {}
5851
HeapSpaceStatistics()5852 HeapSpaceStatistics::HeapSpaceStatistics()
5853 : space_name_(nullptr),
5854 space_size_(0),
5855 space_used_size_(0),
5856 space_available_size_(0),
5857 physical_space_size_(0) {}
5858
HeapObjectStatistics()5859 HeapObjectStatistics::HeapObjectStatistics()
5860 : object_type_(nullptr),
5861 object_sub_type_(nullptr),
5862 object_count_(0),
5863 object_size_(0) {}
5864
HeapCodeStatistics()5865 HeapCodeStatistics::HeapCodeStatistics()
5866 : code_and_metadata_size_(0),
5867 bytecode_and_metadata_size_(0),
5868 external_script_source_size_(0) {}
5869
InitializeICU(const char * icu_data_file)5870 bool v8::V8::InitializeICU(const char* icu_data_file) {
5871 return i::InitializeICU(icu_data_file);
5872 }
5873
InitializeICUDefaultLocation(const char * exec_path,const char * icu_data_file)5874 bool v8::V8::InitializeICUDefaultLocation(const char* exec_path,
5875 const char* icu_data_file) {
5876 return i::InitializeICUDefaultLocation(exec_path, icu_data_file);
5877 }
5878
InitializeExternalStartupData(const char * directory_path)5879 void v8::V8::InitializeExternalStartupData(const char* directory_path) {
5880 i::InitializeExternalStartupData(directory_path);
5881 }
5882
5883 // static
InitializeExternalStartupDataFromFile(const char * snapshot_blob)5884 void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
5885 i::InitializeExternalStartupDataFromFile(snapshot_blob);
5886 }
5887
GetVersion()5888 const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
5889
GetSharedMemoryStatistics(SharedMemoryStatistics * statistics)5890 void V8::GetSharedMemoryStatistics(SharedMemoryStatistics* statistics) {
5891 i::ReadOnlyHeap::PopulateReadOnlySpaceStatistics(statistics);
5892 }
5893
SetIsCrossOriginIsolated()5894 void V8::SetIsCrossOriginIsolated() {
5895 i::FLAG_harmony_sharedarraybuffer = true;
5896 }
5897
5898 template <typename ObjectType>
5899 struct InvokeBootstrapper;
5900
5901 template <>
5902 struct InvokeBootstrapper<i::Context> {
Invokev8::InvokeBootstrapper5903 i::Handle<i::Context> Invoke(
5904 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
5905 v8::Local<v8::ObjectTemplate> global_proxy_template,
5906 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
5907 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
5908 v8::MicrotaskQueue* microtask_queue) {
5909 return isolate->bootstrapper()->CreateEnvironment(
5910 maybe_global_proxy, global_proxy_template, extensions,
5911 context_snapshot_index, embedder_fields_deserializer, microtask_queue);
5912 }
5913 };
5914
5915 template <>
5916 struct InvokeBootstrapper<i::JSGlobalProxy> {
Invokev8::InvokeBootstrapper5917 i::Handle<i::JSGlobalProxy> Invoke(
5918 i::Isolate* isolate, i::MaybeHandle<i::JSGlobalProxy> maybe_global_proxy,
5919 v8::Local<v8::ObjectTemplate> global_proxy_template,
5920 v8::ExtensionConfiguration* extensions, size_t context_snapshot_index,
5921 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
5922 v8::MicrotaskQueue* microtask_queue) {
5923 USE(extensions);
5924 USE(context_snapshot_index);
5925 return isolate->bootstrapper()->NewRemoteContext(maybe_global_proxy,
5926 global_proxy_template);
5927 }
5928 };
5929
5930 template <typename ObjectType>
CreateEnvironment(i::Isolate * isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> maybe_global_template,v8::MaybeLocal<Value> maybe_global_proxy,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)5931 static i::Handle<ObjectType> CreateEnvironment(
5932 i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
5933 v8::MaybeLocal<ObjectTemplate> maybe_global_template,
5934 v8::MaybeLocal<Value> maybe_global_proxy, size_t context_snapshot_index,
5935 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
5936 v8::MicrotaskQueue* microtask_queue) {
5937 i::Handle<ObjectType> result;
5938
5939 {
5940 ENTER_V8_FOR_NEW_CONTEXT(isolate);
5941 v8::Local<ObjectTemplate> proxy_template;
5942 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5943 i::Handle<i::FunctionTemplateInfo> global_constructor;
5944 i::Handle<i::HeapObject> named_interceptor(
5945 isolate->factory()->undefined_value());
5946 i::Handle<i::HeapObject> indexed_interceptor(
5947 isolate->factory()->undefined_value());
5948
5949 if (!maybe_global_template.IsEmpty()) {
5950 v8::Local<v8::ObjectTemplate> global_template =
5951 maybe_global_template.ToLocalChecked();
5952 // Make sure that the global_template has a constructor.
5953 global_constructor = EnsureConstructor(isolate, *global_template);
5954
5955 // Create a fresh template for the global proxy object.
5956 proxy_template =
5957 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate));
5958 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
5959
5960 // Set the global template to be the prototype template of
5961 // global proxy template.
5962 i::FunctionTemplateInfo::SetPrototypeTemplate(
5963 isolate, proxy_constructor, Utils::OpenHandle(*global_template));
5964
5965 proxy_template->SetInternalFieldCount(
5966 global_template->InternalFieldCount());
5967
5968 // Migrate security handlers from global_template to
5969 // proxy_template. Temporarily removing access check
5970 // information from the global template.
5971 if (!global_constructor->GetAccessCheckInfo().IsUndefined(isolate)) {
5972 i::FunctionTemplateInfo::SetAccessCheckInfo(
5973 isolate, proxy_constructor,
5974 i::handle(global_constructor->GetAccessCheckInfo(), isolate));
5975 proxy_constructor->set_needs_access_check(
5976 global_constructor->needs_access_check());
5977 global_constructor->set_needs_access_check(false);
5978 i::FunctionTemplateInfo::SetAccessCheckInfo(
5979 isolate, global_constructor,
5980 i::ReadOnlyRoots(isolate).undefined_value_handle());
5981 }
5982
5983 // Same for other interceptors. If the global constructor has
5984 // interceptors, we need to replace them temporarily with noop
5985 // interceptors, so the map is correctly marked as having interceptors,
5986 // but we don't invoke any.
5987 if (!global_constructor->GetNamedPropertyHandler().IsUndefined(isolate)) {
5988 named_interceptor =
5989 handle(global_constructor->GetNamedPropertyHandler(), isolate);
5990 i::FunctionTemplateInfo::SetNamedPropertyHandler(
5991 isolate, global_constructor,
5992 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
5993 }
5994 if (!global_constructor->GetIndexedPropertyHandler().IsUndefined(
5995 isolate)) {
5996 indexed_interceptor =
5997 handle(global_constructor->GetIndexedPropertyHandler(), isolate);
5998 i::FunctionTemplateInfo::SetIndexedPropertyHandler(
5999 isolate, global_constructor,
6000 i::ReadOnlyRoots(isolate).noop_interceptor_info_handle());
6001 }
6002 }
6003
6004 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
6005 if (!maybe_global_proxy.IsEmpty()) {
6006 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(
6007 Utils::OpenHandle(*maybe_global_proxy.ToLocalChecked()));
6008 }
6009 // Create the environment.
6010 InvokeBootstrapper<ObjectType> invoke;
6011 result = invoke.Invoke(isolate, maybe_proxy, proxy_template, extensions,
6012 context_snapshot_index, embedder_fields_deserializer,
6013 microtask_queue);
6014
6015 // Restore the access check info and interceptors on the global template.
6016 if (!maybe_global_template.IsEmpty()) {
6017 DCHECK(!global_constructor.is_null());
6018 DCHECK(!proxy_constructor.is_null());
6019 i::FunctionTemplateInfo::SetAccessCheckInfo(
6020 isolate, global_constructor,
6021 i::handle(proxy_constructor->GetAccessCheckInfo(), isolate));
6022 global_constructor->set_needs_access_check(
6023 proxy_constructor->needs_access_check());
6024 i::FunctionTemplateInfo::SetNamedPropertyHandler(
6025 isolate, global_constructor, named_interceptor);
6026 i::FunctionTemplateInfo::SetIndexedPropertyHandler(
6027 isolate, global_constructor, indexed_interceptor);
6028 }
6029 }
6030 // Leave V8.
6031
6032 return result;
6033 }
6034
NewContext(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6035 Local<Context> NewContext(
6036 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6037 v8::MaybeLocal<ObjectTemplate> global_template,
6038 v8::MaybeLocal<Value> global_object, size_t context_snapshot_index,
6039 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6040 v8::MicrotaskQueue* microtask_queue) {
6041 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6042 // TODO(jkummerow): This is for crbug.com/713699. Remove it if it doesn't
6043 // fail.
6044 // Sanity-check that the isolate is initialized and usable.
6045 CHECK(isolate->builtins()->builtin(i::Builtins::kIllegal).IsCode());
6046
6047 TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.NewContext");
6048 LOG_API(isolate, Context, New);
6049 i::HandleScope scope(isolate);
6050 ExtensionConfiguration no_extensions;
6051 if (extensions == nullptr) extensions = &no_extensions;
6052 i::Handle<i::Context> env = CreateEnvironment<i::Context>(
6053 isolate, extensions, global_template, global_object,
6054 context_snapshot_index, embedder_fields_deserializer, microtask_queue);
6055 if (env.is_null()) {
6056 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6057 return Local<Context>();
6058 }
6059 return Utils::ToLocal(scope.CloseAndEscape(env));
6060 }
6061
New(v8::Isolate * external_isolate,v8::ExtensionConfiguration * extensions,v8::MaybeLocal<ObjectTemplate> global_template,v8::MaybeLocal<Value> global_object,DeserializeInternalFieldsCallback internal_fields_deserializer,v8::MicrotaskQueue * microtask_queue)6062 Local<Context> v8::Context::New(
6063 v8::Isolate* external_isolate, v8::ExtensionConfiguration* extensions,
6064 v8::MaybeLocal<ObjectTemplate> global_template,
6065 v8::MaybeLocal<Value> global_object,
6066 DeserializeInternalFieldsCallback internal_fields_deserializer,
6067 v8::MicrotaskQueue* microtask_queue) {
6068 return NewContext(external_isolate, extensions, global_template,
6069 global_object, 0, internal_fields_deserializer,
6070 microtask_queue);
6071 }
6072
FromSnapshot(v8::Isolate * external_isolate,size_t context_snapshot_index,v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,v8::ExtensionConfiguration * extensions,MaybeLocal<Value> global_object,v8::MicrotaskQueue * microtask_queue)6073 MaybeLocal<Context> v8::Context::FromSnapshot(
6074 v8::Isolate* external_isolate, size_t context_snapshot_index,
6075 v8::DeserializeInternalFieldsCallback embedder_fields_deserializer,
6076 v8::ExtensionConfiguration* extensions, MaybeLocal<Value> global_object,
6077 v8::MicrotaskQueue* microtask_queue) {
6078 size_t index_including_default_context = context_snapshot_index + 1;
6079 if (!i::Snapshot::HasContextSnapshot(
6080 reinterpret_cast<i::Isolate*>(external_isolate),
6081 index_including_default_context)) {
6082 return MaybeLocal<Context>();
6083 }
6084 return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(),
6085 global_object, index_including_default_context,
6086 embedder_fields_deserializer, microtask_queue);
6087 }
6088
NewRemoteContext(v8::Isolate * external_isolate,v8::Local<ObjectTemplate> global_template,v8::MaybeLocal<v8::Value> global_object)6089 MaybeLocal<Object> v8::Context::NewRemoteContext(
6090 v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template,
6091 v8::MaybeLocal<v8::Value> global_object) {
6092 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
6093 LOG_API(isolate, Context, NewRemoteContext);
6094 i::HandleScope scope(isolate);
6095 i::Handle<i::FunctionTemplateInfo> global_constructor =
6096 EnsureConstructor(isolate, *global_template);
6097 Utils::ApiCheck(global_constructor->needs_access_check(),
6098 "v8::Context::NewRemoteContext",
6099 "Global template needs to have access checks enabled.");
6100 i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6101 i::AccessCheckInfo::cast(global_constructor->GetAccessCheckInfo()),
6102 isolate);
6103 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6104 "v8::Context::NewRemoteContext",
6105 "Global template needs to have access check handlers.");
6106 i::Handle<i::JSObject> global_proxy = CreateEnvironment<i::JSGlobalProxy>(
6107 isolate, nullptr, global_template, global_object, 0,
6108 DeserializeInternalFieldsCallback(), nullptr);
6109 if (global_proxy.is_null()) {
6110 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
6111 return MaybeLocal<Object>();
6112 }
6113 return Utils::ToLocal(scope.CloseAndEscape(global_proxy));
6114 }
6115
SetSecurityToken(Local<Value> token)6116 void v8::Context::SetSecurityToken(Local<Value> token) {
6117 i::Handle<i::Context> env = Utils::OpenHandle(this);
6118 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
6119 env->set_security_token(*token_handle);
6120 }
6121
UseDefaultSecurityToken()6122 void v8::Context::UseDefaultSecurityToken() {
6123 i::Handle<i::Context> env = Utils::OpenHandle(this);
6124 env->set_security_token(env->global_object());
6125 }
6126
GetSecurityToken()6127 Local<Value> v8::Context::GetSecurityToken() {
6128 i::Handle<i::Context> env = Utils::OpenHandle(this);
6129 i::Isolate* isolate = env->GetIsolate();
6130 i::Object security_token = env->security_token();
6131 i::Handle<i::Object> token_handle(security_token, isolate);
6132 return Utils::ToLocal(token_handle);
6133 }
6134
GetIsolate()6135 v8::Isolate* Context::GetIsolate() {
6136 i::Handle<i::Context> env = Utils::OpenHandle(this);
6137 return reinterpret_cast<Isolate*>(env->GetIsolate());
6138 }
6139
Global()6140 v8::Local<v8::Object> Context::Global() {
6141 i::Handle<i::Context> context = Utils::OpenHandle(this);
6142 i::Isolate* isolate = context->GetIsolate();
6143 i::Handle<i::Object> global(context->global_proxy(), isolate);
6144 // TODO(dcarney): This should always return the global proxy
6145 // but can't presently as calls to GetProtoype will return the wrong result.
6146 if (i::Handle<i::JSGlobalProxy>::cast(global)->IsDetachedFrom(
6147 context->global_object())) {
6148 global = i::Handle<i::Object>(context->global_object(), isolate);
6149 }
6150 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
6151 }
6152
DetachGlobal()6153 void Context::DetachGlobal() {
6154 i::Handle<i::Context> context = Utils::OpenHandle(this);
6155 i::Isolate* isolate = context->GetIsolate();
6156 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6157 isolate->bootstrapper()->DetachGlobal(context);
6158 }
6159
GetExtrasBindingObject()6160 Local<v8::Object> Context::GetExtrasBindingObject() {
6161 i::Handle<i::Context> context = Utils::OpenHandle(this);
6162 i::Isolate* isolate = context->GetIsolate();
6163 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
6164 return Utils::ToLocal(binding);
6165 }
6166
AllowCodeGenerationFromStrings(bool allow)6167 void Context::AllowCodeGenerationFromStrings(bool allow) {
6168 i::Handle<i::Context> context = Utils::OpenHandle(this);
6169 i::Isolate* isolate = context->GetIsolate();
6170 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6171 context->set_allow_code_gen_from_strings(
6172 allow ? i::ReadOnlyRoots(isolate).true_value()
6173 : i::ReadOnlyRoots(isolate).false_value());
6174 }
6175
IsCodeGenerationFromStringsAllowed()6176 bool Context::IsCodeGenerationFromStringsAllowed() {
6177 i::Handle<i::Context> context = Utils::OpenHandle(this);
6178 return !context->allow_code_gen_from_strings().IsFalse(context->GetIsolate());
6179 }
6180
SetErrorMessageForCodeGenerationFromStrings(Local<String> error)6181 void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
6182 i::Handle<i::Context> context = Utils::OpenHandle(this);
6183 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
6184 context->set_error_message_for_code_gen_from_strings(*error_handle);
6185 }
6186
SetAbortScriptExecution(Context::AbortScriptExecutionCallback callback)6187 void Context::SetAbortScriptExecution(
6188 Context::AbortScriptExecutionCallback callback) {
6189 i::Handle<i::Context> context = Utils::OpenHandle(this);
6190 i::Isolate* isolate = context->GetIsolate();
6191 if (callback == nullptr) {
6192 context->set_script_execution_callback(
6193 i::ReadOnlyRoots(isolate).undefined_value());
6194 } else {
6195 SET_FIELD_WRAPPED(isolate, context, set_script_execution_callback,
6196 callback);
6197 }
6198 }
6199
GetContinuationPreservedEmbedderData() const6200 Local<Value> Context::GetContinuationPreservedEmbedderData() const {
6201 i::Handle<i::Context> context = Utils::OpenHandle(this);
6202 i::Isolate* isolate = context->GetIsolate();
6203 i::Handle<i::Object> data(
6204 context->native_context().continuation_preserved_embedder_data(),
6205 isolate);
6206 return ToApiHandle<Object>(data);
6207 }
6208
SetContinuationPreservedEmbedderData(Local<Value> data)6209 void Context::SetContinuationPreservedEmbedderData(Local<Value> data) {
6210 i::Handle<i::Context> context = Utils::OpenHandle(this);
6211 i::Isolate* isolate = context->GetIsolate();
6212 if (data.IsEmpty())
6213 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6214 context->native_context().set_continuation_preserved_embedder_data(
6215 *i::Handle<i::HeapObject>::cast(Utils::OpenHandle(*data)));
6216 }
6217
GetContext(Isolate * isolate,metrics::Recorder::ContextId id)6218 MaybeLocal<Context> metrics::Recorder::GetContext(
6219 Isolate* isolate, metrics::Recorder::ContextId id) {
6220 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6221 return i_isolate->GetContextFromRecorderContextId(id);
6222 }
6223
GetContextId(Local<Context> context)6224 metrics::Recorder::ContextId metrics::Recorder::GetContextId(
6225 Local<Context> context) {
6226 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
6227 i::Isolate* isolate = i_context->GetIsolate();
6228 return isolate->GetOrRegisterRecorderContextId(
6229 handle(i_context->native_context(), isolate));
6230 }
6231
6232 namespace {
GetSerializedDataFromFixedArray(i::Isolate * isolate,i::FixedArray list,size_t index)6233 i::Address* GetSerializedDataFromFixedArray(i::Isolate* isolate,
6234 i::FixedArray list, size_t index) {
6235 if (index < static_cast<size_t>(list.length())) {
6236 int int_index = static_cast<int>(index);
6237 i::Object object = list.get(int_index);
6238 if (!object.IsTheHole(isolate)) {
6239 list.set_the_hole(isolate, int_index);
6240 // Shrink the list so that the last element is not the hole (unless it's
6241 // the first element, because we don't want to end up with a non-canonical
6242 // empty FixedArray).
6243 int last = list.length() - 1;
6244 while (last >= 0 && list.is_the_hole(isolate, last)) last--;
6245 if (last != -1) list.Shrink(isolate, last + 1);
6246 return i::Handle<i::Object>(object, isolate).location();
6247 }
6248 }
6249 return nullptr;
6250 }
6251 } // anonymous namespace
6252
GetDataFromSnapshotOnce(size_t index)6253 i::Address* Context::GetDataFromSnapshotOnce(size_t index) {
6254 auto context = Utils::OpenHandle(this);
6255 i::Isolate* i_isolate = context->GetIsolate();
6256 i::FixedArray list = context->serialized_objects();
6257 return GetSerializedDataFromFixedArray(i_isolate, list, index);
6258 }
6259
NewInstance(Local<Context> context)6260 MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
6261 PREPARE_FOR_EXECUTION(context, ObjectTemplate, NewInstance, Object);
6262 auto self = Utils::OpenHandle(this);
6263 Local<Object> result;
6264 has_pending_exception = !ToLocal<Object>(
6265 i::ApiNatives::InstantiateObject(isolate, self), &result);
6266 RETURN_ON_FAILED_EXECUTION(Object);
6267 RETURN_ESCAPED(result);
6268 }
6269
CheckCast(Data * that)6270 void v8::ObjectTemplate::CheckCast(Data* that) {
6271 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6272 Utils::ApiCheck(obj->IsObjectTemplateInfo(), "v8::ObjectTemplate::Cast",
6273 "Value is not an ObjectTemplate");
6274 }
6275
CheckCast(Data * that)6276 void v8::FunctionTemplate::CheckCast(Data* that) {
6277 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6278 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::FunctionTemplate::Cast",
6279 "Value is not a FunctionTemplate");
6280 }
6281
CheckCast(Data * that)6282 void v8::Signature::CheckCast(Data* that) {
6283 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6284 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::Signature::Cast",
6285 "Value is not a Signature");
6286 }
6287
CheckCast(Data * that)6288 void v8::AccessorSignature::CheckCast(Data* that) {
6289 i::Handle<i::Object> obj = Utils::OpenHandle(that);
6290 Utils::ApiCheck(obj->IsFunctionTemplateInfo(), "v8::AccessorSignature::Cast",
6291 "Value is not an AccessorSignature");
6292 }
6293
GetFunction(Local<Context> context)6294 MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
6295 PREPARE_FOR_EXECUTION(context, FunctionTemplate, GetFunction, Function);
6296 auto self = Utils::OpenHandle(this);
6297 Local<Function> result;
6298 has_pending_exception =
6299 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
6300 RETURN_ON_FAILED_EXECUTION(Function);
6301 RETURN_ESCAPED(result);
6302 }
6303
NewRemoteInstance()6304 MaybeLocal<v8::Object> FunctionTemplate::NewRemoteInstance() {
6305 auto self = Utils::OpenHandle(this);
6306 i::Isolate* isolate = self->GetIsolate();
6307 LOG_API(isolate, FunctionTemplate, NewRemoteInstance);
6308 i::HandleScope scope(isolate);
6309 i::Handle<i::FunctionTemplateInfo> constructor =
6310 EnsureConstructor(isolate, *InstanceTemplate());
6311 Utils::ApiCheck(constructor->needs_access_check(),
6312 "v8::FunctionTemplate::NewRemoteInstance",
6313 "InstanceTemplate needs to have access checks enabled.");
6314 i::Handle<i::AccessCheckInfo> access_check_info = i::handle(
6315 i::AccessCheckInfo::cast(constructor->GetAccessCheckInfo()), isolate);
6316 Utils::ApiCheck(access_check_info->named_interceptor() != i::Object(),
6317 "v8::FunctionTemplate::NewRemoteInstance",
6318 "InstanceTemplate needs to have access check handlers.");
6319 i::Handle<i::JSObject> object;
6320 if (!i::ApiNatives::InstantiateRemoteObject(
6321 Utils::OpenHandle(*InstanceTemplate()))
6322 .ToHandle(&object)) {
6323 if (isolate->has_pending_exception()) {
6324 isolate->OptionalRescheduleException(true);
6325 }
6326 return MaybeLocal<Object>();
6327 }
6328 return Utils::ToLocal(scope.CloseAndEscape(object));
6329 }
6330
HasInstance(v8::Local<v8::Value> value)6331 bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
6332 auto self = Utils::OpenHandle(this);
6333 auto obj = Utils::OpenHandle(*value);
6334 if (obj->IsJSObject() && self->IsTemplateFor(i::JSObject::cast(*obj))) {
6335 return true;
6336 }
6337 if (obj->IsJSGlobalProxy()) {
6338 // If it's a global proxy, then test with the global object. Note that the
6339 // inner global object may not necessarily be a JSGlobalObject.
6340 i::PrototypeIterator iter(self->GetIsolate(),
6341 i::JSObject::cast(*obj).map());
6342 // The global proxy should always have a prototype, as it is a bug to call
6343 // this on a detached JSGlobalProxy.
6344 DCHECK(!iter.IsAtEnd());
6345 return self->IsTemplateFor(iter.GetCurrent<i::JSObject>());
6346 }
6347 return false;
6348 }
6349
New(Isolate * isolate,void * value)6350 Local<External> v8::External::New(Isolate* isolate, void* value) {
6351 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
6352 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6353 LOG_API(i_isolate, External, New);
6354 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6355 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
6356 return Utils::ExternalToLocal(external);
6357 }
6358
Value() const6359 void* External::Value() const {
6360 return ExternalValue(*Utils::OpenHandle(this));
6361 }
6362
6363 // anonymous namespace for string creation helper functions
6364 namespace {
6365
StringLength(const char * string)6366 inline int StringLength(const char* string) {
6367 size_t len = strlen(string);
6368 CHECK_GE(i::kMaxInt, len);
6369 return static_cast<int>(len);
6370 }
6371
StringLength(const uint8_t * string)6372 inline int StringLength(const uint8_t* string) {
6373 return StringLength(reinterpret_cast<const char*>(string));
6374 }
6375
StringLength(const uint16_t * string)6376 inline int StringLength(const uint16_t* string) {
6377 size_t length = 0;
6378 while (string[length] != '\0') length++;
6379 CHECK_GE(i::kMaxInt, length);
6380 return static_cast<int>(length);
6381 }
6382
6383 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,i::Vector<const char> string)6384 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6385 NewStringType type,
6386 i::Vector<const char> string) {
6387 if (type == NewStringType::kInternalized) {
6388 return factory->InternalizeUtf8String(string);
6389 }
6390 return factory->NewStringFromUtf8(string);
6391 }
6392
6393 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,i::Vector<const uint8_t> string)6394 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6395 NewStringType type,
6396 i::Vector<const uint8_t> string) {
6397 if (type == NewStringType::kInternalized) {
6398 return factory->InternalizeString(string);
6399 }
6400 return factory->NewStringFromOneByte(string);
6401 }
6402
6403 V8_WARN_UNUSED_RESULT
NewString(i::Factory * factory,NewStringType type,i::Vector<const uint16_t> string)6404 inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
6405 NewStringType type,
6406 i::Vector<const uint16_t> string) {
6407 if (type == NewStringType::kInternalized) {
6408 return factory->InternalizeString(string);
6409 }
6410 return factory->NewStringFromTwoByte(string);
6411 }
6412
6413 STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
6414
6415 } // anonymous namespace
6416
6417 // TODO(dcarney): throw a context free exception.
6418 #define NEW_STRING(isolate, class_name, function_name, Char, data, type, \
6419 length) \
6420 MaybeLocal<String> result; \
6421 if (length == 0) { \
6422 result = String::Empty(isolate); \
6423 } else if (length > i::String::kMaxLength) { \
6424 result = MaybeLocal<String>(); \
6425 } else { \
6426 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate); \
6427 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); \
6428 LOG_API(i_isolate, class_name, function_name); \
6429 if (length < 0) length = StringLength(data); \
6430 i::Handle<i::String> handle_result = \
6431 NewString(i_isolate->factory(), type, \
6432 i::Vector<const Char>(data, length)) \
6433 .ToHandleChecked(); \
6434 result = Utils::ToLocal(handle_result); \
6435 }
6436
NewFromUtf8Literal(Isolate * isolate,const char * literal,NewStringType type,int length)6437 Local<String> String::NewFromUtf8Literal(Isolate* isolate, const char* literal,
6438 NewStringType type, int length) {
6439 DCHECK_LE(length, i::String::kMaxLength);
6440 i::Isolate* i_isolate = reinterpret_cast<internal::Isolate*>(isolate);
6441 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6442 LOG_API(i_isolate, String, NewFromUtf8Literal);
6443 i::Handle<i::String> handle_result =
6444 NewString(i_isolate->factory(), type,
6445 i::Vector<const char>(literal, length))
6446 .ToHandleChecked();
6447 return Utils::ToLocal(handle_result);
6448 }
6449
NewFromUtf8(Isolate * isolate,const char * data,NewStringType type,int length)6450 MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
6451 NewStringType type, int length) {
6452 NEW_STRING(isolate, String, NewFromUtf8, char, data, type, length);
6453 return result;
6454 }
6455
NewFromOneByte(Isolate * isolate,const uint8_t * data,NewStringType type,int length)6456 MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
6457 NewStringType type, int length) {
6458 NEW_STRING(isolate, String, NewFromOneByte, uint8_t, data, type, length);
6459 return result;
6460 }
6461
NewFromTwoByte(Isolate * isolate,const uint16_t * data,NewStringType type,int length)6462 MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
6463 const uint16_t* data,
6464 NewStringType type, int length) {
6465 NEW_STRING(isolate, String, NewFromTwoByte, uint16_t, data, type, length);
6466 return result;
6467 }
6468
Concat(Isolate * v8_isolate,Local<String> left,Local<String> right)6469 Local<String> v8::String::Concat(Isolate* v8_isolate, Local<String> left,
6470 Local<String> right) {
6471 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6472 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
6473 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6474 LOG_API(isolate, String, Concat);
6475 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
6476 // If we are steering towards a range error, do not wait for the error to be
6477 // thrown, and return the null handle instead.
6478 if (left_string->length() + right_string->length() > i::String::kMaxLength) {
6479 return Local<String>();
6480 }
6481 i::Handle<i::String> result = isolate->factory()
6482 ->NewConsString(left_string, right_string)
6483 .ToHandleChecked();
6484 return Utils::ToLocal(result);
6485 }
6486
NewExternalTwoByte(Isolate * isolate,v8::String::ExternalStringResource * resource)6487 MaybeLocal<String> v8::String::NewExternalTwoByte(
6488 Isolate* isolate, v8::String::ExternalStringResource* resource) {
6489 CHECK(resource && resource->data());
6490 // TODO(dcarney): throw a context free exception.
6491 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6492 return MaybeLocal<String>();
6493 }
6494 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6495 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6496 LOG_API(i_isolate, String, NewExternalTwoByte);
6497 if (resource->length() > 0) {
6498 i::Handle<i::String> string = i_isolate->factory()
6499 ->NewExternalStringFromTwoByte(resource)
6500 .ToHandleChecked();
6501 return Utils::ToLocal(string);
6502 } else {
6503 // The resource isn't going to be used, free it immediately.
6504 resource->Dispose();
6505 return Utils::ToLocal(i_isolate->factory()->empty_string());
6506 }
6507 }
6508
NewExternalOneByte(Isolate * isolate,v8::String::ExternalOneByteStringResource * resource)6509 MaybeLocal<String> v8::String::NewExternalOneByte(
6510 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
6511 CHECK_NOT_NULL(resource);
6512 // TODO(dcarney): throw a context free exception.
6513 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
6514 return MaybeLocal<String>();
6515 }
6516 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6517 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6518 LOG_API(i_isolate, String, NewExternalOneByte);
6519 if (resource->length() == 0) {
6520 // The resource isn't going to be used, free it immediately.
6521 resource->Dispose();
6522 return Utils::ToLocal(i_isolate->factory()->empty_string());
6523 }
6524 CHECK_NOT_NULL(resource->data());
6525 i::Handle<i::String> string = i_isolate->factory()
6526 ->NewExternalStringFromOneByte(resource)
6527 .ToHandleChecked();
6528 return Utils::ToLocal(string);
6529 }
6530
MakeExternal(v8::String::ExternalStringResource * resource)6531 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
6532 i::DisallowHeapAllocation no_allocation;
6533
6534 i::String obj = *Utils::OpenHandle(this);
6535
6536 if (obj.IsThinString()) {
6537 obj = i::ThinString::cast(obj).actual();
6538 }
6539
6540 if (!obj.SupportsExternalization()) {
6541 return false;
6542 }
6543
6544 // It is safe to call GetIsolateFromWritableHeapObject because
6545 // SupportsExternalization already checked that the object is writable.
6546 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6547 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6548
6549 CHECK(resource && resource->data());
6550
6551 bool result = obj.MakeExternal(resource);
6552 DCHECK(result);
6553 DCHECK(obj.IsExternalString());
6554 return result;
6555 }
6556
MakeExternal(v8::String::ExternalOneByteStringResource * resource)6557 bool v8::String::MakeExternal(
6558 v8::String::ExternalOneByteStringResource* resource) {
6559 i::DisallowHeapAllocation no_allocation;
6560
6561 i::String obj = *Utils::OpenHandle(this);
6562
6563 if (obj.IsThinString()) {
6564 obj = i::ThinString::cast(obj).actual();
6565 }
6566
6567 if (!obj.SupportsExternalization()) {
6568 return false;
6569 }
6570
6571 // It is safe to call GetIsolateFromWritableHeapObject because
6572 // SupportsExternalization already checked that the object is writable.
6573 i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
6574 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6575
6576 CHECK(resource && resource->data());
6577
6578 bool result = obj.MakeExternal(resource);
6579 DCHECK_IMPLIES(result, obj.IsExternalString());
6580 return result;
6581 }
6582
CanMakeExternal()6583 bool v8::String::CanMakeExternal() {
6584 i::DisallowHeapAllocation no_allocation;
6585 i::String obj = *Utils::OpenHandle(this);
6586
6587 if (obj.IsThinString()) {
6588 obj = i::ThinString::cast(obj).actual();
6589 }
6590
6591 if (!obj.SupportsExternalization()) {
6592 return false;
6593 }
6594
6595 // Only old space strings should be externalized.
6596 return !i::Heap::InYoungGeneration(obj);
6597 }
6598
StringEquals(Local<String> that)6599 bool v8::String::StringEquals(Local<String> that) {
6600 auto self = Utils::OpenHandle(this);
6601 auto other = Utils::OpenHandle(*that);
6602 return self->Equals(*other);
6603 }
6604
GetIsolate()6605 Isolate* v8::Object::GetIsolate() {
6606 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
6607 return reinterpret_cast<Isolate*>(i_isolate);
6608 }
6609
New(Isolate * isolate)6610 Local<v8::Object> v8::Object::New(Isolate* isolate) {
6611 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6612 LOG_API(i_isolate, Object, New);
6613 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6614 i::Handle<i::JSObject> obj =
6615 i_isolate->factory()->NewJSObject(i_isolate->object_function());
6616 return Utils::ToLocal(obj);
6617 }
6618
New(Isolate * isolate,Local<Value> prototype_or_null,Local<Name> * names,Local<Value> * values,size_t length)6619 Local<v8::Object> v8::Object::New(Isolate* isolate,
6620 Local<Value> prototype_or_null,
6621 Local<Name>* names, Local<Value>* values,
6622 size_t length) {
6623 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6624 i::Handle<i::Object> proto = Utils::OpenHandle(*prototype_or_null);
6625 if (!Utils::ApiCheck(proto->IsNull() || proto->IsJSReceiver(),
6626 "v8::Object::New", "prototype must be null or object")) {
6627 return Local<v8::Object>();
6628 }
6629 LOG_API(i_isolate, Object, New);
6630 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6631
6632 // We assume that this API is mostly used to create objects with named
6633 // properties, and so we default to creating a properties backing store
6634 // large enough to hold all of them, while we start with no elements
6635 // (see http://bit.ly/v8-fast-object-create-cpp for the motivation).
6636 i::Handle<i::NameDictionary> properties =
6637 i::NameDictionary::New(i_isolate, static_cast<int>(length));
6638 i::Handle<i::FixedArrayBase> elements =
6639 i_isolate->factory()->empty_fixed_array();
6640 for (size_t i = 0; i < length; ++i) {
6641 i::Handle<i::Name> name = Utils::OpenHandle(*names[i]);
6642 i::Handle<i::Object> value = Utils::OpenHandle(*values[i]);
6643
6644 // See if the {name} is a valid array index, in which case we need to
6645 // add the {name}/{value} pair to the {elements}, otherwise they end
6646 // up in the {properties} backing store.
6647 uint32_t index;
6648 if (name->AsArrayIndex(&index)) {
6649 // If this is the first element, allocate a proper
6650 // dictionary elements backing store for {elements}.
6651 if (!elements->IsNumberDictionary()) {
6652 elements =
6653 i::NumberDictionary::New(i_isolate, static_cast<int>(length));
6654 }
6655 elements = i::NumberDictionary::Set(
6656 i_isolate, i::Handle<i::NumberDictionary>::cast(elements), index,
6657 value);
6658 } else {
6659 // Internalize the {name} first.
6660 name = i_isolate->factory()->InternalizeName(name);
6661 i::InternalIndex const entry = properties->FindEntry(i_isolate, name);
6662 if (entry.is_not_found()) {
6663 // Add the {name}/{value} pair as a new entry.
6664 properties = i::NameDictionary::Add(i_isolate, properties, name, value,
6665 i::PropertyDetails::Empty());
6666 } else {
6667 // Overwrite the {entry} with the {value}.
6668 properties->ValueAtPut(entry, *value);
6669 }
6670 }
6671 }
6672 i::Handle<i::JSObject> obj =
6673 i_isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
6674 i::Handle<i::HeapObject>::cast(proto), properties, elements);
6675 return Utils::ToLocal(obj);
6676 }
6677
New(Isolate * isolate,double value)6678 Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
6679 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6680 LOG_API(i_isolate, NumberObject, New);
6681 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6682 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
6683 i::Handle<i::Object> obj =
6684 i::Object::ToObject(i_isolate, number).ToHandleChecked();
6685 return Utils::ToLocal(obj);
6686 }
6687
ValueOf() const6688 double v8::NumberObject::ValueOf() const {
6689 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6690 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
6691 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
6692 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
6693 LOG_API(isolate, NumberObject, NumberValue);
6694 return js_primitive_wrapper->value().Number();
6695 }
6696
New(Isolate * isolate,int64_t value)6697 Local<v8::Value> v8::BigIntObject::New(Isolate* isolate, int64_t value) {
6698 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6699 LOG_API(i_isolate, BigIntObject, New);
6700 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6701 i::Handle<i::Object> bigint = i::BigInt::FromInt64(i_isolate, value);
6702 i::Handle<i::Object> obj =
6703 i::Object::ToObject(i_isolate, bigint).ToHandleChecked();
6704 return Utils::ToLocal(obj);
6705 }
6706
ValueOf() const6707 Local<v8::BigInt> v8::BigIntObject::ValueOf() const {
6708 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6709 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
6710 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
6711 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
6712 LOG_API(isolate, BigIntObject, BigIntValue);
6713 return Utils::ToLocal(i::Handle<i::BigInt>(
6714 i::BigInt::cast(js_primitive_wrapper->value()), isolate));
6715 }
6716
New(Isolate * isolate,bool value)6717 Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
6718 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6719 LOG_API(i_isolate, BooleanObject, New);
6720 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6721 i::Handle<i::Object> boolean(value
6722 ? i::ReadOnlyRoots(i_isolate).true_value()
6723 : i::ReadOnlyRoots(i_isolate).false_value(),
6724 i_isolate);
6725 i::Handle<i::Object> obj =
6726 i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
6727 return Utils::ToLocal(obj);
6728 }
6729
ValueOf() const6730 bool v8::BooleanObject::ValueOf() const {
6731 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6732 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
6733 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
6734 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
6735 LOG_API(isolate, BooleanObject, BooleanValue);
6736 return js_primitive_wrapper->value().IsTrue(isolate);
6737 }
6738
New(Isolate * v8_isolate,Local<String> value)6739 Local<v8::Value> v8::StringObject::New(Isolate* v8_isolate,
6740 Local<String> value) {
6741 i::Handle<i::String> string = Utils::OpenHandle(*value);
6742 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
6743 LOG_API(isolate, StringObject, New);
6744 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6745 i::Handle<i::Object> obj =
6746 i::Object::ToObject(isolate, string).ToHandleChecked();
6747 return Utils::ToLocal(obj);
6748 }
6749
ValueOf() const6750 Local<v8::String> v8::StringObject::ValueOf() const {
6751 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6752 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
6753 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
6754 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
6755 LOG_API(isolate, StringObject, StringValue);
6756 return Utils::ToLocal(i::Handle<i::String>(
6757 i::String::cast(js_primitive_wrapper->value()), isolate));
6758 }
6759
New(Isolate * isolate,Local<Symbol> value)6760 Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
6761 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6762 LOG_API(i_isolate, SymbolObject, New);
6763 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6764 i::Handle<i::Object> obj =
6765 i::Object::ToObject(i_isolate, Utils::OpenHandle(*value))
6766 .ToHandleChecked();
6767 return Utils::ToLocal(obj);
6768 }
6769
ValueOf() const6770 Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
6771 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6772 i::Handle<i::JSPrimitiveWrapper> js_primitive_wrapper =
6773 i::Handle<i::JSPrimitiveWrapper>::cast(obj);
6774 i::Isolate* isolate = js_primitive_wrapper->GetIsolate();
6775 LOG_API(isolate, SymbolObject, SymbolValue);
6776 return Utils::ToLocal(i::Handle<i::Symbol>(
6777 i::Symbol::cast(js_primitive_wrapper->value()), isolate));
6778 }
6779
New(Local<Context> context,double time)6780 MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
6781 if (std::isnan(time)) {
6782 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6783 time = std::numeric_limits<double>::quiet_NaN();
6784 }
6785 PREPARE_FOR_EXECUTION(context, Date, New, Value);
6786 Local<Value> result;
6787 has_pending_exception = !ToLocal<Value>(
6788 i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
6789 &result);
6790 RETURN_ON_FAILED_EXECUTION(Value);
6791 RETURN_ESCAPED(result);
6792 }
6793
ValueOf() const6794 double v8::Date::ValueOf() const {
6795 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6796 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
6797 i::Isolate* isolate = jsdate->GetIsolate();
6798 LOG_API(isolate, Date, NumberValue);
6799 return jsdate->value().Number();
6800 }
6801
6802 // Assert that the static TimeZoneDetection cast in
6803 // DateTimeConfigurationChangeNotification is valid.
6804 #define TIME_ZONE_DETECTION_ASSERT_EQ(value) \
6805 STATIC_ASSERT( \
6806 static_cast<int>(v8::Isolate::TimeZoneDetection::value) == \
6807 static_cast<int>(base::TimezoneCache::TimeZoneDetection::value));
6808 TIME_ZONE_DETECTION_ASSERT_EQ(kSkip)
TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)6809 TIME_ZONE_DETECTION_ASSERT_EQ(kRedetect)
6810 #undef TIME_ZONE_DETECTION_ASSERT_EQ
6811
6812 MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
6813 Local<String> pattern, Flags flags) {
6814 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
6815 Local<v8::RegExp> result;
6816 has_pending_exception =
6817 !ToLocal<RegExp>(i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
6818 static_cast<i::JSRegExp::Flags>(flags)),
6819 &result);
6820 RETURN_ON_FAILED_EXECUTION(RegExp);
6821 RETURN_ESCAPED(result);
6822 }
6823
NewWithBacktrackLimit(Local<Context> context,Local<String> pattern,Flags flags,uint32_t backtrack_limit)6824 MaybeLocal<v8::RegExp> v8::RegExp::NewWithBacktrackLimit(
6825 Local<Context> context, Local<String> pattern, Flags flags,
6826 uint32_t backtrack_limit) {
6827 CHECK(i::Smi::IsValid(backtrack_limit));
6828 CHECK_NE(backtrack_limit, i::JSRegExp::kNoBacktrackLimit);
6829 PREPARE_FOR_EXECUTION(context, RegExp, New, RegExp);
6830 Local<v8::RegExp> result;
6831 has_pending_exception = !ToLocal<RegExp>(
6832 i::JSRegExp::New(isolate, Utils::OpenHandle(*pattern),
6833 static_cast<i::JSRegExp::Flags>(flags), backtrack_limit),
6834 &result);
6835 RETURN_ON_FAILED_EXECUTION(RegExp);
6836 RETURN_ESCAPED(result);
6837 }
6838
GetSource() const6839 Local<v8::String> v8::RegExp::GetSource() const {
6840 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
6841 return Utils::ToLocal(
6842 i::Handle<i::String>(obj->Pattern(), obj->GetIsolate()));
6843 }
6844
6845 // Assert that the static flags cast in GetFlags is valid.
6846 #define REGEXP_FLAG_ASSERT_EQ(flag) \
6847 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
6848 static_cast<int>(i::JSRegExp::flag))
6849 REGEXP_FLAG_ASSERT_EQ(kNone);
6850 REGEXP_FLAG_ASSERT_EQ(kGlobal);
6851 REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
6852 REGEXP_FLAG_ASSERT_EQ(kMultiline);
6853 REGEXP_FLAG_ASSERT_EQ(kSticky);
6854 REGEXP_FLAG_ASSERT_EQ(kUnicode);
6855 REGEXP_FLAG_ASSERT_EQ(kLinear);
6856 #undef REGEXP_FLAG_ASSERT_EQ
6857
GetFlags() const6858 v8::RegExp::Flags v8::RegExp::GetFlags() const {
6859 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
6860 return RegExp::Flags(static_cast<int>(obj->GetFlags()));
6861 }
6862
Exec(Local<Context> context,Local<v8::String> subject)6863 MaybeLocal<v8::Object> v8::RegExp::Exec(Local<Context> context,
6864 Local<v8::String> subject) {
6865 PREPARE_FOR_EXECUTION(context, RegExp, Exec, Object);
6866
6867 i::Handle<i::JSRegExp> regexp = Utils::OpenHandle(this);
6868 i::Handle<i::String> subject_string = Utils::OpenHandle(*subject);
6869
6870 // TODO(jgruber): RegExpUtils::RegExpExec was not written with efficiency in
6871 // mind. It fetches the 'exec' property and then calls it through JSEntry.
6872 // Unfortunately, this is currently the only full implementation of
6873 // RegExp.prototype.exec available in C++.
6874 Local<v8::Object> result;
6875 has_pending_exception = !ToLocal<Object>(
6876 i::RegExpUtils::RegExpExec(isolate, regexp, subject_string,
6877 isolate->factory()->undefined_value()),
6878 &result);
6879
6880 RETURN_ON_FAILED_EXECUTION(Object);
6881 RETURN_ESCAPED(result);
6882 }
6883
New(Isolate * isolate,int length)6884 Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
6885 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6886 LOG_API(i_isolate, Array, New);
6887 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6888 int real_length = length > 0 ? length : 0;
6889 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
6890 i::Handle<i::Object> length_obj =
6891 i_isolate->factory()->NewNumberFromInt(real_length);
6892 obj->set_length(*length_obj);
6893 return Utils::ToLocal(obj);
6894 }
6895
New(Isolate * isolate,Local<Value> * elements,size_t length)6896 Local<v8::Array> v8::Array::New(Isolate* isolate, Local<Value>* elements,
6897 size_t length) {
6898 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6899 i::Factory* factory = i_isolate->factory();
6900 LOG_API(i_isolate, Array, New);
6901 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6902 int len = static_cast<int>(length);
6903
6904 i::Handle<i::FixedArray> result = factory->NewFixedArray(len);
6905 for (int i = 0; i < len; i++) {
6906 i::Handle<i::Object> element = Utils::OpenHandle(*elements[i]);
6907 result->set(i, *element);
6908 }
6909
6910 return Utils::ToLocal(
6911 factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, len));
6912 }
6913
Length() const6914 uint32_t v8::Array::Length() const {
6915 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
6916 i::Object length = obj->length();
6917 if (length.IsSmi()) {
6918 return i::Smi::ToInt(length);
6919 } else {
6920 return static_cast<uint32_t>(length.Number());
6921 }
6922 }
6923
New(Isolate * isolate)6924 Local<v8::Map> v8::Map::New(Isolate* isolate) {
6925 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6926 LOG_API(i_isolate, Map, New);
6927 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
6928 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
6929 return Utils::ToLocal(obj);
6930 }
6931
Size() const6932 size_t v8::Map::Size() const {
6933 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
6934 return i::OrderedHashMap::cast(obj->table()).NumberOfElements();
6935 }
6936
Clear()6937 void Map::Clear() {
6938 auto self = Utils::OpenHandle(this);
6939 i::Isolate* isolate = self->GetIsolate();
6940 LOG_API(isolate, Map, Clear);
6941 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
6942 i::JSMap::Clear(isolate, self);
6943 }
6944
Get(Local<Context> context,Local<Value> key)6945 MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
6946 PREPARE_FOR_EXECUTION(context, Map, Get, Value);
6947 auto self = Utils::OpenHandle(this);
6948 Local<Value> result;
6949 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6950 has_pending_exception =
6951 !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->map_get(),
6952 self, arraysize(argv), argv),
6953 &result);
6954 RETURN_ON_FAILED_EXECUTION(Value);
6955 RETURN_ESCAPED(result);
6956 }
6957
Set(Local<Context> context,Local<Value> key,Local<Value> value)6958 MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
6959 Local<Value> value) {
6960 PREPARE_FOR_EXECUTION(context, Map, Set, Map);
6961 auto self = Utils::OpenHandle(this);
6962 i::Handle<i::Object> result;
6963 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
6964 Utils::OpenHandle(*value)};
6965 has_pending_exception =
6966 !i::Execution::CallBuiltin(isolate, isolate->map_set(), self,
6967 arraysize(argv), argv)
6968 .ToHandle(&result);
6969 RETURN_ON_FAILED_EXECUTION(Map);
6970 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
6971 }
6972
Has(Local<Context> context,Local<Value> key)6973 Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
6974 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
6975 ENTER_V8(isolate, context, Map, Has, Nothing<bool>(), i::HandleScope);
6976 auto self = Utils::OpenHandle(this);
6977 i::Handle<i::Object> result;
6978 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6979 has_pending_exception =
6980 !i::Execution::CallBuiltin(isolate, isolate->map_has(), self,
6981 arraysize(argv), argv)
6982 .ToHandle(&result);
6983 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6984 return Just(result->IsTrue(isolate));
6985 }
6986
Delete(Local<Context> context,Local<Value> key)6987 Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
6988 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
6989 ENTER_V8(isolate, context, Map, Delete, Nothing<bool>(), i::HandleScope);
6990 auto self = Utils::OpenHandle(this);
6991 i::Handle<i::Object> result;
6992 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6993 has_pending_exception =
6994 !i::Execution::CallBuiltin(isolate, isolate->map_delete(), self,
6995 arraysize(argv), argv)
6996 .ToHandle(&result);
6997 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6998 return Just(result->IsTrue(isolate));
6999 }
7000
7001 namespace {
7002
7003 enum class MapAsArrayKind {
7004 kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
7005 kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
7006 kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
7007 };
7008
7009 enum class SetAsArrayKind {
7010 kEntries = i::JS_SET_KEY_VALUE_ITERATOR_TYPE,
7011 kValues = i::JS_SET_VALUE_ITERATOR_TYPE
7012 };
7013
MapAsArray(i::Isolate * isolate,i::Object table_obj,int offset,MapAsArrayKind kind)7014 i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object table_obj,
7015 int offset, MapAsArrayKind kind) {
7016 i::Factory* factory = isolate->factory();
7017 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
7018 isolate);
7019 const bool collect_keys =
7020 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
7021 const bool collect_values =
7022 kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
7023 int capacity = table->UsedCapacity();
7024 int max_length =
7025 (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
7026 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7027 int result_index = 0;
7028 {
7029 i::DisallowHeapAllocation no_gc;
7030 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7031 for (int i = offset; i < capacity; ++i) {
7032 i::InternalIndex entry(i);
7033 i::Object key = table->KeyAt(entry);
7034 if (key == the_hole) continue;
7035 if (collect_keys) result->set(result_index++, key);
7036 if (collect_values) result->set(result_index++, table->ValueAt(entry));
7037 }
7038 }
7039 DCHECK_GE(max_length, result_index);
7040 if (result_index == 0) return factory->NewJSArray(0);
7041 result->Shrink(isolate, result_index);
7042 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7043 result_index);
7044 }
7045
7046 } // namespace
7047
AsArray() const7048 Local<Array> Map::AsArray() const {
7049 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
7050 i::Isolate* isolate = obj->GetIsolate();
7051 LOG_API(isolate, Map, AsArray);
7052 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7053 return Utils::ToLocal(
7054 MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
7055 }
7056
New(Isolate * isolate)7057 Local<v8::Set> v8::Set::New(Isolate* isolate) {
7058 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7059 LOG_API(i_isolate, Set, New);
7060 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7061 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
7062 return Utils::ToLocal(obj);
7063 }
7064
Size() const7065 size_t v8::Set::Size() const {
7066 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7067 return i::OrderedHashSet::cast(obj->table()).NumberOfElements();
7068 }
7069
Clear()7070 void Set::Clear() {
7071 auto self = Utils::OpenHandle(this);
7072 i::Isolate* isolate = self->GetIsolate();
7073 LOG_API(isolate, Set, Clear);
7074 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7075 i::JSSet::Clear(isolate, self);
7076 }
7077
Add(Local<Context> context,Local<Value> key)7078 MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
7079 PREPARE_FOR_EXECUTION(context, Set, Add, Set);
7080 auto self = Utils::OpenHandle(this);
7081 i::Handle<i::Object> result;
7082 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7083 has_pending_exception =
7084 !i::Execution::CallBuiltin(isolate, isolate->set_add(), self,
7085 arraysize(argv), argv)
7086 .ToHandle(&result);
7087 RETURN_ON_FAILED_EXECUTION(Set);
7088 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
7089 }
7090
Has(Local<Context> context,Local<Value> key)7091 Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
7092 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7093 ENTER_V8(isolate, context, Set, Has, Nothing<bool>(), i::HandleScope);
7094 auto self = Utils::OpenHandle(this);
7095 i::Handle<i::Object> result;
7096 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7097 has_pending_exception =
7098 !i::Execution::CallBuiltin(isolate, isolate->set_has(), self,
7099 arraysize(argv), argv)
7100 .ToHandle(&result);
7101 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7102 return Just(result->IsTrue(isolate));
7103 }
7104
Delete(Local<Context> context,Local<Value> key)7105 Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
7106 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7107 ENTER_V8(isolate, context, Set, Delete, Nothing<bool>(), i::HandleScope);
7108 auto self = Utils::OpenHandle(this);
7109 i::Handle<i::Object> result;
7110 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
7111 has_pending_exception =
7112 !i::Execution::CallBuiltin(isolate, isolate->set_delete(), self,
7113 arraysize(argv), argv)
7114 .ToHandle(&result);
7115 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7116 return Just(result->IsTrue(isolate));
7117 }
7118
7119 namespace {
SetAsArray(i::Isolate * isolate,i::Object table_obj,int offset,SetAsArrayKind kind)7120 i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object table_obj,
7121 int offset, SetAsArrayKind kind) {
7122 i::Factory* factory = isolate->factory();
7123 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
7124 isolate);
7125 // Elements skipped by |offset| may already be deleted.
7126 int capacity = table->UsedCapacity();
7127 const bool collect_key_values = kind == SetAsArrayKind::kEntries;
7128 int max_length = (capacity - offset) * (collect_key_values ? 2 : 1);
7129 if (max_length == 0) return factory->NewJSArray(0);
7130 i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
7131 int result_index = 0;
7132 {
7133 i::DisallowHeapAllocation no_gc;
7134 i::Oddball the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
7135 for (int i = offset; i < capacity; ++i) {
7136 i::InternalIndex entry(i);
7137 i::Object key = table->KeyAt(entry);
7138 if (key == the_hole) continue;
7139 result->set(result_index++, key);
7140 if (collect_key_values) result->set(result_index++, key);
7141 }
7142 }
7143 DCHECK_GE(max_length, result_index);
7144 if (result_index == 0) return factory->NewJSArray(0);
7145 result->Shrink(isolate, result_index);
7146 return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
7147 result_index);
7148 }
7149 } // namespace
7150
AsArray() const7151 Local<Array> Set::AsArray() const {
7152 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
7153 i::Isolate* isolate = obj->GetIsolate();
7154 LOG_API(isolate, Set, AsArray);
7155 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7156 return Utils::ToLocal(
7157 SetAsArray(isolate, obj->table(), 0, SetAsArrayKind::kValues));
7158 }
7159
New(Local<Context> context)7160 MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
7161 PREPARE_FOR_EXECUTION(context, Promise_Resolver, New, Resolver);
7162 Local<Promise::Resolver> result;
7163 has_pending_exception =
7164 !ToLocal<Promise::Resolver>(isolate->factory()->NewJSPromise(), &result);
7165 RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
7166 RETURN_ESCAPED(result);
7167 }
7168
GetPromise()7169 Local<Promise> Promise::Resolver::GetPromise() {
7170 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7171 return Local<Promise>::Cast(Utils::ToLocal(promise));
7172 }
7173
Resolve(Local<Context> context,Local<Value> value)7174 Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
7175 Local<Value> value) {
7176 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7177 ENTER_V8(isolate, context, Promise_Resolver, Resolve, Nothing<bool>(),
7178 i::HandleScope);
7179 auto self = Utils::OpenHandle(this);
7180 auto promise = i::Handle<i::JSPromise>::cast(self);
7181
7182 if (promise->status() != Promise::kPending) {
7183 return Just(true);
7184 }
7185
7186 has_pending_exception =
7187 i::JSPromise::Resolve(promise, Utils::OpenHandle(*value)).is_null();
7188 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7189 return Just(true);
7190 }
7191
Reject(Local<Context> context,Local<Value> value)7192 Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
7193 Local<Value> value) {
7194 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
7195 ENTER_V8(isolate, context, Promise_Resolver, Reject, Nothing<bool>(),
7196 i::HandleScope);
7197 auto self = Utils::OpenHandle(this);
7198 auto promise = i::Handle<i::JSPromise>::cast(self);
7199
7200 if (promise->status() != Promise::kPending) {
7201 return Just(true);
7202 }
7203
7204 has_pending_exception =
7205 i::JSPromise::Reject(promise, Utils::OpenHandle(*value)).is_null();
7206 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
7207 return Just(true);
7208 }
7209
Catch(Local<Context> context,Local<Function> handler)7210 MaybeLocal<Promise> Promise::Catch(Local<Context> context,
7211 Local<Function> handler) {
7212 PREPARE_FOR_EXECUTION(context, Promise, Catch, Promise);
7213 auto self = Utils::OpenHandle(this);
7214 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7215 i::Handle<i::Object> result;
7216 has_pending_exception =
7217 !i::Execution::CallBuiltin(isolate, isolate->promise_catch(), self,
7218 arraysize(argv), argv)
7219 .ToHandle(&result);
7220 RETURN_ON_FAILED_EXECUTION(Promise);
7221 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7222 }
7223
Then(Local<Context> context,Local<Function> handler)7224 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7225 Local<Function> handler) {
7226 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7227 auto self = Utils::OpenHandle(this);
7228 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
7229 i::Handle<i::Object> result;
7230 has_pending_exception =
7231 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7232 arraysize(argv), argv)
7233 .ToHandle(&result);
7234 RETURN_ON_FAILED_EXECUTION(Promise);
7235 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7236 }
7237
Then(Local<Context> context,Local<Function> on_fulfilled,Local<Function> on_rejected)7238 MaybeLocal<Promise> Promise::Then(Local<Context> context,
7239 Local<Function> on_fulfilled,
7240 Local<Function> on_rejected) {
7241 PREPARE_FOR_EXECUTION(context, Promise, Then, Promise);
7242 auto self = Utils::OpenHandle(this);
7243 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*on_fulfilled),
7244 Utils::OpenHandle(*on_rejected)};
7245 i::Handle<i::Object> result;
7246 has_pending_exception =
7247 !i::Execution::CallBuiltin(isolate, isolate->promise_then(), self,
7248 arraysize(argv), argv)
7249 .ToHandle(&result);
7250 RETURN_ON_FAILED_EXECUTION(Promise);
7251 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
7252 }
7253
HasHandler()7254 bool Promise::HasHandler() {
7255 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7256 i::Isolate* isolate = promise->GetIsolate();
7257 LOG_API(isolate, Promise, HasRejectHandler);
7258 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7259 if (promise->IsJSPromise()) {
7260 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7261 return js_promise->has_handler();
7262 }
7263 return false;
7264 }
7265
Result()7266 Local<Value> Promise::Result() {
7267 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7268 i::Isolate* isolate = promise->GetIsolate();
7269 LOG_API(isolate, Promise, Result);
7270 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7271 Utils::ApiCheck(js_promise->status() != kPending, "v8_Promise_Result",
7272 "Promise is still pending");
7273 i::Handle<i::Object> result(js_promise->result(), isolate);
7274 return Utils::ToLocal(result);
7275 }
7276
State()7277 Promise::PromiseState Promise::State() {
7278 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
7279 i::Isolate* isolate = promise->GetIsolate();
7280 LOG_API(isolate, Promise, Status);
7281 i::Handle<i::JSPromise> js_promise = i::Handle<i::JSPromise>::cast(promise);
7282 return static_cast<PromiseState>(js_promise->status());
7283 }
7284
MarkAsHandled()7285 void Promise::MarkAsHandled() {
7286 i::Handle<i::JSPromise> js_promise = Utils::OpenHandle(this);
7287 js_promise->set_has_handler(true);
7288 }
7289
GetTarget()7290 Local<Value> Proxy::GetTarget() {
7291 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7292 i::Handle<i::Object> target(self->target(), self->GetIsolate());
7293 return Utils::ToLocal(target);
7294 }
7295
GetHandler()7296 Local<Value> Proxy::GetHandler() {
7297 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7298 i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
7299 return Utils::ToLocal(handler);
7300 }
7301
IsRevoked()7302 bool Proxy::IsRevoked() {
7303 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7304 return self->IsRevoked();
7305 }
7306
Revoke()7307 void Proxy::Revoke() {
7308 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
7309 i::JSProxy::Revoke(self);
7310 }
7311
New(Local<Context> context,Local<Object> local_target,Local<Object> local_handler)7312 MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
7313 Local<Object> local_handler) {
7314 PREPARE_FOR_EXECUTION(context, Proxy, New, Proxy);
7315 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
7316 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
7317 Local<Proxy> result;
7318 has_pending_exception =
7319 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
7320 RETURN_ON_FAILED_EXECUTION(Proxy);
7321 RETURN_ESCAPED(result);
7322 }
7323
CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule> native_module,const char * source_url,size_t url_length)7324 CompiledWasmModule::CompiledWasmModule(
7325 std::shared_ptr<internal::wasm::NativeModule> native_module,
7326 const char* source_url, size_t url_length)
7327 : native_module_(std::move(native_module)),
7328 source_url_(source_url, url_length) {
7329 CHECK_NOT_NULL(native_module_);
7330 }
7331
Serialize()7332 OwnedBuffer CompiledWasmModule::Serialize() {
7333 TRACE_EVENT0("v8.wasm", "wasm.SerializeModule");
7334 i::wasm::WasmSerializer wasm_serializer(native_module_.get());
7335 size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
7336 std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
7337 if (!wasm_serializer.SerializeNativeModule({buffer.get(), buffer_size}))
7338 return {};
7339 return {std::move(buffer), buffer_size};
7340 }
7341
GetWireBytesRef()7342 MemorySpan<const uint8_t> CompiledWasmModule::GetWireBytesRef() {
7343 i::Vector<const uint8_t> bytes_vec = native_module_->wire_bytes();
7344 return {bytes_vec.begin(), bytes_vec.size()};
7345 }
7346
GetCompiledModule()7347 CompiledWasmModule WasmModuleObject::GetCompiledModule() {
7348 i::Handle<i::WasmModuleObject> obj =
7349 i::Handle<i::WasmModuleObject>::cast(Utils::OpenHandle(this));
7350 auto source_url = i::String::cast(obj->script().source_url());
7351 int length;
7352 std::unique_ptr<char[]> cstring = source_url.ToCString(
7353 i::DISALLOW_NULLS, i::FAST_STRING_TRAVERSAL, &length);
7354 i::Handle<i::String> url(source_url, obj->GetIsolate());
7355 return CompiledWasmModule(std::move(obj->shared_native_module()),
7356 cstring.get(), length);
7357 }
7358
FromCompiledModule(Isolate * isolate,const CompiledWasmModule & compiled_module)7359 MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
7360 Isolate* isolate, const CompiledWasmModule& compiled_module) {
7361 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7362 i::Handle<i::WasmModuleObject> module_object =
7363 i_isolate->wasm_engine()->ImportNativeModule(
7364 i_isolate, compiled_module.native_module_,
7365 i::VectorOf(compiled_module.source_url()));
7366 return Local<WasmModuleObject>::Cast(
7367 Utils::ToLocal(i::Handle<i::JSObject>::cast(module_object)));
7368 }
7369
WasmModuleObjectBuilderStreaming(Isolate * isolate)7370 WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
7371 Isolate* isolate) {
7372 USE(isolate_);
7373 }
7374
GetPromise()7375 Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() { return {}; }
7376
OnBytesReceived(const uint8_t * bytes,size_t size)7377 void WasmModuleObjectBuilderStreaming::OnBytesReceived(const uint8_t* bytes,
7378 size_t size) {}
7379
Finish()7380 void WasmModuleObjectBuilderStreaming::Finish() {}
7381
Abort(MaybeLocal<Value> exception)7382 void WasmModuleObjectBuilderStreaming::Abort(MaybeLocal<Value> exception) {}
7383
Reallocate(void * data,size_t old_length,size_t new_length)7384 void* v8::ArrayBuffer::Allocator::Reallocate(void* data, size_t old_length,
7385 size_t new_length) {
7386 if (old_length == new_length) return data;
7387 uint8_t* new_data =
7388 reinterpret_cast<uint8_t*>(AllocateUninitialized(new_length));
7389 if (new_data == nullptr) return nullptr;
7390 size_t bytes_to_copy = std::min(old_length, new_length);
7391 memcpy(new_data, data, bytes_to_copy);
7392 if (new_length > bytes_to_copy) {
7393 memset(new_data + bytes_to_copy, 0, new_length - bytes_to_copy);
7394 }
7395 Free(data, old_length);
7396 return new_data;
7397 }
7398
7399 // static
NewDefaultAllocator()7400 v8::ArrayBuffer::Allocator* v8::ArrayBuffer::Allocator::NewDefaultAllocator() {
7401 return new ArrayBufferAllocator();
7402 }
7403
IsExternal() const7404 bool v8::ArrayBuffer::IsExternal() const {
7405 return Utils::OpenHandle(this)->is_external();
7406 }
7407
IsDetachable() const7408 bool v8::ArrayBuffer::IsDetachable() const {
7409 return Utils::OpenHandle(this)->is_detachable();
7410 }
7411
7412 namespace {
7413 // The backing store deleter just deletes the indirection, which downrefs
7414 // the shared pointer. It will get collected normally.
BackingStoreDeleter(void * buffer,size_t length,void * info)7415 void BackingStoreDeleter(void* buffer, size_t length, void* info) {
7416 std::shared_ptr<i::BackingStore>* bs_indirection =
7417 reinterpret_cast<std::shared_ptr<i::BackingStore>*>(info);
7418 if (bs_indirection) {
7419 i::BackingStore* backing_store = bs_indirection->get();
7420 TRACE_BS("API:delete bs=%p mem=%p (length=%zu)\n", backing_store,
7421 backing_store->buffer_start(), backing_store->byte_length());
7422 USE(backing_store);
7423 }
7424 delete bs_indirection;
7425 }
7426
MakeDeleterData(std::shared_ptr<i::BackingStore> backing_store)7427 void* MakeDeleterData(std::shared_ptr<i::BackingStore> backing_store) {
7428 if (!backing_store) return nullptr;
7429 TRACE_BS("API:extern bs=%p mem=%p (length=%zu)\n", backing_store.get(),
7430 backing_store->buffer_start(), backing_store->byte_length());
7431 return new std::shared_ptr<i::BackingStore>(backing_store);
7432 }
7433
LookupOrCreateBackingStore(i::Isolate * i_isolate,void * data,size_t byte_length,i::SharedFlag shared,ArrayBufferCreationMode mode)7434 std::shared_ptr<i::BackingStore> LookupOrCreateBackingStore(
7435 i::Isolate* i_isolate, void* data, size_t byte_length, i::SharedFlag shared,
7436 ArrayBufferCreationMode mode) {
7437 // "internalized" means that the storage was allocated by the
7438 // ArrayBufferAllocator and thus should be freed upon destruction.
7439 bool free_on_destruct = mode == ArrayBufferCreationMode::kInternalized;
7440
7441 // Try to lookup a previously-registered backing store in the global
7442 // registry. If found, use that instead of wrapping an embedder allocation.
7443 std::shared_ptr<i::BackingStore> backing_store =
7444 i::GlobalBackingStoreRegistry::Lookup(data, byte_length);
7445
7446 if (backing_store) {
7447 // Check invariants for a previously-found backing store.
7448
7449 // 1. We cannot allow an embedder to first allocate a backing store that
7450 // should not be freed upon destruct, and then allocate an alias that should
7451 // destruct it. The other order is fine.
7452 bool changing_destruct_mode =
7453 free_on_destruct && !backing_store->free_on_destruct();
7454 Utils::ApiCheck(
7455 !changing_destruct_mode, "v8_[Shared]ArrayBuffer_New",
7456 "previous backing store found that should not be freed on destruct");
7457
7458 // 2. We cannot allow embedders to use the same backing store for both
7459 // SharedArrayBuffers and regular ArrayBuffers.
7460 bool changing_shared_flag =
7461 (shared == i::SharedFlag::kShared) != backing_store->is_shared();
7462 Utils::ApiCheck(
7463 !changing_shared_flag, "v8_[Shared]ArrayBuffer_New",
7464 "previous backing store found that does not match shared flag");
7465 } else {
7466 // No previous backing store found.
7467 backing_store = i::BackingStore::WrapAllocation(
7468 i_isolate, data, byte_length, shared, free_on_destruct);
7469
7470 // The embedder already has a direct pointer to the buffer start, so
7471 // globally register the backing store in case they come back with the
7472 // same buffer start and the backing store is marked as free_on_destruct.
7473 i::GlobalBackingStoreRegistry::Register(backing_store);
7474 }
7475 return backing_store;
7476 }
7477
ToInternal(std::shared_ptr<i::BackingStoreBase> backing_store)7478 std::shared_ptr<i::BackingStore> ToInternal(
7479 std::shared_ptr<i::BackingStoreBase> backing_store) {
7480 return std::static_pointer_cast<i::BackingStore>(backing_store);
7481 }
7482 } // namespace
7483
Contents(void * data,size_t byte_length,void * allocation_base,size_t allocation_length,Allocator::AllocationMode allocation_mode,DeleterCallback deleter,void * deleter_data)7484 v8::ArrayBuffer::Contents::Contents(void* data, size_t byte_length,
7485 void* allocation_base,
7486 size_t allocation_length,
7487 Allocator::AllocationMode allocation_mode,
7488 DeleterCallback deleter, void* deleter_data)
7489 : data_(data),
7490 byte_length_(byte_length),
7491 allocation_base_(allocation_base),
7492 allocation_length_(allocation_length),
7493 allocation_mode_(allocation_mode),
7494 deleter_(deleter),
7495 deleter_data_(deleter_data) {
7496 DCHECK_LE(allocation_base_, data_);
7497 DCHECK_LE(byte_length_, allocation_length_);
7498 }
7499
Externalize()7500 v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
7501 return GetContents(true);
7502 }
7503
Externalize(const std::shared_ptr<BackingStore> & backing_store)7504 void v8::ArrayBuffer::Externalize(
7505 const std::shared_ptr<BackingStore>& backing_store) {
7506 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7507 Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
7508 "ArrayBuffer already externalized");
7509 self->set_is_external(true);
7510 DCHECK_EQ(self->backing_store(), backing_store->Data());
7511 }
7512
GetContents()7513 v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
7514 return GetContents(false);
7515 }
7516
GetContents(bool externalize)7517 v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents(bool externalize) {
7518 // TODO(titzer): reduce duplication between shared/unshared GetContents()
7519 using BufferType = v8::ArrayBuffer;
7520
7521 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7522
7523 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
7524
7525 void* deleter_data = nullptr;
7526 if (externalize) {
7527 Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize",
7528 "ArrayBuffer already externalized");
7529 self->set_is_external(true);
7530 // When externalizing, upref the shared pointer to the backing store
7531 // and store that as the deleter data. When the embedder calls the deleter
7532 // callback, we will delete the additional (on-heap) shared_ptr.
7533 deleter_data = MakeDeleterData(backing_store);
7534 }
7535
7536 if (!backing_store) {
7537 // If the array buffer has zero length or was detached, return empty
7538 // contents.
7539 DCHECK_EQ(0, self->byte_length());
7540 BufferType::Contents contents(
7541 nullptr, 0, nullptr, 0,
7542 v8::ArrayBuffer::Allocator::AllocationMode::kNormal,
7543 BackingStoreDeleter, deleter_data);
7544 return contents;
7545 }
7546
7547 // Backing stores that given to the embedder might be passed back through
7548 // the API using only the start of the buffer. We need to find such
7549 // backing stores using global registration until the API is changed.
7550 i::GlobalBackingStoreRegistry::Register(backing_store);
7551
7552 auto allocation_mode =
7553 backing_store->is_wasm_memory()
7554 ? v8::ArrayBuffer::Allocator::AllocationMode::kReservation
7555 : v8::ArrayBuffer::Allocator::AllocationMode::kNormal;
7556
7557 BufferType::Contents contents(backing_store->buffer_start(), // --
7558 backing_store->byte_length(), // --
7559 backing_store->buffer_start(), // --
7560 backing_store->byte_length(), // --
7561 allocation_mode, // --
7562 BackingStoreDeleter, // --
7563 deleter_data);
7564 return contents;
7565 }
7566
Detach()7567 void v8::ArrayBuffer::Detach() {
7568 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7569 i::Isolate* isolate = obj->GetIsolate();
7570 Utils::ApiCheck(obj->is_detachable(), "v8::ArrayBuffer::Detach",
7571 "Only detachable ArrayBuffers can be detached");
7572 LOG_API(isolate, ArrayBuffer, Detach);
7573 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7574 obj->Detach();
7575 }
7576
ByteLength() const7577 size_t v8::ArrayBuffer::ByteLength() const {
7578 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7579 return obj->byte_length();
7580 }
7581
New(Isolate * isolate,size_t byte_length)7582 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
7583 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7584 LOG_API(i_isolate, ArrayBuffer, New);
7585 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7586 i::MaybeHandle<i::JSArrayBuffer> result =
7587 i_isolate->factory()->NewJSArrayBufferAndBackingStore(
7588 byte_length, i::InitializedFlag::kZeroInitialized);
7589
7590 i::Handle<i::JSArrayBuffer> array_buffer;
7591 if (!result.ToHandle(&array_buffer)) {
7592 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7593 // version that throws an exception or otherwise does not crash.
7594 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New");
7595 }
7596
7597 return Utils::ToLocal(array_buffer);
7598 }
7599
New(Isolate * isolate,void * data,size_t byte_length,ArrayBufferCreationMode mode)7600 Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
7601 size_t byte_length,
7602 ArrayBufferCreationMode mode) {
7603 // Embedders must guarantee that the external backing store is valid.
7604 CHECK_IMPLIES(byte_length != 0, data != nullptr);
7605 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7606 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7607 LOG_API(i_isolate, ArrayBuffer, New);
7608 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7609
7610 std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore(
7611 i_isolate, data, byte_length, i::SharedFlag::kNotShared, mode);
7612
7613 i::Handle<i::JSArrayBuffer> obj =
7614 i_isolate->factory()->NewJSArrayBuffer(std::move(backing_store));
7615 if (mode == ArrayBufferCreationMode::kExternalized) {
7616 obj->set_is_external(true);
7617 }
7618 return Utils::ToLocal(obj);
7619 }
7620
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7621 Local<ArrayBuffer> v8::ArrayBuffer::New(
7622 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7623 CHECK_IMPLIES(backing_store->ByteLength() != 0,
7624 backing_store->Data() != nullptr);
7625 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7626 LOG_API(i_isolate, ArrayBuffer, New);
7627 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7628 std::shared_ptr<i::BackingStore> i_backing_store(
7629 ToInternal(std::move(backing_store)));
7630 Utils::ApiCheck(
7631 !i_backing_store->is_shared(), "v8_ArrayBuffer_New",
7632 "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer");
7633 i::Handle<i::JSArrayBuffer> obj =
7634 i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store));
7635 return Utils::ToLocal(obj);
7636 }
7637
NewBackingStore(Isolate * isolate,size_t byte_length)7638 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7639 Isolate* isolate, size_t byte_length) {
7640 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7641 LOG_API(i_isolate, ArrayBuffer, NewBackingStore);
7642 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7643 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7644 std::unique_ptr<i::BackingStoreBase> backing_store =
7645 i::BackingStore::Allocate(i_isolate, byte_length,
7646 i::SharedFlag::kNotShared,
7647 i::InitializedFlag::kZeroInitialized);
7648 if (!backing_store) {
7649 i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore");
7650 }
7651 return std::unique_ptr<v8::BackingStore>(
7652 static_cast<v8::BackingStore*>(backing_store.release()));
7653 }
7654
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)7655 std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore(
7656 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
7657 void* deleter_data) {
7658 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7659 std::unique_ptr<i::BackingStoreBase> backing_store =
7660 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
7661 i::SharedFlag::kNotShared);
7662 return std::unique_ptr<v8::BackingStore>(
7663 static_cast<v8::BackingStore*>(backing_store.release()));
7664 }
7665
Buffer()7666 Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
7667 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7668 i::Handle<i::JSArrayBuffer> buffer;
7669 if (obj->IsJSDataView()) {
7670 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj),
7671 obj->GetIsolate());
7672 DCHECK(data_view->buffer().IsJSArrayBuffer());
7673 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()),
7674 data_view->GetIsolate());
7675 } else {
7676 DCHECK(obj->IsJSTypedArray());
7677 buffer = i::JSTypedArray::cast(*obj).GetBuffer();
7678 }
7679 return Utils::ToLocal(buffer);
7680 }
7681
CopyContents(void * dest,size_t byte_length)7682 size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
7683 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7684 size_t byte_offset = self->byte_offset();
7685 size_t bytes_to_copy = std::min(byte_length, self->byte_length());
7686 if (bytes_to_copy) {
7687 i::DisallowHeapAllocation no_gc;
7688 i::Isolate* isolate = self->GetIsolate();
7689 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()),
7690 isolate);
7691 const char* source = reinterpret_cast<char*>(buffer->backing_store());
7692 if (source == nullptr) {
7693 DCHECK(self->IsJSTypedArray());
7694 i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self),
7695 isolate);
7696 source = reinterpret_cast<char*>(typed_array->DataPtr());
7697 }
7698 memcpy(dest, source + byte_offset, bytes_to_copy);
7699 }
7700 return bytes_to_copy;
7701 }
7702
HasBuffer() const7703 bool v8::ArrayBufferView::HasBuffer() const {
7704 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
7705 if (!self->IsJSTypedArray()) return true;
7706 auto typed_array = i::Handle<i::JSTypedArray>::cast(self);
7707 return !typed_array->is_on_heap();
7708 }
7709
ByteOffset()7710 size_t v8::ArrayBufferView::ByteOffset() {
7711 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7712 return obj->WasDetached() ? 0 : obj->byte_offset();
7713 }
7714
ByteLength()7715 size_t v8::ArrayBufferView::ByteLength() {
7716 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
7717 return obj->WasDetached() ? 0 : obj->byte_length();
7718 }
7719
Length()7720 size_t v8::TypedArray::Length() {
7721 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
7722 return obj->WasDetached() ? 0 : obj->length();
7723 }
7724
7725 static_assert(
7726 v8::TypedArray::kMaxLength == i::JSTypedArray::kMaxLength,
7727 "v8::TypedArray::kMaxLength must match i::JSTypedArray::kMaxLength");
7728
7729 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype) \
7730 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
7731 size_t byte_offset, size_t length) { \
7732 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
7733 LOG_API(isolate, Type##Array, New); \
7734 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
7735 if (!Utils::ApiCheck(length <= kMaxLength, \
7736 "v8::" #Type \
7737 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
7738 "length exceeds max allowed value")) { \
7739 return Local<Type##Array>(); \
7740 } \
7741 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
7742 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
7743 i::kExternal##Type##Array, buffer, byte_offset, length); \
7744 return Utils::ToLocal##Type##Array(obj); \
7745 } \
7746 Local<Type##Array> Type##Array::New( \
7747 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
7748 size_t length) { \
7749 CHECK(i::FLAG_harmony_sharedarraybuffer); \
7750 i::Isolate* isolate = \
7751 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
7752 LOG_API(isolate, Type##Array, New); \
7753 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
7754 if (!Utils::ApiCheck( \
7755 length <= kMaxLength, \
7756 "v8::" #Type \
7757 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
7758 "length exceeds max allowed value")) { \
7759 return Local<Type##Array>(); \
7760 } \
7761 i::Handle<i::JSArrayBuffer> buffer = \
7762 Utils::OpenHandle(*shared_array_buffer); \
7763 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
7764 i::kExternal##Type##Array, buffer, byte_offset, length); \
7765 return Utils::ToLocal##Type##Array(obj); \
7766 }
7767
TYPED_ARRAYS(TYPED_ARRAY_NEW)7768 TYPED_ARRAYS(TYPED_ARRAY_NEW)
7769 #undef TYPED_ARRAY_NEW
7770
7771 Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
7772 size_t byte_offset, size_t byte_length) {
7773 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
7774 i::Isolate* isolate = buffer->GetIsolate();
7775 LOG_API(isolate, DataView, New);
7776 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7777 i::Handle<i::JSDataView> obj =
7778 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7779 return Utils::ToLocal(obj);
7780 }
7781
New(Local<SharedArrayBuffer> shared_array_buffer,size_t byte_offset,size_t byte_length)7782 Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
7783 size_t byte_offset, size_t byte_length) {
7784 CHECK(i::FLAG_harmony_sharedarraybuffer);
7785 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
7786 i::Isolate* isolate = buffer->GetIsolate();
7787 LOG_API(isolate, DataView, New);
7788 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
7789 i::Handle<i::JSDataView> obj =
7790 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
7791 return Utils::ToLocal(obj);
7792 }
7793
7794 namespace {
SetupSharedArrayBuffer(Isolate * isolate,void * data,size_t byte_length,ArrayBufferCreationMode mode)7795 i::Handle<i::JSArrayBuffer> SetupSharedArrayBuffer(
7796 Isolate* isolate, void* data, size_t byte_length,
7797 ArrayBufferCreationMode mode) {
7798 CHECK(i::FLAG_harmony_sharedarraybuffer);
7799 // Embedders must guarantee that the external backing store is valid.
7800 CHECK(byte_length == 0 || data != nullptr);
7801 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7802 LOG_API(i_isolate, SharedArrayBuffer, New);
7803 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7804
7805 std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore(
7806 i_isolate, data, byte_length, i::SharedFlag::kShared, mode);
7807
7808 i::Handle<i::JSArrayBuffer> obj =
7809 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
7810
7811 if (mode == ArrayBufferCreationMode::kExternalized) {
7812 obj->set_is_external(true);
7813 }
7814 return obj;
7815 }
7816
7817 } // namespace
7818
IsExternal() const7819 bool v8::SharedArrayBuffer::IsExternal() const {
7820 return Utils::OpenHandle(this)->is_external();
7821 }
7822
Contents(void * data,size_t byte_length,void * allocation_base,size_t allocation_length,Allocator::AllocationMode allocation_mode,DeleterCallback deleter,void * deleter_data)7823 v8::SharedArrayBuffer::Contents::Contents(
7824 void* data, size_t byte_length, void* allocation_base,
7825 size_t allocation_length, Allocator::AllocationMode allocation_mode,
7826 DeleterCallback deleter, void* deleter_data)
7827 : data_(data),
7828 byte_length_(byte_length),
7829 allocation_base_(allocation_base),
7830 allocation_length_(allocation_length),
7831 allocation_mode_(allocation_mode),
7832 deleter_(deleter),
7833 deleter_data_(deleter_data) {
7834 DCHECK_LE(allocation_base_, data_);
7835 DCHECK_LE(byte_length_, allocation_length_);
7836 }
7837
Externalize()7838 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
7839 return GetContents(true);
7840 }
7841
Externalize(const std::shared_ptr<BackingStore> & backing_store)7842 void v8::SharedArrayBuffer::Externalize(
7843 const std::shared_ptr<BackingStore>& backing_store) {
7844 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7845 Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
7846 "SharedArrayBuffer already externalized");
7847 self->set_is_external(true);
7848
7849 DCHECK_EQ(self->backing_store(), backing_store->Data());
7850 }
7851
GetContents()7852 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
7853 return GetContents(false);
7854 }
7855
GetContents(bool externalize)7856 v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents(
7857 bool externalize) {
7858 // TODO(titzer): reduce duplication between shared/unshared GetContents()
7859 using BufferType = v8::SharedArrayBuffer;
7860
7861 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
7862
7863 std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore();
7864
7865 void* deleter_data = nullptr;
7866 if (externalize) {
7867 Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize",
7868 "SharedArrayBuffer already externalized");
7869 self->set_is_external(true);
7870 // When externalizing, upref the shared pointer to the backing store
7871 // and store that as the deleter data. When the embedder calls the deleter
7872 // callback, we will delete the additional (on-heap) shared_ptr.
7873 deleter_data = MakeDeleterData(backing_store);
7874 }
7875
7876 if (!backing_store) {
7877 // If the array buffer has zero length or was detached, return empty
7878 // contents.
7879 DCHECK_EQ(0, self->byte_length());
7880 BufferType::Contents contents(
7881 nullptr, 0, nullptr, 0,
7882 v8::ArrayBuffer::Allocator::AllocationMode::kNormal,
7883 BackingStoreDeleter, deleter_data);
7884 return contents;
7885 }
7886
7887 // Backing stores that given to the embedder might be passed back through
7888 // the API using only the start of the buffer. We need to find such
7889 // backing stores using global registration until the API is changed.
7890 i::GlobalBackingStoreRegistry::Register(backing_store);
7891
7892 auto allocation_mode =
7893 backing_store->is_wasm_memory()
7894 ? v8::ArrayBuffer::Allocator::AllocationMode::kReservation
7895 : v8::ArrayBuffer::Allocator::AllocationMode::kNormal;
7896
7897 BufferType::Contents contents(backing_store->buffer_start(), // --
7898 backing_store->byte_length(), // --
7899 backing_store->buffer_start(), // --
7900 backing_store->byte_length(), // --
7901 allocation_mode, // --
7902 BackingStoreDeleter, // --
7903 deleter_data);
7904 return contents;
7905 }
7906
ByteLength() const7907 size_t v8::SharedArrayBuffer::ByteLength() const {
7908 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
7909 return obj->byte_length();
7910 }
7911
New(Isolate * isolate,size_t byte_length)7912 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
7913 size_t byte_length) {
7914 CHECK(i::FLAG_harmony_sharedarraybuffer);
7915 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7916 LOG_API(i_isolate, SharedArrayBuffer, New);
7917 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7918
7919 std::unique_ptr<i::BackingStore> backing_store =
7920 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
7921 i::InitializedFlag::kZeroInitialized);
7922
7923 if (!backing_store) {
7924 // TODO(jbroman): It may be useful in the future to provide a MaybeLocal
7925 // version that throws an exception or otherwise does not crash.
7926 i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New");
7927 }
7928
7929 i::Handle<i::JSArrayBuffer> obj =
7930 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store));
7931 return Utils::ToLocalShared(obj);
7932 }
7933
New(Isolate * isolate,void * data,size_t byte_length,ArrayBufferCreationMode mode)7934 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
7935 Isolate* isolate, void* data, size_t byte_length,
7936 ArrayBufferCreationMode mode) {
7937 i::Handle<i::JSArrayBuffer> buffer =
7938 SetupSharedArrayBuffer(isolate, data, byte_length, mode);
7939 return Utils::ToLocalShared(buffer);
7940 }
7941
New(Isolate * isolate,std::shared_ptr<BackingStore> backing_store)7942 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
7943 Isolate* isolate, std::shared_ptr<BackingStore> backing_store) {
7944 CHECK(i::FLAG_harmony_sharedarraybuffer);
7945 CHECK_IMPLIES(backing_store->ByteLength() != 0,
7946 backing_store->Data() != nullptr);
7947 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7948 LOG_API(i_isolate, SharedArrayBuffer, New);
7949 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7950 std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store));
7951 Utils::ApiCheck(
7952 i_backing_store->is_shared(), "v8_SharedArrayBuffer_New",
7953 "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer");
7954 i::Handle<i::JSArrayBuffer> obj =
7955 i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store));
7956 return Utils::ToLocalShared(obj);
7957 }
7958
New(Isolate * isolate,const SharedArrayBuffer::Contents & contents,ArrayBufferCreationMode mode)7959 Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
7960 Isolate* isolate, const SharedArrayBuffer::Contents& contents,
7961 ArrayBufferCreationMode mode) {
7962 i::Handle<i::JSArrayBuffer> buffer = SetupSharedArrayBuffer(
7963 isolate, contents.Data(), contents.ByteLength(), mode);
7964 return Utils::ToLocalShared(buffer);
7965 }
7966
NewBackingStore(Isolate * isolate,size_t byte_length)7967 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
7968 Isolate* isolate, size_t byte_length) {
7969 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7970 LOG_API(i_isolate, SharedArrayBuffer, NewBackingStore);
7971 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7972 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7973 std::unique_ptr<i::BackingStoreBase> backing_store =
7974 i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared,
7975 i::InitializedFlag::kZeroInitialized);
7976 if (!backing_store) {
7977 i::FatalProcessOutOfMemory(i_isolate,
7978 "v8::SharedArrayBuffer::NewBackingStore");
7979 }
7980 return std::unique_ptr<v8::BackingStore>(
7981 static_cast<v8::BackingStore*>(backing_store.release()));
7982 }
7983
NewBackingStore(void * data,size_t byte_length,v8::BackingStore::DeleterCallback deleter,void * deleter_data)7984 std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore(
7985 void* data, size_t byte_length, v8::BackingStore::DeleterCallback deleter,
7986 void* deleter_data) {
7987 CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength);
7988 std::unique_ptr<i::BackingStoreBase> backing_store =
7989 i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data,
7990 i::SharedFlag::kShared);
7991 return std::unique_ptr<v8::BackingStore>(
7992 static_cast<v8::BackingStore*>(backing_store.release()));
7993 }
7994
New(Isolate * isolate,Local<String> name)7995 Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
7996 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7997 LOG_API(i_isolate, Symbol, New);
7998 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
7999 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
8000 if (!name.IsEmpty()) result->set_description(*Utils::OpenHandle(*name));
8001 return Utils::ToLocal(result);
8002 }
8003
For(Isolate * isolate,Local<String> name)8004 Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
8005 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8006 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8007 return Utils::ToLocal(
8008 i_isolate->SymbolFor(i::RootIndex::kPublicSymbolTable, i_name, false));
8009 }
8010
ForApi(Isolate * isolate,Local<String> name)8011 Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
8012 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8013 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8014 return Utils::ToLocal(
8015 i_isolate->SymbolFor(i::RootIndex::kApiSymbolTable, i_name, false));
8016 }
8017
8018 #define WELL_KNOWN_SYMBOLS(V) \
8019 V(AsyncIterator, async_iterator) \
8020 V(HasInstance, has_instance) \
8021 V(IsConcatSpreadable, is_concat_spreadable) \
8022 V(Iterator, iterator) \
8023 V(Match, match) \
8024 V(Replace, replace) \
8025 V(Search, search) \
8026 V(Split, split) \
8027 V(ToPrimitive, to_primitive) \
8028 V(ToStringTag, to_string_tag) \
8029 V(Unscopables, unscopables)
8030
8031 #define SYMBOL_GETTER(Name, name) \
8032 Local<Symbol> v8::Symbol::Get##Name(Isolate* isolate) { \
8033 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \
8034 return Utils::ToLocal(i_isolate->factory()->name##_symbol()); \
8035 }
8036
WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)8037 WELL_KNOWN_SYMBOLS(SYMBOL_GETTER)
8038
8039 #undef SYMBOL_GETTER
8040 #undef WELL_KNOWN_SYMBOLS
8041
8042 Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
8043 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8044 LOG_API(i_isolate, Private, New);
8045 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
8046 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
8047 if (!name.IsEmpty()) symbol->set_description(*Utils::OpenHandle(*name));
8048 Local<Symbol> result = Utils::ToLocal(symbol);
8049 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8050 }
8051
ForApi(Isolate * isolate,Local<String> name)8052 Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
8053 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8054 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
8055 Local<Symbol> result = Utils::ToLocal(
8056 i_isolate->SymbolFor(i::RootIndex::kApiPrivateSymbolTable, i_name, true));
8057 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
8058 }
8059
New(Isolate * isolate,double value)8060 Local<Number> v8::Number::New(Isolate* isolate, double value) {
8061 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8062 if (std::isnan(value)) {
8063 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
8064 value = std::numeric_limits<double>::quiet_NaN();
8065 }
8066 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8067 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8068 return Utils::NumberToLocal(result);
8069 }
8070
New(Isolate * isolate,int32_t value)8071 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
8072 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8073 if (i::Smi::IsValid(value)) {
8074 return Utils::IntegerToLocal(
8075 i::Handle<i::Object>(i::Smi::FromInt(value), internal_isolate));
8076 }
8077 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8078 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8079 return Utils::IntegerToLocal(result);
8080 }
8081
NewFromUnsigned(Isolate * isolate,uint32_t value)8082 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
8083 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8084 bool fits_into_int32_t = (value & (1 << 31)) == 0;
8085 if (fits_into_int32_t) {
8086 return Integer::New(isolate, static_cast<int32_t>(value));
8087 }
8088 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8089 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
8090 return Utils::IntegerToLocal(result);
8091 }
8092
New(Isolate * isolate,int64_t value)8093 Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) {
8094 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8095 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8096 i::Handle<i::BigInt> result = i::BigInt::FromInt64(internal_isolate, value);
8097 return Utils::ToLocal(result);
8098 }
8099
NewFromUnsigned(Isolate * isolate,uint64_t value)8100 Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) {
8101 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8102 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate);
8103 i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value);
8104 return Utils::ToLocal(result);
8105 }
8106
NewFromWords(Local<Context> context,int sign_bit,int word_count,const uint64_t * words)8107 MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context,
8108 int sign_bit, int word_count,
8109 const uint64_t* words) {
8110 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
8111 ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords,
8112 MaybeLocal<BigInt>(), InternalEscapableScope);
8113 i::MaybeHandle<i::BigInt> result =
8114 i::BigInt::FromWords64(isolate, sign_bit, word_count, words);
8115 has_pending_exception = result.is_null();
8116 RETURN_ON_FAILED_EXECUTION(BigInt);
8117 RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked()));
8118 }
8119
Uint64Value(bool * lossless) const8120 uint64_t v8::BigInt::Uint64Value(bool* lossless) const {
8121 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8122 return handle->AsUint64(lossless);
8123 }
8124
Int64Value(bool * lossless) const8125 int64_t v8::BigInt::Int64Value(bool* lossless) const {
8126 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8127 return handle->AsInt64(lossless);
8128 }
8129
WordCount() const8130 int BigInt::WordCount() const {
8131 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8132 return handle->Words64Count();
8133 }
8134
ToWordsArray(int * sign_bit,int * word_count,uint64_t * words) const8135 void BigInt::ToWordsArray(int* sign_bit, int* word_count,
8136 uint64_t* words) const {
8137 i::Handle<i::BigInt> handle = Utils::OpenHandle(this);
8138 return handle->ToWordsArray64(sign_bit, word_count, words);
8139 }
8140
ReportExternalAllocationLimitReached()8141 void Isolate::ReportExternalAllocationLimitReached() {
8142 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
8143 if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
8144 heap->ReportExternalMemoryPressure();
8145 }
8146
GetHeapProfiler()8147 HeapProfiler* Isolate::GetHeapProfiler() {
8148 i::HeapProfiler* heap_profiler =
8149 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
8150 return reinterpret_cast<HeapProfiler*>(heap_profiler);
8151 }
8152
SetIdle(bool is_idle)8153 void Isolate::SetIdle(bool is_idle) {
8154 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8155 isolate->SetIdle(is_idle);
8156 }
8157
GetArrayBufferAllocator()8158 ArrayBuffer::Allocator* Isolate::GetArrayBufferAllocator() {
8159 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8160 return isolate->array_buffer_allocator();
8161 }
8162
InContext()8163 bool Isolate::InContext() {
8164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8165 return !isolate->context().is_null();
8166 }
8167
ClearKeptObjects()8168 void Isolate::ClearKeptObjects() {
8169 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8170 isolate->ClearKeptObjects();
8171 }
8172
GetCurrentContext()8173 v8::Local<v8::Context> Isolate::GetCurrentContext() {
8174 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8175 i::Context context = isolate->context();
8176 if (context.is_null()) return Local<Context>();
8177 i::Context native_context = context.native_context();
8178 if (native_context.is_null()) return Local<Context>();
8179 return Utils::ToLocal(i::Handle<i::Context>(native_context, isolate));
8180 }
8181
GetEnteredContext()8182 v8::Local<v8::Context> Isolate::GetEnteredContext() {
8183 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8184 i::Handle<i::Object> last =
8185 isolate->handle_scope_implementer()->LastEnteredContext();
8186 if (last.is_null()) return Local<Context>();
8187 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8188 }
8189
GetEnteredOrMicrotaskContext()8190 v8::Local<v8::Context> Isolate::GetEnteredOrMicrotaskContext() {
8191 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8192 i::Handle<i::Object> last =
8193 isolate->handle_scope_implementer()->LastEnteredOrMicrotaskContext();
8194 if (last.is_null()) return Local<Context>();
8195 DCHECK(last->IsNativeContext());
8196 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
8197 }
8198
GetIncumbentContext()8199 v8::Local<v8::Context> Isolate::GetIncumbentContext() {
8200 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8201 i::Handle<i::Context> context = isolate->GetIncumbentContext();
8202 return Utils::ToLocal(context);
8203 }
8204
ThrowException(v8::Local<v8::Value> value)8205 v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
8206 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8207 ENTER_V8_DO_NOT_USE(isolate);
8208 // If we're passed an empty handle, we throw an undefined exception
8209 // to deal more gracefully with out of memory situations.
8210 if (value.IsEmpty()) {
8211 isolate->ScheduleThrow(i::ReadOnlyRoots(isolate).undefined_value());
8212 } else {
8213 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
8214 }
8215 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
8216 }
8217
AddGCPrologueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8218 void Isolate::AddGCPrologueCallback(GCCallbackWithData callback, void* data,
8219 GCType gc_type) {
8220 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8221 isolate->heap()->AddGCPrologueCallback(callback, gc_type, data);
8222 }
8223
RemoveGCPrologueCallback(GCCallbackWithData callback,void * data)8224 void Isolate::RemoveGCPrologueCallback(GCCallbackWithData callback,
8225 void* data) {
8226 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8227 isolate->heap()->RemoveGCPrologueCallback(callback, data);
8228 }
8229
AddGCEpilogueCallback(GCCallbackWithData callback,void * data,GCType gc_type)8230 void Isolate::AddGCEpilogueCallback(GCCallbackWithData callback, void* data,
8231 GCType gc_type) {
8232 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8233 isolate->heap()->AddGCEpilogueCallback(callback, gc_type, data);
8234 }
8235
RemoveGCEpilogueCallback(GCCallbackWithData callback,void * data)8236 void Isolate::RemoveGCEpilogueCallback(GCCallbackWithData callback,
8237 void* data) {
8238 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8239 isolate->heap()->RemoveGCEpilogueCallback(callback, data);
8240 }
8241
CallGCCallbackWithoutData(Isolate * isolate,GCType type,GCCallbackFlags flags,void * data)8242 static void CallGCCallbackWithoutData(Isolate* isolate, GCType type,
8243 GCCallbackFlags flags, void* data) {
8244 reinterpret_cast<Isolate::GCCallback>(data)(isolate, type, flags);
8245 }
8246
AddGCPrologueCallback(GCCallback callback,GCType gc_type)8247 void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
8248 void* data = reinterpret_cast<void*>(callback);
8249 AddGCPrologueCallback(CallGCCallbackWithoutData, data, gc_type);
8250 }
8251
RemoveGCPrologueCallback(GCCallback callback)8252 void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
8253 void* data = reinterpret_cast<void*>(callback);
8254 RemoveGCPrologueCallback(CallGCCallbackWithoutData, data);
8255 }
8256
AddGCEpilogueCallback(GCCallback callback,GCType gc_type)8257 void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
8258 void* data = reinterpret_cast<void*>(callback);
8259 AddGCEpilogueCallback(CallGCCallbackWithoutData, data, gc_type);
8260 }
8261
RemoveGCEpilogueCallback(GCCallback callback)8262 void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
8263 void* data = reinterpret_cast<void*>(callback);
8264 RemoveGCEpilogueCallback(CallGCCallbackWithoutData, data);
8265 }
8266
SetEmbedderHeapTracer(EmbedderHeapTracer * tracer)8267 void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
8268 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8269 isolate->heap()->SetEmbedderHeapTracer(tracer);
8270 }
8271
GetEmbedderHeapTracer()8272 EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
8273 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8274 return isolate->heap()->GetEmbedderHeapTracer();
8275 }
8276
SetGetExternallyAllocatedMemoryInBytesCallback(GetExternallyAllocatedMemoryInBytesCallback callback)8277 void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
8278 GetExternallyAllocatedMemoryInBytesCallback callback) {
8279 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8280 isolate->heap()->SetGetExternallyAllocatedMemoryInBytesCallback(callback);
8281 }
8282
TerminateExecution()8283 void Isolate::TerminateExecution() {
8284 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8285 isolate->stack_guard()->RequestTerminateExecution();
8286 }
8287
IsExecutionTerminating()8288 bool Isolate::IsExecutionTerminating() {
8289 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8290 return IsExecutionTerminatingCheck(isolate);
8291 }
8292
CancelTerminateExecution()8293 void Isolate::CancelTerminateExecution() {
8294 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8295 isolate->stack_guard()->ClearTerminateExecution();
8296 isolate->CancelTerminateExecution();
8297 }
8298
RequestInterrupt(InterruptCallback callback,void * data)8299 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
8300 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8301 isolate->RequestInterrupt(callback, data);
8302 }
8303
HasPendingBackgroundTasks()8304 bool Isolate::HasPendingBackgroundTasks() {
8305 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8306 return isolate->wasm_engine()->HasRunningCompileJob(isolate);
8307 }
8308
RequestGarbageCollectionForTesting(GarbageCollectionType type)8309 void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
8310 CHECK(i::FLAG_expose_gc);
8311 if (type == kMinorGarbageCollection) {
8312 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
8313 i::NEW_SPACE, i::GarbageCollectionReason::kTesting,
8314 kGCCallbackFlagForced);
8315 } else {
8316 DCHECK_EQ(kFullGarbageCollection, type);
8317 reinterpret_cast<i::Isolate*>(this)->heap()->PreciseCollectAllGarbage(
8318 i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
8319 kGCCallbackFlagForced);
8320 }
8321 }
8322
GetCurrent()8323 Isolate* Isolate::GetCurrent() {
8324 i::Isolate* isolate = i::Isolate::Current();
8325 return reinterpret_cast<Isolate*>(isolate);
8326 }
8327
8328 // static
Allocate()8329 Isolate* Isolate::Allocate() {
8330 return reinterpret_cast<Isolate*>(i::Isolate::New());
8331 }
8332
8333 // static
8334 // This is separate so that tests can provide a different |isolate|.
Initialize(Isolate * isolate,const v8::Isolate::CreateParams & params)8335 void Isolate::Initialize(Isolate* isolate,
8336 const v8::Isolate::CreateParams& params) {
8337 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8338 if (auto allocator = params.array_buffer_allocator_shared) {
8339 CHECK(params.array_buffer_allocator == nullptr ||
8340 params.array_buffer_allocator == allocator.get());
8341 i_isolate->set_array_buffer_allocator(allocator.get());
8342 i_isolate->set_array_buffer_allocator_shared(std::move(allocator));
8343 } else {
8344 CHECK_NOT_NULL(params.array_buffer_allocator);
8345 i_isolate->set_array_buffer_allocator(params.array_buffer_allocator);
8346 }
8347 if (params.snapshot_blob != nullptr) {
8348 i_isolate->set_snapshot_blob(params.snapshot_blob);
8349 } else {
8350 i_isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
8351 }
8352 auto code_event_handler = params.code_event_handler;
8353 #ifdef ENABLE_GDB_JIT_INTERFACE
8354 if (code_event_handler == nullptr && i::FLAG_gdbjit) {
8355 code_event_handler = i::GDBJITInterface::EventHandler;
8356 }
8357 #endif // ENABLE_GDB_JIT_INTERFACE
8358 if (code_event_handler) {
8359 i_isolate->InitializeLoggingAndCounters();
8360 i_isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
8361 code_event_handler);
8362 }
8363 if (params.counter_lookup_callback) {
8364 isolate->SetCounterFunction(params.counter_lookup_callback);
8365 }
8366
8367 if (params.create_histogram_callback) {
8368 isolate->SetCreateHistogramFunction(params.create_histogram_callback);
8369 }
8370
8371 if (params.add_histogram_sample_callback) {
8372 isolate->SetAddHistogramSampleFunction(
8373 params.add_histogram_sample_callback);
8374 }
8375
8376 i_isolate->set_api_external_references(params.external_references);
8377 i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
8378
8379 i_isolate->heap()->ConfigureHeap(params.constraints);
8380 if (params.constraints.stack_limit() != nullptr) {
8381 uintptr_t limit =
8382 reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
8383 i_isolate->stack_guard()->SetStackLimit(limit);
8384 }
8385 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
8386 Isolate::Scope isolate_scope(isolate);
8387 if (!i::Snapshot::Initialize(i_isolate)) {
8388 // If snapshot data was provided and we failed to deserialize it must
8389 // have been corrupted.
8390 if (i_isolate->snapshot_blob() != nullptr) {
8391 FATAL(
8392 "Failed to deserialize the V8 snapshot blob. This can mean that the "
8393 "snapshot blob file is corrupted or missing.");
8394 }
8395 base::ElapsedTimer timer;
8396 if (i::FLAG_profile_deserialization) timer.Start();
8397 i_isolate->InitWithoutSnapshot();
8398 if (i::FLAG_profile_deserialization) {
8399 double ms = timer.Elapsed().InMillisecondsF();
8400 i::PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
8401 }
8402 }
8403 i_isolate->set_only_terminate_in_safe_scope(
8404 params.only_terminate_in_safe_scope);
8405 i_isolate->set_embedder_wrapper_type_index(
8406 params.embedder_wrapper_type_index);
8407 i_isolate->set_embedder_wrapper_object_index(
8408 params.embedder_wrapper_object_index);
8409
8410 if (!i::V8::GetCurrentPlatform()
8411 ->GetForegroundTaskRunner(isolate)
8412 ->NonNestableTasksEnabled()) {
8413 FATAL(
8414 "The current platform's foreground task runner does not have "
8415 "non-nestable tasks enabled. The embedder must provide one.");
8416 }
8417 }
8418
New(const Isolate::CreateParams & params)8419 Isolate* Isolate::New(const Isolate::CreateParams& params) {
8420 Isolate* isolate = Allocate();
8421 Initialize(isolate, params);
8422 return isolate;
8423 }
8424
Dispose()8425 void Isolate::Dispose() {
8426 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8427 if (!Utils::ApiCheck(!isolate->IsInUse(), "v8::Isolate::Dispose()",
8428 "Disposing the isolate that is entered by a thread.")) {
8429 return;
8430 }
8431 i::Isolate::Delete(isolate);
8432 }
8433
DumpAndResetStats()8434 void Isolate::DumpAndResetStats() {
8435 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8436 isolate->DumpAndResetStats();
8437 }
8438
DiscardThreadSpecificMetadata()8439 void Isolate::DiscardThreadSpecificMetadata() {
8440 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8441 isolate->DiscardPerThreadDataForThisThread();
8442 }
8443
Enter()8444 void Isolate::Enter() {
8445 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8446 isolate->Enter();
8447 }
8448
Exit()8449 void Isolate::Exit() {
8450 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8451 isolate->Exit();
8452 }
8453
SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback callback)8454 void Isolate::SetAbortOnUncaughtExceptionCallback(
8455 AbortOnUncaughtExceptionCallback callback) {
8456 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8457 isolate->SetAbortOnUncaughtExceptionCallback(callback);
8458 }
8459
SetHostImportModuleDynamicallyCallback(HostImportModuleDynamicallyCallback callback)8460 void Isolate::SetHostImportModuleDynamicallyCallback(
8461 HostImportModuleDynamicallyCallback callback) {
8462 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8463 isolate->SetHostImportModuleDynamicallyCallback(callback);
8464 }
8465
SetHostInitializeImportMetaObjectCallback(HostInitializeImportMetaObjectCallback callback)8466 void Isolate::SetHostInitializeImportMetaObjectCallback(
8467 HostInitializeImportMetaObjectCallback callback) {
8468 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8469 isolate->SetHostInitializeImportMetaObjectCallback(callback);
8470 }
8471
SetPrepareStackTraceCallback(PrepareStackTraceCallback callback)8472 void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
8473 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8474 isolate->SetPrepareStackTraceCallback(callback);
8475 }
8476
DisallowJavascriptExecutionScope(Isolate * isolate,Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)8477 Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
8478 Isolate* isolate,
8479 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
8480 : on_failure_(on_failure) {
8481 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8482 switch (on_failure_) {
8483 case CRASH_ON_FAILURE:
8484 internal_ = reinterpret_cast<void*>(
8485 new i::DisallowJavascriptExecution(i_isolate));
8486 break;
8487 case THROW_ON_FAILURE:
8488 DCHECK_EQ(THROW_ON_FAILURE, on_failure);
8489 internal_ =
8490 reinterpret_cast<void*>(new i::ThrowOnJavascriptExecution(i_isolate));
8491 break;
8492 case DUMP_ON_FAILURE:
8493 internal_ =
8494 reinterpret_cast<void*>(new i::DumpOnJavascriptExecution(i_isolate));
8495 break;
8496 default:
8497 UNREACHABLE();
8498 }
8499 }
8500
~DisallowJavascriptExecutionScope()8501 Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
8502 switch (on_failure_) {
8503 case CRASH_ON_FAILURE:
8504 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
8505 break;
8506 case THROW_ON_FAILURE:
8507 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
8508 break;
8509 case DUMP_ON_FAILURE:
8510 delete reinterpret_cast<i::DumpOnJavascriptExecution*>(internal_);
8511 break;
8512 default:
8513 UNREACHABLE();
8514 }
8515 }
8516
AllowJavascriptExecutionScope(Isolate * isolate)8517 Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
8518 Isolate* isolate) {
8519 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8520 internal_assert_ =
8521 reinterpret_cast<void*>(new i::AllowJavascriptExecution(i_isolate));
8522 internal_throws_ =
8523 reinterpret_cast<void*>(new i::NoThrowOnJavascriptExecution(i_isolate));
8524 internal_dump_ =
8525 reinterpret_cast<void*>(new i::NoDumpOnJavascriptExecution(i_isolate));
8526 }
8527
~AllowJavascriptExecutionScope()8528 Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
8529 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
8530 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
8531 delete reinterpret_cast<i::NoDumpOnJavascriptExecution*>(internal_dump_);
8532 }
8533
SuppressMicrotaskExecutionScope(Isolate * isolate,MicrotaskQueue * microtask_queue)8534 Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
8535 Isolate* isolate, MicrotaskQueue* microtask_queue)
8536 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8537 microtask_queue_(microtask_queue
8538 ? static_cast<i::MicrotaskQueue*>(microtask_queue)
8539 : isolate_->default_microtask_queue()) {
8540 isolate_->thread_local_top()->IncrementCallDepth(this);
8541 microtask_queue_->IncrementMicrotasksSuppressions();
8542 }
8543
~SuppressMicrotaskExecutionScope()8544 Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
8545 microtask_queue_->DecrementMicrotasksSuppressions();
8546 isolate_->thread_local_top()->DecrementCallDepth(this);
8547 }
8548
SafeForTerminationScope(v8::Isolate * isolate)8549 Isolate::SafeForTerminationScope::SafeForTerminationScope(v8::Isolate* isolate)
8550 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
8551 prev_value_(isolate_->next_v8_call_is_safe_for_termination()) {
8552 isolate_->set_next_v8_call_is_safe_for_termination(true);
8553 }
8554
~SafeForTerminationScope()8555 Isolate::SafeForTerminationScope::~SafeForTerminationScope() {
8556 isolate_->set_next_v8_call_is_safe_for_termination(prev_value_);
8557 }
8558
GetDataFromSnapshotOnce(size_t index)8559 i::Address* Isolate::GetDataFromSnapshotOnce(size_t index) {
8560 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8561 i::FixedArray list = i_isolate->heap()->serialized_objects();
8562 return GetSerializedDataFromFixedArray(i_isolate, list, index);
8563 }
8564
GetHeapStatistics(HeapStatistics * heap_statistics)8565 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
8566 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8567 i::Heap* heap = isolate->heap();
8568
8569 // The order of acquiring memory statistics is important here. We query in
8570 // this order because of concurrent allocation: 1) used memory 2) comitted
8571 // physical memory 3) committed memory. Therefore the condition used <=
8572 // committed physical <= committed should hold.
8573 heap_statistics->used_global_handles_size_ = heap->UsedGlobalHandlesSize();
8574 heap_statistics->total_global_handles_size_ = heap->TotalGlobalHandlesSize();
8575 DCHECK_LE(heap_statistics->used_global_handles_size_,
8576 heap_statistics->total_global_handles_size_);
8577
8578 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
8579 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
8580 heap_statistics->total_heap_size_ = heap->CommittedMemory();
8581
8582 heap_statistics->total_available_size_ = heap->Available();
8583
8584 if (!i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8585 i::ReadOnlySpace* ro_space = heap->read_only_space();
8586 heap_statistics->used_heap_size_ += ro_space->Size();
8587 heap_statistics->total_physical_size_ +=
8588 ro_space->CommittedPhysicalMemory();
8589 heap_statistics->total_heap_size_ += ro_space->CommittedMemory();
8590 }
8591
8592 // TODO(dinfuehr): Right now used <= committed physical does not hold. Fix
8593 // this and add DCHECK.
8594 DCHECK_LE(heap_statistics->used_heap_size_,
8595 heap_statistics->total_heap_size_);
8596
8597 heap_statistics->total_heap_size_executable_ =
8598 heap->CommittedMemoryExecutable();
8599 heap_statistics->heap_size_limit_ = heap->MaxReserved();
8600 // TODO(7424): There is no public API for the {WasmEngine} yet. Once such an
8601 // API becomes available we should report the malloced memory separately. For
8602 // now we just add the values, thereby over-approximating the peak slightly.
8603 heap_statistics->malloced_memory_ =
8604 isolate->allocator()->GetCurrentMemoryUsage() +
8605 isolate->wasm_engine()->allocator()->GetCurrentMemoryUsage() +
8606 isolate->string_table()->GetCurrentMemoryUsage();
8607 heap_statistics->external_memory_ = isolate->heap()->backing_store_bytes();
8608 heap_statistics->peak_malloced_memory_ =
8609 isolate->allocator()->GetMaxMemoryUsage() +
8610 isolate->wasm_engine()->allocator()->GetMaxMemoryUsage();
8611 heap_statistics->number_of_native_contexts_ = heap->NumberOfNativeContexts();
8612 heap_statistics->number_of_detached_contexts_ =
8613 heap->NumberOfDetachedContexts();
8614 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
8615 }
8616
NumberOfHeapSpaces()8617 size_t Isolate::NumberOfHeapSpaces() {
8618 return i::LAST_SPACE - i::FIRST_SPACE + 1;
8619 }
8620
GetHeapSpaceStatistics(HeapSpaceStatistics * space_statistics,size_t index)8621 bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
8622 size_t index) {
8623 if (!space_statistics) return false;
8624 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
8625 return false;
8626
8627 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8628 i::Heap* heap = isolate->heap();
8629
8630 i::AllocationSpace allocation_space = static_cast<i::AllocationSpace>(index);
8631 space_statistics->space_name_ = i::BaseSpace::GetSpaceName(allocation_space);
8632
8633 if (allocation_space == i::RO_SPACE) {
8634 if (i::ReadOnlyHeap::IsReadOnlySpaceShared()) {
8635 // RO_SPACE memory is accounted for elsewhere when ReadOnlyHeap is shared.
8636 space_statistics->space_size_ = 0;
8637 space_statistics->space_used_size_ = 0;
8638 space_statistics->space_available_size_ = 0;
8639 space_statistics->physical_space_size_ = 0;
8640 } else {
8641 i::ReadOnlySpace* space = heap->read_only_space();
8642 space_statistics->space_size_ = space->CommittedMemory();
8643 space_statistics->space_used_size_ = space->Size();
8644 space_statistics->space_available_size_ = 0;
8645 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8646 }
8647 } else {
8648 i::Space* space = heap->space(static_cast<int>(index));
8649 space_statistics->space_size_ = space->CommittedMemory();
8650 space_statistics->space_used_size_ = space->SizeOfObjects();
8651 space_statistics->space_available_size_ = space->Available();
8652 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
8653 }
8654 return true;
8655 }
8656
NumberOfTrackedHeapObjectTypes()8657 size_t Isolate::NumberOfTrackedHeapObjectTypes() {
8658 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8659 i::Heap* heap = isolate->heap();
8660 return heap->NumberOfTrackedHeapObjectTypes();
8661 }
8662
GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics * object_statistics,size_t type_index)8663 bool Isolate::GetHeapObjectStatisticsAtLastGC(
8664 HeapObjectStatistics* object_statistics, size_t type_index) {
8665 if (!object_statistics) return false;
8666 if (V8_LIKELY(!i::TracingFlags::is_gc_stats_enabled())) return false;
8667
8668 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8669 i::Heap* heap = isolate->heap();
8670 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
8671
8672 const char* object_type;
8673 const char* object_sub_type;
8674 size_t object_count = heap->ObjectCountAtLastGC(type_index);
8675 size_t object_size = heap->ObjectSizeAtLastGC(type_index);
8676 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
8677 // There should be no objects counted when the type is unknown.
8678 DCHECK_EQ(object_count, 0U);
8679 DCHECK_EQ(object_size, 0U);
8680 return false;
8681 }
8682
8683 object_statistics->object_type_ = object_type;
8684 object_statistics->object_sub_type_ = object_sub_type;
8685 object_statistics->object_count_ = object_count;
8686 object_statistics->object_size_ = object_size;
8687 return true;
8688 }
8689
GetHeapCodeAndMetadataStatistics(HeapCodeStatistics * code_statistics)8690 bool Isolate::GetHeapCodeAndMetadataStatistics(
8691 HeapCodeStatistics* code_statistics) {
8692 if (!code_statistics) return false;
8693
8694 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8695 isolate->heap()->CollectCodeStatistics();
8696
8697 code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
8698 code_statistics->bytecode_and_metadata_size_ =
8699 isolate->bytecode_and_metadata_size();
8700 code_statistics->external_script_source_size_ =
8701 isolate->external_script_source_size();
8702 return true;
8703 }
8704
MeasureMemory(v8::Local<v8::Context> context,MeasureMemoryMode mode)8705 v8::MaybeLocal<v8::Promise> Isolate::MeasureMemory(
8706 v8::Local<v8::Context> context, MeasureMemoryMode mode) {
8707 return v8::MaybeLocal<v8::Promise>();
8708 }
8709
MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,MeasureMemoryExecution execution)8710 bool Isolate::MeasureMemory(std::unique_ptr<MeasureMemoryDelegate> delegate,
8711 MeasureMemoryExecution execution) {
8712 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8713 return isolate->heap()->MeasureMemory(std::move(delegate), execution);
8714 }
8715
Default(Isolate * isolate,Local<Context> context,Local<Promise::Resolver> promise_resolver,MeasureMemoryMode mode)8716 std::unique_ptr<MeasureMemoryDelegate> MeasureMemoryDelegate::Default(
8717 Isolate* isolate, Local<Context> context,
8718 Local<Promise::Resolver> promise_resolver, MeasureMemoryMode mode) {
8719 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8720 i::Handle<i::NativeContext> native_context =
8721 handle(Utils::OpenHandle(*context)->native_context(), i_isolate);
8722 i::Handle<i::JSPromise> js_promise =
8723 i::Handle<i::JSPromise>::cast(Utils::OpenHandle(*promise_resolver));
8724 return i_isolate->heap()->MeasureMemoryDelegate(native_context, js_promise,
8725 mode);
8726 }
8727
GetStackSample(const RegisterState & state,void ** frames,size_t frames_limit,SampleInfo * sample_info)8728 void Isolate::GetStackSample(const RegisterState& state, void** frames,
8729 size_t frames_limit, SampleInfo* sample_info) {
8730 RegisterState regs = state;
8731 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8732 if (i::TickSample::GetStackSample(isolate, ®s,
8733 i::TickSample::kSkipCEntryFrame, frames,
8734 frames_limit, sample_info)) {
8735 return;
8736 }
8737 sample_info->frames_count = 0;
8738 sample_info->vm_state = OTHER;
8739 sample_info->external_callback_entry = nullptr;
8740 }
8741
NumberOfPhantomHandleResetsSinceLastCall()8742 size_t Isolate::NumberOfPhantomHandleResetsSinceLastCall() {
8743 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8744 return isolate->global_handles()->GetAndResetGlobalHandleResetCount();
8745 }
8746
AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes)8747 int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
8748 int64_t change_in_bytes) {
8749 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
8750 int64_t amount = i_isolate->heap()->update_external_memory(change_in_bytes);
8751
8752 if (change_in_bytes <= 0) return amount;
8753
8754 if (amount > i_isolate->heap()->external_memory_limit()) {
8755 ReportExternalAllocationLimitReached();
8756 }
8757 return amount;
8758 }
8759
SetEventLogger(LogEventCallback that)8760 void Isolate::SetEventLogger(LogEventCallback that) {
8761 // Do not overwrite the event logger if we want to log explicitly.
8762 if (i::FLAG_log_internal_timer_events) return;
8763 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8764 isolate->set_event_logger(that);
8765 }
8766
AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8767 void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
8768 if (callback == nullptr) return;
8769 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8770 isolate->AddBeforeCallEnteredCallback(callback);
8771 }
8772
RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback)8773 void Isolate::RemoveBeforeCallEnteredCallback(
8774 BeforeCallEnteredCallback callback) {
8775 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8776 isolate->RemoveBeforeCallEnteredCallback(callback);
8777 }
8778
AddCallCompletedCallback(CallCompletedCallback callback)8779 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
8780 if (callback == nullptr) return;
8781 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8782 isolate->AddCallCompletedCallback(callback);
8783 }
8784
RemoveCallCompletedCallback(CallCompletedCallback callback)8785 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
8786 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8787 isolate->RemoveCallCompletedCallback(callback);
8788 }
8789
Wake()8790 void Isolate::AtomicsWaitWakeHandle::Wake() {
8791 reinterpret_cast<i::AtomicsWaitWakeHandle*>(this)->Wake();
8792 }
8793
SetAtomicsWaitCallback(AtomicsWaitCallback callback,void * data)8794 void Isolate::SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data) {
8795 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8796 isolate->SetAtomicsWaitCallback(callback, data);
8797 }
8798
SetPromiseHook(PromiseHook hook)8799 void Isolate::SetPromiseHook(PromiseHook hook) {
8800 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8801 isolate->SetPromiseHook(hook);
8802 }
8803
SetPromiseRejectCallback(PromiseRejectCallback callback)8804 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
8805 if (callback == nullptr) return;
8806 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8807 isolate->SetPromiseRejectCallback(callback);
8808 }
8809
PerformMicrotaskCheckpoint()8810 void Isolate::PerformMicrotaskCheckpoint() {
8811 DCHECK_NE(MicrotasksPolicy::kScoped, GetMicrotasksPolicy());
8812 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8813 isolate->default_microtask_queue()->PerformCheckpoint(this);
8814 }
8815
EnqueueMicrotask(Local<Function> v8_function)8816 void Isolate::EnqueueMicrotask(Local<Function> v8_function) {
8817 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8818 i::Handle<i::JSReceiver> function = Utils::OpenHandle(*v8_function);
8819 i::Handle<i::NativeContext> handler_context;
8820 if (!i::JSReceiver::GetContextForMicrotask(function).ToHandle(
8821 &handler_context))
8822 handler_context = isolate->native_context();
8823 MicrotaskQueue* microtask_queue = handler_context->microtask_queue();
8824 if (microtask_queue) microtask_queue->EnqueueMicrotask(this, v8_function);
8825 }
8826
EnqueueMicrotask(MicrotaskCallback callback,void * data)8827 void Isolate::EnqueueMicrotask(MicrotaskCallback callback, void* data) {
8828 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8829 isolate->default_microtask_queue()->EnqueueMicrotask(this, callback, data);
8830 }
8831
SetMicrotasksPolicy(MicrotasksPolicy policy)8832 void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
8833 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8834 isolate->default_microtask_queue()->set_microtasks_policy(policy);
8835 }
8836
GetMicrotasksPolicy() const8837 MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
8838 i::Isolate* isolate =
8839 reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
8840 return isolate->default_microtask_queue()->microtasks_policy();
8841 }
8842
8843 namespace {
8844
MicrotasksCompletedCallbackAdapter(v8::Isolate * isolate,void * data)8845 void MicrotasksCompletedCallbackAdapter(v8::Isolate* isolate, void* data) {
8846 auto callback = reinterpret_cast<void (*)(v8::Isolate*)>(data);
8847 callback(isolate);
8848 }
8849
8850 } // namespace
8851
AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback)8852 void Isolate::AddMicrotasksCompletedCallback(
8853 MicrotasksCompletedCallback callback) {
8854 DCHECK(callback);
8855 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8856 isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(
8857 &MicrotasksCompletedCallbackAdapter, reinterpret_cast<void*>(callback));
8858 }
8859
AddMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)8860 void Isolate::AddMicrotasksCompletedCallback(
8861 MicrotasksCompletedCallbackWithData callback, void* data) {
8862 DCHECK(callback);
8863 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8864 isolate->default_microtask_queue()->AddMicrotasksCompletedCallback(callback,
8865 data);
8866 }
8867
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback)8868 void Isolate::RemoveMicrotasksCompletedCallback(
8869 MicrotasksCompletedCallback callback) {
8870 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8871 isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
8872 &MicrotasksCompletedCallbackAdapter, reinterpret_cast<void*>(callback));
8873 }
8874
RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallbackWithData callback,void * data)8875 void Isolate::RemoveMicrotasksCompletedCallback(
8876 MicrotasksCompletedCallbackWithData callback, void* data) {
8877 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8878 isolate->default_microtask_queue()->RemoveMicrotasksCompletedCallback(
8879 callback, data);
8880 }
8881
SetUseCounterCallback(UseCounterCallback callback)8882 void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
8883 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
8884 }
8885
SetCounterFunction(CounterLookupCallback callback)8886 void Isolate::SetCounterFunction(CounterLookupCallback callback) {
8887 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8888 isolate->counters()->ResetCounterFunction(callback);
8889 }
8890
SetCreateHistogramFunction(CreateHistogramCallback callback)8891 void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
8892 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8893 isolate->counters()->ResetCreateHistogramFunction(callback);
8894 }
8895
SetAddHistogramSampleFunction(AddHistogramSampleCallback callback)8896 void Isolate::SetAddHistogramSampleFunction(
8897 AddHistogramSampleCallback callback) {
8898 reinterpret_cast<i::Isolate*>(this)
8899 ->counters()
8900 ->SetAddHistogramSampleFunction(callback);
8901 }
8902
SetMetricsRecorder(const std::shared_ptr<metrics::Recorder> & metrics_recorder)8903 void Isolate::SetMetricsRecorder(
8904 const std::shared_ptr<metrics::Recorder>& metrics_recorder) {
8905 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8906 isolate->metrics_recorder()->SetRecorder(isolate, metrics_recorder);
8907 }
8908
SetAddCrashKeyCallback(AddCrashKeyCallback callback)8909 void Isolate::SetAddCrashKeyCallback(AddCrashKeyCallback callback) {
8910 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8911 isolate->SetAddCrashKeyCallback(callback);
8912 }
8913
IdleNotificationDeadline(double deadline_in_seconds)8914 bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
8915 // Returning true tells the caller that it need not
8916 // continue to call IdleNotification.
8917 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8918 if (!i::FLAG_use_idle_notification) return true;
8919 return isolate->heap()->IdleNotification(deadline_in_seconds);
8920 }
8921
LowMemoryNotification()8922 void Isolate::LowMemoryNotification() {
8923 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8924 {
8925 i::HistogramTimerScope idle_notification_scope(
8926 isolate->counters()->gc_low_memory_notification());
8927 TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
8928 isolate->heap()->CollectAllAvailableGarbage(
8929 i::GarbageCollectionReason::kLowMemoryNotification);
8930 }
8931 }
8932
ContextDisposedNotification(bool dependant_context)8933 int Isolate::ContextDisposedNotification(bool dependant_context) {
8934 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8935 if (!dependant_context) {
8936 if (!isolate->context().is_null()) {
8937 // We left the current context, we can abort all WebAssembly compilations
8938 // of that context.
8939 // A handle scope for the native context.
8940 i::HandleScope handle_scope(isolate);
8941 isolate->wasm_engine()->DeleteCompileJobsOnContext(
8942 isolate->native_context());
8943 }
8944 }
8945 // TODO(ahaas): move other non-heap activity out of the heap call.
8946 return isolate->heap()->NotifyContextDisposed(dependant_context);
8947 }
8948
IsolateInForegroundNotification()8949 void Isolate::IsolateInForegroundNotification() {
8950 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8951 return isolate->IsolateInForegroundNotification();
8952 }
8953
IsolateInBackgroundNotification()8954 void Isolate::IsolateInBackgroundNotification() {
8955 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8956 return isolate->IsolateInBackgroundNotification();
8957 }
8958
MemoryPressureNotification(MemoryPressureLevel level)8959 void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
8960 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8961 bool on_isolate_thread =
8962 v8::Locker::IsActive()
8963 ? isolate->thread_manager()->IsLockedByCurrentThread()
8964 : i::ThreadId::Current() == isolate->thread_id();
8965 isolate->heap()->MemoryPressureNotification(level, on_isolate_thread);
8966 }
8967
EnableMemorySavingsMode()8968 void Isolate::EnableMemorySavingsMode() {
8969 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8970 isolate->EnableMemorySavingsMode();
8971 }
8972
DisableMemorySavingsMode()8973 void Isolate::DisableMemorySavingsMode() {
8974 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8975 isolate->DisableMemorySavingsMode();
8976 }
8977
SetRAILMode(RAILMode rail_mode)8978 void Isolate::SetRAILMode(RAILMode rail_mode) {
8979 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8980 return isolate->SetRAILMode(rail_mode);
8981 }
8982
IncreaseHeapLimitForDebugging()8983 void Isolate::IncreaseHeapLimitForDebugging() {
8984 // No-op.
8985 }
8986
RestoreOriginalHeapLimit()8987 void Isolate::RestoreOriginalHeapLimit() {
8988 // No-op.
8989 }
8990
IsHeapLimitIncreasedForDebugging()8991 bool Isolate::IsHeapLimitIncreasedForDebugging() { return false; }
8992
SetJitCodeEventHandler(JitCodeEventOptions options,JitCodeEventHandler event_handler)8993 void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
8994 JitCodeEventHandler event_handler) {
8995 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
8996 // Ensure that logging is initialized for our isolate.
8997 isolate->InitializeLoggingAndCounters();
8998 isolate->logger()->SetCodeEventHandler(options, event_handler);
8999 }
9000
SetStackLimit(uintptr_t stack_limit)9001 void Isolate::SetStackLimit(uintptr_t stack_limit) {
9002 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9003 CHECK(stack_limit);
9004 isolate->stack_guard()->SetStackLimit(stack_limit);
9005 }
9006
GetCodeRange(void ** start,size_t * length_in_bytes)9007 void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
9008 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9009 const base::AddressRegion& code_range =
9010 isolate->heap()->memory_allocator()->code_range();
9011 *start = reinterpret_cast<void*>(code_range.begin());
9012 *length_in_bytes = code_range.size();
9013 }
9014
GetEmbeddedCodeRange(const void ** start,size_t * length_in_bytes)9015 void Isolate::GetEmbeddedCodeRange(const void** start,
9016 size_t* length_in_bytes) {
9017 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9018 i::EmbeddedData d = i::EmbeddedData::FromBlob(isolate);
9019 *start = reinterpret_cast<const void*>(d.code());
9020 *length_in_bytes = d.code_size();
9021 }
9022
GetJSEntryStubs()9023 JSEntryStubs Isolate::GetJSEntryStubs() {
9024 JSEntryStubs entry_stubs;
9025
9026 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9027 std::array<std::pair<i::Builtins::Name, JSEntryStub*>, 3> stubs = {
9028 {{i::Builtins::kJSEntry, &entry_stubs.js_entry_stub},
9029 {i::Builtins::kJSConstructEntry, &entry_stubs.js_construct_entry_stub},
9030 {i::Builtins::kJSRunMicrotasksEntry,
9031 &entry_stubs.js_run_microtasks_entry_stub}}};
9032 for (auto& pair : stubs) {
9033 i::Code js_entry = isolate->heap()->builtin(pair.first);
9034 pair.second->code.start =
9035 reinterpret_cast<const void*>(js_entry.InstructionStart());
9036 pair.second->code.length_in_bytes = js_entry.InstructionSize();
9037 }
9038
9039 return entry_stubs;
9040 }
9041
CopyCodePages(size_t capacity,MemoryRange * code_pages_out)9042 size_t Isolate::CopyCodePages(size_t capacity, MemoryRange* code_pages_out) {
9043 #if !defined(V8_TARGET_ARCH_64_BIT) && !defined(V8_TARGET_ARCH_ARM)
9044 // Not implemented on other platforms.
9045 UNREACHABLE();
9046 #else
9047
9048 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9049 std::vector<MemoryRange>* code_pages = isolate->GetCodePages();
9050
9051 DCHECK_NOT_NULL(code_pages);
9052
9053 // Copy as many elements into the output vector as we can. If the
9054 // caller-provided buffer is not big enough, we fill it, and the caller can
9055 // provide a bigger one next time. We do it this way because allocation is not
9056 // allowed in signal handlers.
9057 size_t limit = std::min(capacity, code_pages->size());
9058 for (size_t i = 0; i < limit; i++) {
9059 code_pages_out[i] = code_pages->at(i);
9060 }
9061 return code_pages->size();
9062 #endif
9063 }
9064
9065 #define CALLBACK_SETTER(ExternalName, Type, InternalName) \
9066 void Isolate::Set##ExternalName(Type callback) { \
9067 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); \
9068 isolate->set_##InternalName(callback); \
9069 }
9070
CALLBACK_SETTER(FatalErrorHandler,FatalErrorCallback,exception_behavior)9071 CALLBACK_SETTER(FatalErrorHandler, FatalErrorCallback, exception_behavior)
9072 CALLBACK_SETTER(OOMErrorHandler, OOMErrorCallback, oom_behavior)
9073 CALLBACK_SETTER(AllowCodeGenerationFromStringsCallback,
9074 AllowCodeGenerationFromStringsCallback, allow_code_gen_callback)
9075 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9076 ModifyCodeGenerationFromStringsCallback,
9077 modify_code_gen_callback)
9078 CALLBACK_SETTER(ModifyCodeGenerationFromStringsCallback,
9079 ModifyCodeGenerationFromStringsCallback2,
9080 modify_code_gen_callback2)
9081 CALLBACK_SETTER(AllowWasmCodeGenerationCallback,
9082 AllowWasmCodeGenerationCallback, allow_wasm_code_gen_callback)
9083
9084 CALLBACK_SETTER(WasmModuleCallback, ExtensionCallback, wasm_module_callback)
9085 CALLBACK_SETTER(WasmInstanceCallback, ExtensionCallback, wasm_instance_callback)
9086
9087 CALLBACK_SETTER(WasmStreamingCallback, WasmStreamingCallback,
9088 wasm_streaming_callback)
9089
9090 CALLBACK_SETTER(WasmThreadsEnabledCallback, WasmThreadsEnabledCallback,
9091 wasm_threads_enabled_callback)
9092
9093 CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
9094 wasm_load_source_map_callback)
9095
9096 CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback,
9097 wasm_simd_enabled_callback)
9098
9099 void Isolate::AddNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9100 void* data) {
9101 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9102 isolate->heap()->AddNearHeapLimitCallback(callback, data);
9103 }
9104
RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,size_t heap_limit)9105 void Isolate::RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
9106 size_t heap_limit) {
9107 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9108 isolate->heap()->RemoveNearHeapLimitCallback(callback, heap_limit);
9109 }
9110
AutomaticallyRestoreInitialHeapLimit(double threshold_percent)9111 void Isolate::AutomaticallyRestoreInitialHeapLimit(double threshold_percent) {
9112 DCHECK_GT(threshold_percent, 0.0);
9113 DCHECK_LT(threshold_percent, 1.0);
9114 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9115 isolate->heap()->AutomaticallyRestoreInitialHeapLimit(threshold_percent);
9116 }
9117
IsDead()9118 bool Isolate::IsDead() {
9119 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9120 return isolate->IsDead();
9121 }
9122
AddMessageListener(MessageCallback that,Local<Value> data)9123 bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
9124 return AddMessageListenerWithErrorLevel(that, kMessageError, data);
9125 }
9126
AddMessageListenerWithErrorLevel(MessageCallback that,int message_levels,Local<Value> data)9127 bool Isolate::AddMessageListenerWithErrorLevel(MessageCallback that,
9128 int message_levels,
9129 Local<Value> data) {
9130 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9131 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9132 i::HandleScope scope(isolate);
9133 i::Handle<i::TemplateList> list = isolate->factory()->message_listeners();
9134 i::Handle<i::FixedArray> listener = isolate->factory()->NewFixedArray(3);
9135 i::Handle<i::Foreign> foreign =
9136 isolate->factory()->NewForeign(FUNCTION_ADDR(that));
9137 listener->set(0, *foreign);
9138 listener->set(1, data.IsEmpty() ? i::ReadOnlyRoots(isolate).undefined_value()
9139 : *Utils::OpenHandle(*data));
9140 listener->set(2, i::Smi::FromInt(message_levels));
9141 list = i::TemplateList::Add(isolate, list, listener);
9142 isolate->heap()->SetMessageListeners(*list);
9143 return true;
9144 }
9145
RemoveMessageListeners(MessageCallback that)9146 void Isolate::RemoveMessageListeners(MessageCallback that) {
9147 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9148 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9149 i::HandleScope scope(isolate);
9150 i::DisallowHeapAllocation no_gc;
9151 i::TemplateList listeners = isolate->heap()->message_listeners();
9152 for (int i = 0; i < listeners.length(); i++) {
9153 if (listeners.get(i).IsUndefined(isolate)) continue; // skip deleted ones
9154 i::FixedArray listener = i::FixedArray::cast(listeners.get(i));
9155 i::Foreign callback_obj = i::Foreign::cast(listener.get(0));
9156 if (callback_obj.foreign_address() == FUNCTION_ADDR(that)) {
9157 listeners.set(i, i::ReadOnlyRoots(isolate).undefined_value());
9158 }
9159 }
9160 }
9161
SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback callback)9162 void Isolate::SetFailedAccessCheckCallbackFunction(
9163 FailedAccessCheckCallback callback) {
9164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9165 isolate->SetFailedAccessCheckCallback(callback);
9166 }
9167
SetCaptureStackTraceForUncaughtExceptions(bool capture,int frame_limit,StackTrace::StackTraceOptions options)9168 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
9169 bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
9170 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9171 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
9172 options);
9173 }
9174
VisitExternalResources(ExternalResourceVisitor * visitor)9175 void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
9176 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9177 isolate->heap()->VisitExternalResources(visitor);
9178 }
9179
IsInUse()9180 bool Isolate::IsInUse() {
9181 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9182 return isolate->IsInUse();
9183 }
9184
VisitHandlesWithClassIds(PersistentHandleVisitor * visitor)9185 void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
9186 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9187 i::DisallowHeapAllocation no_allocation;
9188 isolate->global_handles()->IterateAllRootsWithClassIds(visitor);
9189 }
9190
VisitWeakHandles(PersistentHandleVisitor * visitor)9191 void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
9192 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9193 i::DisallowHeapAllocation no_allocation;
9194 isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor);
9195 }
9196
SetAllowAtomicsWait(bool allow)9197 void Isolate::SetAllowAtomicsWait(bool allow) {
9198 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
9199 isolate->set_allow_atomics_wait(allow);
9200 }
9201
DateTimeConfigurationChangeNotification(TimeZoneDetection time_zone_detection)9202 void v8::Isolate::DateTimeConfigurationChangeNotification(
9203 TimeZoneDetection time_zone_detection) {
9204 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9205 LOG_API(i_isolate, Isolate, DateTimeConfigurationChangeNotification);
9206 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9207 i_isolate->date_cache()->ResetDateCache(
9208 static_cast<base::TimezoneCache::TimeZoneDetection>(time_zone_detection));
9209 #ifdef V8_INTL_SUPPORT
9210 i_isolate->clear_cached_icu_object(
9211 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormat);
9212 i_isolate->clear_cached_icu_object(
9213 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForTime);
9214 i_isolate->clear_cached_icu_object(
9215 i::Isolate::ICUObjectCacheType::kDefaultSimpleDateFormatForDate);
9216 #endif // V8_INTL_SUPPORT
9217 }
9218
LocaleConfigurationChangeNotification()9219 void v8::Isolate::LocaleConfigurationChangeNotification() {
9220 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
9221 LOG_API(i_isolate, Isolate, LocaleConfigurationChangeNotification);
9222 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9223
9224 #ifdef V8_INTL_SUPPORT
9225 i_isolate->ResetDefaultLocale();
9226 i_isolate->ClearCachedIcuObjects();
9227 #endif // V8_INTL_SUPPORT
9228 }
9229
IsCodeLike(v8::Isolate * isolate)9230 bool v8::Object::IsCodeLike(v8::Isolate* isolate) {
9231 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9232 LOG_API(i_isolate, Object, IsCodeLike);
9233 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9234 i::HandleScope scope(i_isolate);
9235 return Utils::OpenHandle(this)->IsCodeLike(i_isolate);
9236 }
9237
9238 // static
New(Isolate * isolate,MicrotasksPolicy policy)9239 std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate,
9240 MicrotasksPolicy policy) {
9241 auto microtask_queue =
9242 i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(isolate));
9243 microtask_queue->set_microtasks_policy(policy);
9244 std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
9245 return ret;
9246 }
9247
MicrotasksScope(Isolate * isolate,MicrotasksScope::Type type)9248 MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
9249 : MicrotasksScope(isolate, nullptr, type) {}
9250
MicrotasksScope(Isolate * isolate,MicrotaskQueue * microtask_queue,MicrotasksScope::Type type)9251 MicrotasksScope::MicrotasksScope(Isolate* isolate,
9252 MicrotaskQueue* microtask_queue,
9253 MicrotasksScope::Type type)
9254 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
9255 microtask_queue_(microtask_queue
9256 ? static_cast<i::MicrotaskQueue*>(microtask_queue)
9257 : isolate_->default_microtask_queue()),
9258 run_(type == MicrotasksScope::kRunMicrotasks) {
9259 if (run_) microtask_queue_->IncrementMicrotasksScopeDepth();
9260 #ifdef DEBUG
9261 if (!run_) microtask_queue_->IncrementDebugMicrotasksScopeDepth();
9262 #endif
9263 }
9264
~MicrotasksScope()9265 MicrotasksScope::~MicrotasksScope() {
9266 if (run_) {
9267 microtask_queue_->DecrementMicrotasksScopeDepth();
9268 if (MicrotasksPolicy::kScoped == microtask_queue_->microtasks_policy() &&
9269 !isolate_->has_scheduled_exception()) {
9270 DCHECK_IMPLIES(isolate_->has_scheduled_exception(),
9271 isolate_->scheduled_exception() ==
9272 i::ReadOnlyRoots(isolate_).termination_exception());
9273 microtask_queue_->PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
9274 }
9275 }
9276 #ifdef DEBUG
9277 if (!run_) microtask_queue_->DecrementDebugMicrotasksScopeDepth();
9278 #endif
9279 }
9280
PerformCheckpoint(Isolate * v8_isolate)9281 void MicrotasksScope::PerformCheckpoint(Isolate* v8_isolate) {
9282 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9283 auto* microtask_queue = isolate->default_microtask_queue();
9284 microtask_queue->PerformCheckpoint(v8_isolate);
9285 }
9286
GetCurrentDepth(Isolate * v8_isolate)9287 int MicrotasksScope::GetCurrentDepth(Isolate* v8_isolate) {
9288 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9289 auto* microtask_queue = isolate->default_microtask_queue();
9290 return microtask_queue->GetMicrotasksScopeDepth();
9291 }
9292
IsRunningMicrotasks(Isolate * v8_isolate)9293 bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) {
9294 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9295 auto* microtask_queue = isolate->default_microtask_queue();
9296 return microtask_queue->IsRunningMicrotasks();
9297 }
9298
Utf8Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9299 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9300 : str_(nullptr), length_(0) {
9301 if (obj.IsEmpty()) return;
9302 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9303 ENTER_V8_DO_NOT_USE(i_isolate);
9304 i::HandleScope scope(i_isolate);
9305 Local<Context> context = isolate->GetCurrentContext();
9306 TryCatch try_catch(isolate);
9307 Local<String> str;
9308 if (!obj->ToString(context).ToLocal(&str)) return;
9309 length_ = str->Utf8Length(isolate);
9310 str_ = i::NewArray<char>(length_ + 1);
9311 str->WriteUtf8(isolate, str_);
9312 }
9313
~Utf8Value()9314 String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); }
9315
Value(v8::Isolate * isolate,v8::Local<v8::Value> obj)9316 String::Value::Value(v8::Isolate* isolate, v8::Local<v8::Value> obj)
9317 : str_(nullptr), length_(0) {
9318 if (obj.IsEmpty()) return;
9319 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9320 ENTER_V8_DO_NOT_USE(i_isolate);
9321 i::HandleScope scope(i_isolate);
9322 Local<Context> context = isolate->GetCurrentContext();
9323 TryCatch try_catch(isolate);
9324 Local<String> str;
9325 if (!obj->ToString(context).ToLocal(&str)) return;
9326 length_ = str->Length();
9327 str_ = i::NewArray<uint16_t>(length_ + 1);
9328 str->Write(isolate, str_);
9329 }
9330
~Value()9331 String::Value::~Value() { i::DeleteArray(str_); }
9332
9333 #define DEFINE_ERROR(NAME, name) \
9334 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
9335 i::Isolate* isolate = i::Isolate::Current(); \
9336 LOG_API(isolate, NAME, New); \
9337 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); \
9338 i::Object error; \
9339 { \
9340 i::HandleScope scope(isolate); \
9341 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
9342 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
9343 error = *isolate->factory()->NewError(constructor, message); \
9344 } \
9345 i::Handle<i::Object> result(error, isolate); \
9346 return Utils::ToLocal(result); \
9347 }
9348
DEFINE_ERROR(RangeError,range_error)9349 DEFINE_ERROR(RangeError, range_error)
9350 DEFINE_ERROR(ReferenceError, reference_error)
9351 DEFINE_ERROR(SyntaxError, syntax_error)
9352 DEFINE_ERROR(TypeError, type_error)
9353 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
9354 DEFINE_ERROR(WasmLinkError, wasm_link_error)
9355 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
9356 DEFINE_ERROR(Error, error)
9357
9358 #undef DEFINE_ERROR
9359
9360 Local<Message> Exception::CreateMessage(Isolate* isolate,
9361 Local<Value> exception) {
9362 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9363 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9364 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
9365 i::HandleScope scope(i_isolate);
9366 return Utils::MessageToLocal(
9367 scope.CloseAndEscape(i_isolate->CreateMessage(obj, nullptr)));
9368 }
9369
GetStackTrace(Local<Value> exception)9370 Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
9371 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
9372 if (!obj->IsJSObject()) return Local<StackTrace>();
9373 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
9374 i::Isolate* isolate = js_obj->GetIsolate();
9375 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9376 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
9377 }
9378
9379 // --- D e b u g S u p p o r t ---
9380
SetContextId(Local<Context> context,int id)9381 void debug::SetContextId(Local<Context> context, int id) {
9382 Utils::OpenHandle(*context)->set_debug_context_id(i::Smi::FromInt(id));
9383 }
9384
GetContextId(Local<Context> context)9385 int debug::GetContextId(Local<Context> context) {
9386 i::Object value = Utils::OpenHandle(*context)->debug_context_id();
9387 return (value.IsSmi()) ? i::Smi::ToInt(value) : 0;
9388 }
9389
SetInspector(Isolate * isolate,v8_inspector::V8Inspector * inspector)9390 void debug::SetInspector(Isolate* isolate,
9391 v8_inspector::V8Inspector* inspector) {
9392 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
9393 i_isolate->set_inspector(inspector);
9394 }
9395
GetInspector(Isolate * isolate)9396 v8_inspector::V8Inspector* debug::GetInspector(Isolate* isolate) {
9397 return reinterpret_cast<i::Isolate*>(isolate)->inspector();
9398 }
9399
SetBreakOnNextFunctionCall(Isolate * isolate)9400 void debug::SetBreakOnNextFunctionCall(Isolate* isolate) {
9401 reinterpret_cast<i::Isolate*>(isolate)->debug()->SetBreakOnNextFunctionCall();
9402 }
9403
ClearBreakOnNextFunctionCall(Isolate * isolate)9404 void debug::ClearBreakOnNextFunctionCall(Isolate* isolate) {
9405 reinterpret_cast<i::Isolate*>(isolate)
9406 ->debug()
9407 ->ClearBreakOnNextFunctionCall();
9408 }
9409
GetInternalProperties(Isolate * v8_isolate,Local<Value> value)9410 MaybeLocal<Array> debug::GetInternalProperties(Isolate* v8_isolate,
9411 Local<Value> value) {
9412 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9413 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9414 i::Handle<i::Object> val = Utils::OpenHandle(*value);
9415 i::Handle<i::JSArray> result;
9416 if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
9417 return MaybeLocal<Array>();
9418 return Utils::ToLocal(result);
9419 }
9420
9421 namespace {
CollectPrivateMethodsAndAccessorsFromContext(i::Isolate * isolate,i::Handle<i::Context> context,i::IsStaticFlag is_static_flag,std::vector<Local<Value>> * names_out,std::vector<Local<Value>> * values_out)9422 void CollectPrivateMethodsAndAccessorsFromContext(
9423 i::Isolate* isolate, i::Handle<i::Context> context,
9424 i::IsStaticFlag is_static_flag, std::vector<Local<Value>>* names_out,
9425 std::vector<Local<Value>>* values_out) {
9426 i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate);
9427 int local_count = scope_info->ContextLocalCount();
9428 for (int j = 0; j < local_count; ++j) {
9429 i::VariableMode mode = scope_info->ContextLocalMode(j);
9430 i::IsStaticFlag flag = scope_info->ContextLocalIsStaticFlag(j);
9431 if (!i::IsPrivateMethodOrAccessorVariableMode(mode) ||
9432 flag != is_static_flag) {
9433 continue;
9434 }
9435
9436 i::Handle<i::String> name(scope_info->ContextLocalName(j), isolate);
9437 int context_index = scope_info->ContextHeaderLength() + j;
9438 i::Handle<i::Object> slot_value(context->get(context_index), isolate);
9439 DCHECK_IMPLIES(mode == i::VariableMode::kPrivateMethod,
9440 slot_value->IsJSFunction());
9441 DCHECK_IMPLIES(mode != i::VariableMode::kPrivateMethod,
9442 slot_value->IsAccessorPair());
9443 names_out->push_back(Utils::ToLocal(name));
9444 values_out->push_back(Utils::ToLocal(slot_value));
9445 }
9446 }
9447 } // anonymous namespace
9448
GetPrivateMembers(Local<Context> context,Local<Object> value,std::vector<Local<Value>> * names_out,std::vector<Local<Value>> * values_out)9449 bool debug::GetPrivateMembers(Local<Context> context, Local<Object> value,
9450 std::vector<Local<Value>>* names_out,
9451 std::vector<Local<Value>>* values_out) {
9452 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
9453 LOG_API(isolate, debug, GetPrivateMembers);
9454 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9455 i::Handle<i::JSReceiver> receiver = Utils::OpenHandle(*value);
9456 i::Handle<i::JSArray> names;
9457 i::Handle<i::FixedArray> values;
9458
9459 i::PropertyFilter key_filter =
9460 static_cast<i::PropertyFilter>(i::PropertyFilter::PRIVATE_NAMES_ONLY);
9461 i::Handle<i::FixedArray> keys;
9462 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9463 isolate, keys,
9464 i::KeyAccumulator::GetKeys(receiver, i::KeyCollectionMode::kOwnOnly,
9465 key_filter,
9466 i::GetKeysConversion::kConvertToString),
9467 false);
9468
9469 // Estimate number of private fields and private instance methods/accessors.
9470 int private_entries_count = 0;
9471 for (int i = 0; i < keys->length(); ++i) {
9472 // Exclude the private brand symbols.
9473 i::Handle<i::Symbol> key(i::Symbol::cast(keys->get(i)), isolate);
9474 if (key->is_private_brand()) {
9475 i::Handle<i::Object> value;
9476 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9477 isolate, value, i::Object::GetProperty(isolate, receiver, key),
9478 false);
9479
9480 i::Handle<i::Context> context(i::Context::cast(*value), isolate);
9481 i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate);
9482 // At least one slot contains the brand symbol so it does not count.
9483 private_entries_count += (scope_info->ContextLocalCount() - 1);
9484 } else {
9485 private_entries_count++;
9486 }
9487 }
9488
9489 // Estimate number of static private methods/accessors for classes.
9490 bool has_static_private_methods_or_accessors = false;
9491 if (receiver->IsJSFunction()) {
9492 i::Handle<i::JSFunction> func(i::JSFunction::cast(*receiver), isolate);
9493 i::Handle<i::SharedFunctionInfo> shared(func->shared(), isolate);
9494 if (shared->is_class_constructor() &&
9495 shared->has_static_private_methods_or_accessors()) {
9496 has_static_private_methods_or_accessors = true;
9497 i::Handle<i::Context> context(func->context(), isolate);
9498 i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate);
9499 int local_count = scope_info->ContextLocalCount();
9500 for (int j = 0; j < local_count; ++j) {
9501 i::VariableMode mode = scope_info->ContextLocalMode(j);
9502 i::IsStaticFlag is_static_flag =
9503 scope_info->ContextLocalIsStaticFlag(j);
9504 if (i::IsPrivateMethodOrAccessorVariableMode(mode) &&
9505 is_static_flag == i::IsStaticFlag::kStatic) {
9506 private_entries_count += local_count;
9507 break;
9508 }
9509 }
9510 }
9511 }
9512
9513 DCHECK(names_out->empty());
9514 names_out->reserve(private_entries_count);
9515 DCHECK(values_out->empty());
9516 values_out->reserve(private_entries_count);
9517
9518 if (has_static_private_methods_or_accessors) {
9519 i::Handle<i::Context> context(i::JSFunction::cast(*receiver).context(),
9520 isolate);
9521 CollectPrivateMethodsAndAccessorsFromContext(
9522 isolate, context, i::IsStaticFlag::kStatic, names_out, values_out);
9523 }
9524
9525 for (int i = 0; i < keys->length(); ++i) {
9526 i::Handle<i::Object> obj_key(keys->get(i), isolate);
9527 i::Handle<i::Symbol> key(i::Symbol::cast(*obj_key), isolate);
9528 CHECK(key->is_private_name());
9529 i::Handle<i::Object> value;
9530 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9531 isolate, value, i::Object::GetProperty(isolate, receiver, key), false);
9532
9533 if (key->is_private_brand()) {
9534 DCHECK(value->IsContext());
9535 i::Handle<i::Context> context(i::Context::cast(*value), isolate);
9536 CollectPrivateMethodsAndAccessorsFromContext(
9537 isolate, context, i::IsStaticFlag::kNotStatic, names_out, values_out);
9538 } else { // Private fields
9539 i::Handle<i::String> name(
9540 i::String::cast(i::Symbol::cast(*key).description()), isolate);
9541 names_out->push_back(Utils::ToLocal(name));
9542 values_out->push_back(Utils::ToLocal(value));
9543 }
9544 }
9545
9546 DCHECK_EQ(names_out->size(), values_out->size());
9547 DCHECK_LE(names_out->size(), private_entries_count);
9548 return true;
9549 }
9550
GetCreationContext(Local<Object> value)9551 Local<Context> debug::GetCreationContext(Local<Object> value) {
9552 i::Handle<i::Object> val = Utils::OpenHandle(*value);
9553 if (val->IsJSGlobalProxy()) {
9554 return Local<Context>();
9555 }
9556 return value->CreationContext();
9557 }
9558
ChangeBreakOnException(Isolate * isolate,ExceptionBreakState type)9559 void debug::ChangeBreakOnException(Isolate* isolate, ExceptionBreakState type) {
9560 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
9561 internal_isolate->debug()->ChangeBreakOnException(
9562 i::BreakException, type == BreakOnAnyException);
9563 internal_isolate->debug()->ChangeBreakOnException(i::BreakUncaughtException,
9564 type != NoBreakOnException);
9565 }
9566
SetBreakPointsActive(Isolate * v8_isolate,bool is_active)9567 void debug::SetBreakPointsActive(Isolate* v8_isolate, bool is_active) {
9568 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9569 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9570 isolate->debug()->set_break_points_active(is_active);
9571 }
9572
PrepareStep(Isolate * v8_isolate,StepAction action)9573 void debug::PrepareStep(Isolate* v8_isolate, StepAction action) {
9574 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9575 ENTER_V8_DO_NOT_USE(isolate);
9576 CHECK(isolate->debug()->CheckExecutionState());
9577 // Clear all current stepping setup.
9578 isolate->debug()->ClearStepping();
9579 // Prepare step.
9580 isolate->debug()->PrepareStep(static_cast<i::StepAction>(action));
9581 }
9582
ClearStepping(Isolate * v8_isolate)9583 void debug::ClearStepping(Isolate* v8_isolate) {
9584 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9585 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9586 // Clear all current stepping setup.
9587 isolate->debug()->ClearStepping();
9588 }
9589
BreakRightNow(Isolate * v8_isolate)9590 void debug::BreakRightNow(Isolate* v8_isolate) {
9591 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9592 ENTER_V8_DO_NOT_USE(isolate);
9593 isolate->debug()->HandleDebugBreak(i::kIgnoreIfAllFramesBlackboxed);
9594 }
9595
SetTerminateOnResume(Isolate * v8_isolate)9596 void debug::SetTerminateOnResume(Isolate* v8_isolate) {
9597 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9598 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
9599 isolate->debug()->SetTerminateOnResume();
9600 }
9601
AllFramesOnStackAreBlackboxed(Isolate * v8_isolate)9602 bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) {
9603 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9604 ENTER_V8_DO_NOT_USE(isolate);
9605 return isolate->debug()->AllFramesOnStackAreBlackboxed();
9606 }
9607
GetIsolate() const9608 v8::Isolate* debug::Script::GetIsolate() const {
9609 return reinterpret_cast<v8::Isolate*>(Utils::OpenHandle(this)->GetIsolate());
9610 }
9611
OriginOptions() const9612 ScriptOriginOptions debug::Script::OriginOptions() const {
9613 return Utils::OpenHandle(this)->origin_options();
9614 }
9615
WasCompiled() const9616 bool debug::Script::WasCompiled() const {
9617 return Utils::OpenHandle(this)->compilation_state() ==
9618 i::Script::COMPILATION_STATE_COMPILED;
9619 }
9620
IsEmbedded() const9621 bool debug::Script::IsEmbedded() const {
9622 i::Handle<i::Script> script = Utils::OpenHandle(this);
9623 return script->context_data() ==
9624 script->GetReadOnlyRoots().uninitialized_symbol();
9625 }
9626
Id() const9627 int debug::Script::Id() const { return Utils::OpenHandle(this)->id(); }
9628
LineOffset() const9629 int debug::Script::LineOffset() const {
9630 return Utils::OpenHandle(this)->line_offset();
9631 }
9632
ColumnOffset() const9633 int debug::Script::ColumnOffset() const {
9634 return Utils::OpenHandle(this)->column_offset();
9635 }
9636
LineEnds() const9637 std::vector<int> debug::Script::LineEnds() const {
9638 i::Handle<i::Script> script = Utils::OpenHandle(this);
9639 if (script->type() == i::Script::TYPE_WASM) return std::vector<int>();
9640
9641 i::Isolate* isolate = script->GetIsolate();
9642 i::HandleScope scope(isolate);
9643 i::Script::InitLineEnds(isolate, script);
9644 CHECK(script->line_ends().IsFixedArray());
9645 i::Handle<i::FixedArray> line_ends(i::FixedArray::cast(script->line_ends()),
9646 isolate);
9647 std::vector<int> result(line_ends->length());
9648 for (int i = 0; i < line_ends->length(); ++i) {
9649 i::Smi line_end = i::Smi::cast(line_ends->get(i));
9650 result[i] = line_end.value();
9651 }
9652 return result;
9653 }
9654
Name() const9655 MaybeLocal<String> debug::Script::Name() const {
9656 i::Handle<i::Script> script = Utils::OpenHandle(this);
9657 i::Isolate* isolate = script->GetIsolate();
9658 i::HandleScope handle_scope(isolate);
9659 i::Handle<i::Object> value(script->name(), isolate);
9660 if (!value->IsString()) return MaybeLocal<String>();
9661 return Utils::ToLocal(
9662 handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9663 }
9664
SourceURL() const9665 MaybeLocal<String> debug::Script::SourceURL() const {
9666 i::Handle<i::Script> script = Utils::OpenHandle(this);
9667 i::Isolate* isolate = script->GetIsolate();
9668 i::HandleScope handle_scope(isolate);
9669 i::Handle<i::Object> value(script->source_url(), isolate);
9670 if (!value->IsString()) return MaybeLocal<String>();
9671 return Utils::ToLocal(
9672 handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9673 }
9674
SourceMappingURL() const9675 MaybeLocal<String> debug::Script::SourceMappingURL() const {
9676 i::Handle<i::Script> script = Utils::OpenHandle(this);
9677 i::Isolate* isolate = script->GetIsolate();
9678 i::HandleScope handle_scope(isolate);
9679 i::Handle<i::Object> value(script->source_mapping_url(), isolate);
9680 if (!value->IsString()) return MaybeLocal<String>();
9681 return Utils::ToLocal(
9682 handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9683 }
9684
ContextId() const9685 Maybe<int> debug::Script::ContextId() const {
9686 i::Handle<i::Script> script = Utils::OpenHandle(this);
9687 i::Isolate* isolate = script->GetIsolate();
9688 i::HandleScope handle_scope(isolate);
9689 i::Object value = script->context_data();
9690 if (value.IsSmi()) return Just(i::Smi::ToInt(value));
9691 return Nothing<int>();
9692 }
9693
Source() const9694 MaybeLocal<String> debug::Script::Source() const {
9695 i::Handle<i::Script> script = Utils::OpenHandle(this);
9696 i::Isolate* isolate = script->GetIsolate();
9697 i::HandleScope handle_scope(isolate);
9698 i::Handle<i::Object> value(script->source(), isolate);
9699 if (!value->IsString()) return MaybeLocal<String>();
9700 return Utils::ToLocal(
9701 handle_scope.CloseAndEscape(i::Handle<i::String>::cast(value)));
9702 }
9703
IsWasm() const9704 bool debug::Script::IsWasm() const {
9705 return Utils::OpenHandle(this)->type() == i::Script::TYPE_WASM;
9706 }
9707
IsModule() const9708 bool debug::Script::IsModule() const {
9709 return Utils::OpenHandle(this)->origin_options().IsModule();
9710 }
9711
9712 namespace {
GetSmiValue(i::Handle<i::FixedArray> array,int index)9713 int GetSmiValue(i::Handle<i::FixedArray> array, int index) {
9714 return i::Smi::ToInt(array->get(index));
9715 }
9716
CompareBreakLocation(const i::BreakLocation & loc1,const i::BreakLocation & loc2)9717 bool CompareBreakLocation(const i::BreakLocation& loc1,
9718 const i::BreakLocation& loc2) {
9719 return loc1.position() < loc2.position();
9720 }
9721 } // namespace
9722
GetPossibleBreakpoints(const debug::Location & start,const debug::Location & end,bool restrict_to_function,std::vector<debug::BreakLocation> * locations) const9723 bool debug::Script::GetPossibleBreakpoints(
9724 const debug::Location& start, const debug::Location& end,
9725 bool restrict_to_function,
9726 std::vector<debug::BreakLocation>* locations) const {
9727 CHECK(!start.IsEmpty());
9728 i::Handle<i::Script> script = Utils::OpenHandle(this);
9729 if (script->type() == i::Script::TYPE_WASM) {
9730 i::wasm::NativeModule* native_module = script->wasm_native_module();
9731 return i::WasmScript::GetPossibleBreakpoints(native_module, start, end,
9732 locations);
9733 }
9734
9735 i::Isolate* isolate = script->GetIsolate();
9736 i::Script::InitLineEnds(isolate, script);
9737 CHECK(script->line_ends().IsFixedArray());
9738 i::Handle<i::FixedArray> line_ends =
9739 i::Handle<i::FixedArray>::cast(i::handle(script->line_ends(), isolate));
9740 CHECK(line_ends->length());
9741
9742 int start_offset = GetSourceOffset(start);
9743 int end_offset = end.IsEmpty()
9744 ? GetSmiValue(line_ends, line_ends->length() - 1) + 1
9745 : GetSourceOffset(end);
9746 if (start_offset >= end_offset) return true;
9747
9748 std::vector<i::BreakLocation> v8_locations;
9749 if (!isolate->debug()->GetPossibleBreakpoints(
9750 script, start_offset, end_offset, restrict_to_function,
9751 &v8_locations)) {
9752 return false;
9753 }
9754
9755 std::sort(v8_locations.begin(), v8_locations.end(), CompareBreakLocation);
9756 int current_line_end_index = 0;
9757 for (const auto& v8_location : v8_locations) {
9758 int offset = v8_location.position();
9759 while (offset > GetSmiValue(line_ends, current_line_end_index)) {
9760 ++current_line_end_index;
9761 CHECK(current_line_end_index < line_ends->length());
9762 }
9763 int line_offset = 0;
9764
9765 if (current_line_end_index > 0) {
9766 line_offset = GetSmiValue(line_ends, current_line_end_index - 1) + 1;
9767 }
9768 locations->emplace_back(
9769 current_line_end_index + script->line_offset(),
9770 offset - line_offset +
9771 (current_line_end_index == 0 ? script->column_offset() : 0),
9772 v8_location.type());
9773 }
9774 return true;
9775 }
9776
GetSourceOffset(const debug::Location & location) const9777 int debug::Script::GetSourceOffset(const debug::Location& location) const {
9778 i::Handle<i::Script> script = Utils::OpenHandle(this);
9779 if (script->type() == i::Script::TYPE_WASM) {
9780 DCHECK_EQ(0, location.GetLineNumber());
9781 return location.GetColumnNumber();
9782 }
9783
9784 int line = std::max(location.GetLineNumber() - script->line_offset(), 0);
9785 int column = location.GetColumnNumber();
9786 if (line == 0) {
9787 column = std::max(0, column - script->column_offset());
9788 }
9789
9790 i::Script::InitLineEnds(script->GetIsolate(), script);
9791 CHECK(script->line_ends().IsFixedArray());
9792 i::Handle<i::FixedArray> line_ends = i::Handle<i::FixedArray>::cast(
9793 i::handle(script->line_ends(), script->GetIsolate()));
9794 CHECK(line_ends->length());
9795 if (line >= line_ends->length())
9796 return GetSmiValue(line_ends, line_ends->length() - 1);
9797 int line_offset = GetSmiValue(line_ends, line);
9798 if (line == 0) return std::min(column, line_offset);
9799 int prev_line_offset = GetSmiValue(line_ends, line - 1);
9800 return std::min(prev_line_offset + column + 1, line_offset);
9801 }
9802
GetSourceLocation(int offset) const9803 v8::debug::Location debug::Script::GetSourceLocation(int offset) const {
9804 i::Handle<i::Script> script = Utils::OpenHandle(this);
9805 i::Script::PositionInfo info;
9806 i::Script::GetPositionInfo(script, offset, &info, i::Script::WITH_OFFSET);
9807 return debug::Location(info.line, info.column);
9808 }
9809
SetScriptSource(v8::Local<v8::String> newSource,bool preview,debug::LiveEditResult * result) const9810 bool debug::Script::SetScriptSource(v8::Local<v8::String> newSource,
9811 bool preview,
9812 debug::LiveEditResult* result) const {
9813 i::Handle<i::Script> script = Utils::OpenHandle(this);
9814 i::Isolate* isolate = script->GetIsolate();
9815 return isolate->debug()->SetScriptSource(
9816 script, Utils::OpenHandle(*newSource), preview, result);
9817 }
9818
SetBreakpoint(v8::Local<v8::String> condition,debug::Location * location,debug::BreakpointId * id) const9819 bool debug::Script::SetBreakpoint(v8::Local<v8::String> condition,
9820 debug::Location* location,
9821 debug::BreakpointId* id) const {
9822 i::Handle<i::Script> script = Utils::OpenHandle(this);
9823 i::Isolate* isolate = script->GetIsolate();
9824 int offset = GetSourceOffset(*location);
9825 if (!isolate->debug()->SetBreakPointForScript(
9826 script, Utils::OpenHandle(*condition), &offset, id)) {
9827 return false;
9828 }
9829 *location = GetSourceLocation(offset);
9830 return true;
9831 }
9832
SetBreakpointOnScriptEntry(BreakpointId * id) const9833 bool debug::Script::SetBreakpointOnScriptEntry(BreakpointId* id) const {
9834 i::Handle<i::Script> script = Utils::OpenHandle(this);
9835 i::Isolate* isolate = script->GetIsolate();
9836 i::SharedFunctionInfo::ScriptIterator it(isolate, *script);
9837 for (i::SharedFunctionInfo sfi = it.Next(); !sfi.is_null(); sfi = it.Next()) {
9838 if (sfi.is_toplevel()) {
9839 return isolate->debug()->SetBreakpointForFunction(
9840 handle(sfi, isolate), isolate->factory()->empty_string(), id);
9841 }
9842 }
9843 return false;
9844 }
9845
RemoveWasmBreakpoint(debug::BreakpointId id)9846 void debug::Script::RemoveWasmBreakpoint(debug::BreakpointId id) {
9847 i::Handle<i::Script> script = Utils::OpenHandle(this);
9848 i::Isolate* isolate = script->GetIsolate();
9849 isolate->debug()->RemoveBreakpointForWasmScript(script, id);
9850 }
9851
RemoveBreakpoint(Isolate * v8_isolate,BreakpointId id)9852 void debug::RemoveBreakpoint(Isolate* v8_isolate, BreakpointId id) {
9853 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
9854 i::HandleScope handle_scope(isolate);
9855 isolate->debug()->RemoveBreakpoint(id);
9856 }
9857
GetCurrentPlatform()9858 v8::Platform* debug::GetCurrentPlatform() {
9859 return i::V8::GetCurrentPlatform();
9860 }
9861
ForceGarbageCollection(v8::Isolate * isolate,v8::EmbedderHeapTracer::EmbedderStackState embedder_stack_state)9862 void debug::ForceGarbageCollection(
9863 v8::Isolate* isolate,
9864 v8::EmbedderHeapTracer::EmbedderStackState embedder_stack_state) {
9865 i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
9866 heap->SetEmbedderStackStateForNextFinalization(embedder_stack_state);
9867 isolate->LowMemoryNotification();
9868 }
9869
Cast(debug::Script * script)9870 debug::WasmScript* debug::WasmScript::Cast(debug::Script* script) {
9871 CHECK(script->IsWasm());
9872 return static_cast<WasmScript*>(script);
9873 }
9874
GetDebugSymbolType() const9875 debug::WasmScript::DebugSymbolsType debug::WasmScript::GetDebugSymbolType()
9876 const {
9877 i::Handle<i::Script> script = Utils::OpenHandle(this);
9878 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9879 switch (script->wasm_native_module()->module()->debug_symbols.type) {
9880 case i::wasm::WasmDebugSymbols::Type::None:
9881 return debug::WasmScript::DebugSymbolsType::None;
9882 case i::wasm::WasmDebugSymbols::Type::EmbeddedDWARF:
9883 return debug::WasmScript::DebugSymbolsType::EmbeddedDWARF;
9884 case i::wasm::WasmDebugSymbols::Type::ExternalDWARF:
9885 return debug::WasmScript::DebugSymbolsType::ExternalDWARF;
9886 case i::wasm::WasmDebugSymbols::Type::SourceMap:
9887 return debug::WasmScript::DebugSymbolsType::SourceMap;
9888 }
9889 }
9890
ExternalSymbolsURL() const9891 MemorySpan<const char> debug::WasmScript::ExternalSymbolsURL() const {
9892 i::Handle<i::Script> script = Utils::OpenHandle(this);
9893 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9894
9895 const i::wasm::WasmDebugSymbols& symbols =
9896 script->wasm_native_module()->module()->debug_symbols;
9897 if (symbols.external_url.is_empty()) return {};
9898
9899 internal::wasm::ModuleWireBytes wire_bytes(
9900 script->wasm_native_module()->wire_bytes());
9901 i::wasm::WasmName external_url =
9902 wire_bytes.GetNameOrNull(symbols.external_url);
9903 return {external_url.data(), external_url.size()};
9904 }
9905
NumFunctions() const9906 int debug::WasmScript::NumFunctions() const {
9907 i::DisallowHeapAllocation no_gc;
9908 i::Handle<i::Script> script = Utils::OpenHandle(this);
9909 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9910 i::wasm::NativeModule* native_module = script->wasm_native_module();
9911 const i::wasm::WasmModule* module = native_module->module();
9912 DCHECK_GE(i::kMaxInt, module->functions.size());
9913 return static_cast<int>(module->functions.size());
9914 }
9915
NumImportedFunctions() const9916 int debug::WasmScript::NumImportedFunctions() const {
9917 i::DisallowHeapAllocation no_gc;
9918 i::Handle<i::Script> script = Utils::OpenHandle(this);
9919 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9920 i::wasm::NativeModule* native_module = script->wasm_native_module();
9921 const i::wasm::WasmModule* module = native_module->module();
9922 DCHECK_GE(i::kMaxInt, module->num_imported_functions);
9923 return static_cast<int>(module->num_imported_functions);
9924 }
9925
Bytecode() const9926 MemorySpan<const uint8_t> debug::WasmScript::Bytecode() const {
9927 i::Handle<i::Script> script = Utils::OpenHandle(this);
9928 i::Vector<const uint8_t> wire_bytes =
9929 script->wasm_native_module()->wire_bytes();
9930 return {wire_bytes.begin(), wire_bytes.size()};
9931 }
9932
GetFunctionRange(int function_index) const9933 std::pair<int, int> debug::WasmScript::GetFunctionRange(
9934 int function_index) const {
9935 i::DisallowHeapAllocation no_gc;
9936 i::Handle<i::Script> script = Utils::OpenHandle(this);
9937 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9938 i::wasm::NativeModule* native_module = script->wasm_native_module();
9939 const i::wasm::WasmModule* module = native_module->module();
9940 DCHECK_LE(0, function_index);
9941 DCHECK_GT(module->functions.size(), function_index);
9942 const i::wasm::WasmFunction& func = module->functions[function_index];
9943 DCHECK_GE(i::kMaxInt, func.code.offset());
9944 DCHECK_GE(i::kMaxInt, func.code.end_offset());
9945 return std::make_pair(static_cast<int>(func.code.offset()),
9946 static_cast<int>(func.code.end_offset()));
9947 }
9948
GetContainingFunction(int byte_offset) const9949 int debug::WasmScript::GetContainingFunction(int byte_offset) const {
9950 i::DisallowHeapAllocation no_gc;
9951 i::Handle<i::Script> script = Utils::OpenHandle(this);
9952 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9953 i::wasm::NativeModule* native_module = script->wasm_native_module();
9954 const i::wasm::WasmModule* module = native_module->module();
9955 DCHECK_LE(0, byte_offset);
9956
9957 return i::wasm::GetContainingWasmFunction(module, byte_offset);
9958 }
9959
GetFunctionHash(int function_index)9960 uint32_t debug::WasmScript::GetFunctionHash(int function_index) {
9961 i::DisallowHeapAllocation no_gc;
9962 i::Handle<i::Script> script = Utils::OpenHandle(this);
9963 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9964 i::wasm::NativeModule* native_module = script->wasm_native_module();
9965 const i::wasm::WasmModule* module = native_module->module();
9966 DCHECK_LE(0, function_index);
9967 DCHECK_GT(module->functions.size(), function_index);
9968 const i::wasm::WasmFunction& func = module->functions[function_index];
9969 i::wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes());
9970 i::Vector<const i::byte> function_bytes = wire_bytes.GetFunctionBytes(&func);
9971 // TODO(herhut): Maybe also take module, name and signature into account.
9972 return i::StringHasher::HashSequentialString(function_bytes.begin(),
9973 function_bytes.length(), 0);
9974 }
9975
CodeOffset() const9976 int debug::WasmScript::CodeOffset() const {
9977 i::Handle<i::Script> script = Utils::OpenHandle(this);
9978 DCHECK_EQ(i::Script::TYPE_WASM, script->type());
9979 i::wasm::NativeModule* native_module = script->wasm_native_module();
9980 const i::wasm::WasmModule* module = native_module->module();
9981
9982 // If the module contains at least one function, the code offset must have
9983 // been initialized, and it cannot be zero.
9984 DCHECK_IMPLIES(module->num_declared_functions > 0,
9985 module->code.offset() != 0);
9986 return module->code.offset();
9987 }
9988
Location(int line_number,int column_number)9989 debug::Location::Location(int line_number, int column_number)
9990 : line_number_(line_number),
9991 column_number_(column_number),
9992 is_empty_(false) {}
9993
Location()9994 debug::Location::Location()
9995 : line_number_(v8::Function::kLineOffsetNotFound),
9996 column_number_(v8::Function::kLineOffsetNotFound),
9997 is_empty_(true) {}
9998
GetLineNumber() const9999 int debug::Location::GetLineNumber() const {
10000 DCHECK(!IsEmpty());
10001 return line_number_;
10002 }
10003
GetColumnNumber() const10004 int debug::Location::GetColumnNumber() const {
10005 DCHECK(!IsEmpty());
10006 return column_number_;
10007 }
10008
IsEmpty() const10009 bool debug::Location::IsEmpty() const { return is_empty_; }
10010
GetLoadedScripts(v8::Isolate * v8_isolate,PersistentValueVector<debug::Script> & scripts)10011 void debug::GetLoadedScripts(v8::Isolate* v8_isolate,
10012 PersistentValueVector<debug::Script>& scripts) {
10013 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10014 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10015 {
10016 i::DisallowHeapAllocation no_gc;
10017 i::Script::Iterator iterator(isolate);
10018 for (i::Script script = iterator.Next(); !script.is_null();
10019 script = iterator.Next()) {
10020 if (script.type() == i::Script::TYPE_NORMAL ||
10021 script.type() == i::Script::TYPE_WASM) {
10022 if (script.HasValidSource()) {
10023 i::HandleScope handle_scope(isolate);
10024 i::Handle<i::Script> script_handle(script, isolate);
10025 scripts.Append(ToApiHandle<Script>(script_handle));
10026 }
10027 }
10028 }
10029 }
10030 }
10031
CompileInspectorScript(Isolate * v8_isolate,Local<String> source)10032 MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
10033 Local<String> source) {
10034 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10035 PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(isolate, UnboundScript);
10036 i::Handle<i::String> str = Utils::OpenHandle(*source);
10037 i::Handle<i::SharedFunctionInfo> result;
10038 {
10039 ScriptOriginOptions origin_options;
10040 i::ScriptData* script_data = nullptr;
10041 i::MaybeHandle<i::SharedFunctionInfo> maybe_function_info =
10042 i::Compiler::GetSharedFunctionInfoForScript(
10043 isolate, str, i::Compiler::ScriptDetails(), origin_options, nullptr,
10044 script_data, ScriptCompiler::kNoCompileOptions,
10045 ScriptCompiler::kNoCacheBecauseInspector,
10046 i::FLAG_expose_inspector_scripts ? i::NOT_NATIVES_CODE
10047 : i::INSPECTOR_CODE);
10048 has_pending_exception = !maybe_function_info.ToHandle(&result);
10049 RETURN_ON_FAILED_EXECUTION(UnboundScript);
10050 }
10051 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
10052 }
10053
TierDownAllModulesPerIsolate(Isolate * v8_isolate)10054 void debug::TierDownAllModulesPerIsolate(Isolate* v8_isolate) {
10055 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10056 isolate->wasm_engine()->TierDownAllModulesPerIsolate(isolate);
10057 }
10058
TierUpAllModulesPerIsolate(Isolate * v8_isolate)10059 void debug::TierUpAllModulesPerIsolate(Isolate* v8_isolate) {
10060 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10061 isolate->wasm_engine()->TierUpAllModulesPerIsolate(isolate);
10062 }
10063
SetDebugDelegate(Isolate * v8_isolate,debug::DebugDelegate * delegate)10064 void debug::SetDebugDelegate(Isolate* v8_isolate,
10065 debug::DebugDelegate* delegate) {
10066 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10067 isolate->debug()->SetDebugDelegate(delegate);
10068 }
10069
SetAsyncEventDelegate(Isolate * v8_isolate,debug::AsyncEventDelegate * delegate)10070 void debug::SetAsyncEventDelegate(Isolate* v8_isolate,
10071 debug::AsyncEventDelegate* delegate) {
10072 reinterpret_cast<i::Isolate*>(v8_isolate)->set_async_event_delegate(delegate);
10073 }
10074
ResetBlackboxedStateCache(Isolate * v8_isolate,v8::Local<debug::Script> script)10075 void debug::ResetBlackboxedStateCache(Isolate* v8_isolate,
10076 v8::Local<debug::Script> script) {
10077 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10078 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10079 i::DisallowHeapAllocation no_gc;
10080 i::SharedFunctionInfo::ScriptIterator iter(isolate,
10081 *Utils::OpenHandle(*script));
10082 for (i::SharedFunctionInfo info = iter.Next(); !info.is_null();
10083 info = iter.Next()) {
10084 if (info.HasDebugInfo()) {
10085 info.GetDebugInfo().set_computed_debug_is_blackboxed(false);
10086 }
10087 }
10088 }
10089
EstimatedValueSize(Isolate * v8_isolate,v8::Local<v8::Value> value)10090 int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local<v8::Value> value) {
10091 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10092 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10093 i::Handle<i::Object> object = Utils::OpenHandle(*value);
10094 if (object->IsSmi()) return i::kTaggedSize;
10095 CHECK(object->IsHeapObject());
10096 return i::Handle<i::HeapObject>::cast(object)->Size();
10097 }
10098
PreviewEntries(bool * is_key_value)10099 v8::MaybeLocal<v8::Array> v8::Object::PreviewEntries(bool* is_key_value) {
10100 if (IsMap()) {
10101 *is_key_value = true;
10102 return Map::Cast(this)->AsArray();
10103 }
10104 if (IsSet()) {
10105 *is_key_value = false;
10106 return Set::Cast(this)->AsArray();
10107 }
10108
10109 i::Handle<i::JSReceiver> object = Utils::OpenHandle(this);
10110 i::Isolate* isolate = object->GetIsolate();
10111 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
10112 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10113 if (object->IsJSWeakCollection()) {
10114 *is_key_value = object->IsJSWeakMap();
10115 return Utils::ToLocal(i::JSWeakCollection::GetEntries(
10116 i::Handle<i::JSWeakCollection>::cast(object), 0));
10117 }
10118 if (object->IsJSMapIterator()) {
10119 i::Handle<i::JSMapIterator> it = i::Handle<i::JSMapIterator>::cast(object);
10120 MapAsArrayKind const kind =
10121 static_cast<MapAsArrayKind>(it->map().instance_type());
10122 *is_key_value = kind == MapAsArrayKind::kEntries;
10123 if (!it->HasMore()) return v8::Array::New(v8_isolate);
10124 return Utils::ToLocal(
10125 MapAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
10126 }
10127 if (object->IsJSSetIterator()) {
10128 i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);
10129 SetAsArrayKind const kind =
10130 static_cast<SetAsArrayKind>(it->map().instance_type());
10131 *is_key_value = kind == SetAsArrayKind::kEntries;
10132 if (!it->HasMore()) return v8::Array::New(v8_isolate);
10133 return Utils::ToLocal(
10134 SetAsArray(isolate, it->table(), i::Smi::ToInt(it->index()), kind));
10135 }
10136 return v8::MaybeLocal<v8::Array>();
10137 }
10138
GetBuiltin(Isolate * v8_isolate,Builtin builtin)10139 Local<Function> debug::GetBuiltin(Isolate* v8_isolate, Builtin builtin) {
10140 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10141 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10142 i::HandleScope handle_scope(isolate);
10143 i::Builtins::Name builtin_id;
10144 switch (builtin) {
10145 case kStringToLowerCase:
10146 builtin_id = i::Builtins::kStringPrototypeToLocaleLowerCase;
10147 break;
10148 default:
10149 UNREACHABLE();
10150 }
10151
10152 i::Handle<i::String> name = isolate->factory()->empty_string();
10153 i::NewFunctionArgs args = i::NewFunctionArgs::ForBuiltinWithoutPrototype(
10154 name, builtin_id, i::LanguageMode::kStrict);
10155 i::Handle<i::JSFunction> fun = isolate->factory()->NewFunction(args);
10156
10157 fun->shared().set_internal_formal_parameter_count(0);
10158 fun->shared().set_length(0);
10159 return Utils::ToLocal(handle_scope.CloseAndEscape(fun));
10160 }
10161
SetConsoleDelegate(Isolate * v8_isolate,ConsoleDelegate * delegate)10162 void debug::SetConsoleDelegate(Isolate* v8_isolate, ConsoleDelegate* delegate) {
10163 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10164 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10165 isolate->set_console_delegate(delegate);
10166 }
10167
ConsoleCallArguments(const v8::FunctionCallbackInfo<v8::Value> & info)10168 debug::ConsoleCallArguments::ConsoleCallArguments(
10169 const v8::FunctionCallbackInfo<v8::Value>& info)
10170 : v8::FunctionCallbackInfo<v8::Value>(nullptr, info.values_, info.length_) {
10171 }
10172
ConsoleCallArguments(const internal::BuiltinArguments & args)10173 debug::ConsoleCallArguments::ConsoleCallArguments(
10174 const internal::BuiltinArguments& args)
10175 : v8::FunctionCallbackInfo<v8::Value>(
10176 nullptr,
10177 // Drop the first argument (receiver, i.e. the "console" object).
10178 args.length() > 1 ? args.address_of_first_argument() : nullptr,
10179 args.length() - 1) {}
10180
10181 // Marked V8_DEPRECATED.
GetStackFrameId(v8::Local<v8::StackFrame> frame)10182 int debug::GetStackFrameId(v8::Local<v8::StackFrame> frame) { return 0; }
10183
GetDetailedStackTrace(Isolate * v8_isolate,v8::Local<v8::Object> v8_error)10184 v8::Local<v8::StackTrace> debug::GetDetailedStackTrace(
10185 Isolate* v8_isolate, v8::Local<v8::Object> v8_error) {
10186 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10187 i::Handle<i::JSReceiver> error = Utils::OpenHandle(*v8_error);
10188 if (!error->IsJSObject()) {
10189 return v8::Local<v8::StackTrace>();
10190 }
10191 i::Handle<i::FixedArray> stack_trace =
10192 isolate->GetDetailedStackTrace(i::Handle<i::JSObject>::cast(error));
10193 return Utils::StackTraceToLocal(stack_trace);
10194 }
10195
Script()10196 MaybeLocal<debug::Script> debug::GeneratorObject::Script() {
10197 i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10198 i::Object maybe_script = obj->function().shared().script();
10199 if (!maybe_script.IsScript()) return MaybeLocal<debug::Script>();
10200 i::Handle<i::Script> script(i::Script::cast(maybe_script), obj->GetIsolate());
10201 return ToApiHandle<debug::Script>(script);
10202 }
10203
Function()10204 Local<Function> debug::GeneratorObject::Function() {
10205 i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10206 return Utils::ToLocal(handle(obj->function(), obj->GetIsolate()));
10207 }
10208
SuspendedLocation()10209 debug::Location debug::GeneratorObject::SuspendedLocation() {
10210 i::Handle<i::JSGeneratorObject> obj = Utils::OpenHandle(this);
10211 CHECK(obj->is_suspended());
10212 i::Object maybe_script = obj->function().shared().script();
10213 if (!maybe_script.IsScript()) return debug::Location();
10214 i::Isolate* isolate = obj->GetIsolate();
10215 i::Handle<i::Script> script(i::Script::cast(maybe_script), isolate);
10216 i::Script::PositionInfo info;
10217 i::SharedFunctionInfo::EnsureSourcePositionsAvailable(
10218 isolate, i::handle(obj->function().shared(), isolate));
10219 i::Script::GetPositionInfo(script, obj->source_position(), &info,
10220 i::Script::WITH_OFFSET);
10221 return debug::Location(info.line, info.column);
10222 }
10223
IsSuspended()10224 bool debug::GeneratorObject::IsSuspended() {
10225 return Utils::OpenHandle(this)->is_suspended();
10226 }
10227
Cast(v8::Local<v8::Value> value)10228 v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast(
10229 v8::Local<v8::Value> value) {
10230 CHECK(value->IsGeneratorObject());
10231 return ToApiHandle<debug::GeneratorObject>(Utils::OpenHandle(*value));
10232 }
10233
EvaluateGlobal(v8::Isolate * isolate,v8::Local<v8::String> source,EvaluateGlobalMode mode,bool repl)10234 MaybeLocal<v8::Value> debug::EvaluateGlobal(v8::Isolate* isolate,
10235 v8::Local<v8::String> source,
10236 EvaluateGlobalMode mode,
10237 bool repl) {
10238 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
10239 PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(internal_isolate, Value);
10240 i::REPLMode repl_mode = repl ? i::REPLMode::kYes : i::REPLMode::kNo;
10241 Local<Value> result;
10242 has_pending_exception = !ToLocal<Value>(
10243 i::DebugEvaluate::Global(internal_isolate, Utils::OpenHandle(*source),
10244 mode, repl_mode),
10245 &result);
10246 RETURN_ON_FAILED_EXECUTION(Value);
10247 RETURN_ESCAPED(result);
10248 }
10249
QueryObjects(v8::Local<v8::Context> v8_context,QueryObjectPredicate * predicate,PersistentValueVector<v8::Object> * objects)10250 void debug::QueryObjects(v8::Local<v8::Context> v8_context,
10251 QueryObjectPredicate* predicate,
10252 PersistentValueVector<v8::Object>* objects) {
10253 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_context->GetIsolate());
10254 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
10255 isolate->heap_profiler()->QueryObjects(Utils::OpenHandle(*v8_context),
10256 predicate, objects);
10257 }
10258
GlobalLexicalScopeNames(v8::Local<v8::Context> v8_context,v8::PersistentValueVector<v8::String> * names)10259 void debug::GlobalLexicalScopeNames(
10260 v8::Local<v8::Context> v8_context,
10261 v8::PersistentValueVector<v8::String>* names) {
10262 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
10263 i::Isolate* isolate = context->GetIsolate();
10264 i::Handle<i::ScriptContextTable> table(
10265 context->global_object().native_context().script_context_table(),
10266 isolate);
10267 for (int i = 0; i < table->synchronized_used(); i++) {
10268 i::Handle<i::Context> context =
10269 i::ScriptContextTable::GetContext(isolate, table, i);
10270 DCHECK(context->IsScriptContext());
10271 i::Handle<i::ScopeInfo> scope_info(context->scope_info(), isolate);
10272 int local_count = scope_info->ContextLocalCount();
10273 for (int j = 0; j < local_count; ++j) {
10274 i::String name = scope_info->ContextLocalName(j);
10275 if (i::ScopeInfo::VariableIsSynthetic(name)) continue;
10276 names->Append(Utils::ToLocal(handle(name, isolate)));
10277 }
10278 }
10279 }
10280
SetReturnValue(v8::Isolate * v8_isolate,v8::Local<v8::Value> value)10281 void debug::SetReturnValue(v8::Isolate* v8_isolate,
10282 v8::Local<v8::Value> value) {
10283 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10284 isolate->debug()->set_return_value(*Utils::OpenHandle(*value));
10285 }
10286
GetNextRandomInt64(v8::Isolate * v8_isolate)10287 int64_t debug::GetNextRandomInt64(v8::Isolate* v8_isolate) {
10288 return reinterpret_cast<i::Isolate*>(v8_isolate)
10289 ->random_number_generator()
10290 ->NextInt64();
10291 }
10292
EnumerateRuntimeCallCounters(v8::Isolate * v8_isolate,RuntimeCallCounterCallback callback)10293 void debug::EnumerateRuntimeCallCounters(v8::Isolate* v8_isolate,
10294 RuntimeCallCounterCallback callback) {
10295 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
10296 if (isolate->counters()) {
10297 isolate->counters()->runtime_call_stats()->EnumerateCounters(callback);
10298 }
10299 }
10300
GetDebuggingId(v8::Local<v8::Function> function)10301 int debug::GetDebuggingId(v8::Local<v8::Function> function) {
10302 i::Handle<i::JSReceiver> callable = v8::Utils::OpenHandle(*function);
10303 if (!callable->IsJSFunction()) return i::DebugInfo::kNoDebuggingId;
10304 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(callable);
10305 int id = func->GetIsolate()->debug()->GetFunctionDebuggingId(func);
10306 DCHECK_NE(i::DebugInfo::kNoDebuggingId, id);
10307 return id;
10308 }
10309
SetFunctionBreakpoint(v8::Local<v8::Function> function,v8::Local<v8::String> condition,BreakpointId * id)10310 bool debug::SetFunctionBreakpoint(v8::Local<v8::Function> function,
10311 v8::Local<v8::String> condition,
10312 BreakpointId* id) {
10313 i::Handle<i::JSReceiver> callable = Utils::OpenHandle(*function);
10314 if (!callable->IsJSFunction()) return false;
10315 i::Handle<i::JSFunction> jsfunction =
10316 i::Handle<i::JSFunction>::cast(callable);
10317 i::Isolate* isolate = jsfunction->GetIsolate();
10318 i::Handle<i::String> condition_string =
10319 condition.IsEmpty() ? isolate->factory()->empty_string()
10320 : Utils::OpenHandle(*condition);
10321 return isolate->debug()->SetBreakpointForFunction(
10322 handle(jsfunction->shared(), isolate), condition_string, id);
10323 }
10324
PostponeInterruptsScope(v8::Isolate * isolate)10325 debug::PostponeInterruptsScope::PostponeInterruptsScope(v8::Isolate* isolate)
10326 : scope_(
10327 new i::PostponeInterruptsScope(reinterpret_cast<i::Isolate*>(isolate),
10328 i::StackGuard::API_INTERRUPT)) {}
10329
10330 debug::PostponeInterruptsScope::~PostponeInterruptsScope() = default;
10331
DisableBreakScope(v8::Isolate * isolate)10332 debug::DisableBreakScope::DisableBreakScope(v8::Isolate* isolate)
10333 : scope_(std::make_unique<i::DisableBreak>(
10334 reinterpret_cast<i::Isolate*>(isolate)->debug())) {}
10335
10336 debug::DisableBreakScope::~DisableBreakScope() = default;
10337
GetFunctionName() const10338 Local<String> CpuProfileNode::GetFunctionName() const {
10339 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10340 i::Isolate* isolate = node->isolate();
10341 const i::CodeEntry* entry = node->entry();
10342 i::Handle<i::String> name =
10343 isolate->factory()->InternalizeUtf8String(entry->name());
10344 return ToApiHandle<String>(name);
10345 }
10346
StartOffset() const10347 int debug::Coverage::BlockData::StartOffset() const { return block_->start; }
EndOffset() const10348 int debug::Coverage::BlockData::EndOffset() const { return block_->end; }
Count() const10349 uint32_t debug::Coverage::BlockData::Count() const { return block_->count; }
10350
StartOffset() const10351 int debug::Coverage::FunctionData::StartOffset() const {
10352 return function_->start;
10353 }
EndOffset() const10354 int debug::Coverage::FunctionData::EndOffset() const { return function_->end; }
Count() const10355 uint32_t debug::Coverage::FunctionData::Count() const {
10356 return function_->count;
10357 }
10358
Name() const10359 MaybeLocal<String> debug::Coverage::FunctionData::Name() const {
10360 return ToApiHandle<String>(function_->name);
10361 }
10362
BlockCount() const10363 size_t debug::Coverage::FunctionData::BlockCount() const {
10364 return function_->blocks.size();
10365 }
10366
HasBlockCoverage() const10367 bool debug::Coverage::FunctionData::HasBlockCoverage() const {
10368 return function_->has_block_coverage;
10369 }
10370
GetBlockData(size_t i) const10371 debug::Coverage::BlockData debug::Coverage::FunctionData::GetBlockData(
10372 size_t i) const {
10373 return BlockData(&function_->blocks.at(i), coverage_);
10374 }
10375
GetScript() const10376 Local<debug::Script> debug::Coverage::ScriptData::GetScript() const {
10377 return ToApiHandle<debug::Script>(script_->script);
10378 }
10379
FunctionCount() const10380 size_t debug::Coverage::ScriptData::FunctionCount() const {
10381 return script_->functions.size();
10382 }
10383
GetFunctionData(size_t i) const10384 debug::Coverage::FunctionData debug::Coverage::ScriptData::GetFunctionData(
10385 size_t i) const {
10386 return FunctionData(&script_->functions.at(i), coverage_);
10387 }
10388
ScriptData(size_t index,std::shared_ptr<i::Coverage> coverage)10389 debug::Coverage::ScriptData::ScriptData(size_t index,
10390 std::shared_ptr<i::Coverage> coverage)
10391 : script_(&coverage->at(index)), coverage_(std::move(coverage)) {}
10392
ScriptCount() const10393 size_t debug::Coverage::ScriptCount() const { return coverage_->size(); }
10394
GetScriptData(size_t i) const10395 debug::Coverage::ScriptData debug::Coverage::GetScriptData(size_t i) const {
10396 return ScriptData(i, coverage_);
10397 }
10398
CollectPrecise(Isolate * isolate)10399 debug::Coverage debug::Coverage::CollectPrecise(Isolate* isolate) {
10400 return Coverage(
10401 i::Coverage::CollectPrecise(reinterpret_cast<i::Isolate*>(isolate)));
10402 }
10403
CollectBestEffort(Isolate * isolate)10404 debug::Coverage debug::Coverage::CollectBestEffort(Isolate* isolate) {
10405 return Coverage(
10406 i::Coverage::CollectBestEffort(reinterpret_cast<i::Isolate*>(isolate)));
10407 }
10408
SelectMode(Isolate * isolate,debug::CoverageMode mode)10409 void debug::Coverage::SelectMode(Isolate* isolate, debug::CoverageMode mode) {
10410 i::Coverage::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode);
10411 }
10412
SourcePosition() const10413 int debug::TypeProfile::Entry::SourcePosition() const {
10414 return entry_->position;
10415 }
10416
Types() const10417 std::vector<MaybeLocal<String>> debug::TypeProfile::Entry::Types() const {
10418 std::vector<MaybeLocal<String>> result;
10419 for (const internal::Handle<internal::String>& type : entry_->types) {
10420 result.emplace_back(ToApiHandle<String>(type));
10421 }
10422 return result;
10423 }
10424
ScriptData(size_t index,std::shared_ptr<i::TypeProfile> type_profile)10425 debug::TypeProfile::ScriptData::ScriptData(
10426 size_t index, std::shared_ptr<i::TypeProfile> type_profile)
10427 : script_(&type_profile->at(index)),
10428 type_profile_(std::move(type_profile)) {}
10429
GetScript() const10430 Local<debug::Script> debug::TypeProfile::ScriptData::GetScript() const {
10431 return ToApiHandle<debug::Script>(script_->script);
10432 }
10433
Entries() const10434 std::vector<debug::TypeProfile::Entry> debug::TypeProfile::ScriptData::Entries()
10435 const {
10436 std::vector<debug::TypeProfile::Entry> result;
10437 for (const internal::TypeProfileEntry& entry : script_->entries) {
10438 result.push_back(debug::TypeProfile::Entry(&entry, type_profile_));
10439 }
10440 return result;
10441 }
10442
Collect(Isolate * isolate)10443 debug::TypeProfile debug::TypeProfile::Collect(Isolate* isolate) {
10444 return TypeProfile(
10445 i::TypeProfile::Collect(reinterpret_cast<i::Isolate*>(isolate)));
10446 }
10447
SelectMode(Isolate * isolate,debug::TypeProfileMode mode)10448 void debug::TypeProfile::SelectMode(Isolate* isolate,
10449 debug::TypeProfileMode mode) {
10450 i::TypeProfile::SelectMode(reinterpret_cast<i::Isolate*>(isolate), mode);
10451 }
10452
ScriptCount() const10453 size_t debug::TypeProfile::ScriptCount() const { return type_profile_->size(); }
10454
GetScriptData(size_t i) const10455 debug::TypeProfile::ScriptData debug::TypeProfile::GetScriptData(
10456 size_t i) const {
10457 return ScriptData(i, type_profile_);
10458 }
10459
Get(v8::Local<v8::Context> context,v8::Local<v8::Value> key)10460 v8::MaybeLocal<v8::Value> debug::WeakMap::Get(v8::Local<v8::Context> context,
10461 v8::Local<v8::Value> key) {
10462 PREPARE_FOR_EXECUTION(context, WeakMap, Get, Value);
10463 auto self = Utils::OpenHandle(this);
10464 Local<Value> result;
10465 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
10466 has_pending_exception =
10467 !ToLocal<Value>(i::Execution::CallBuiltin(isolate, isolate->weakmap_get(),
10468 self, arraysize(argv), argv),
10469 &result);
10470 RETURN_ON_FAILED_EXECUTION(Value);
10471 RETURN_ESCAPED(result);
10472 }
10473
Set(v8::Local<v8::Context> context,v8::Local<v8::Value> key,v8::Local<v8::Value> value)10474 v8::MaybeLocal<debug::WeakMap> debug::WeakMap::Set(
10475 v8::Local<v8::Context> context, v8::Local<v8::Value> key,
10476 v8::Local<v8::Value> value) {
10477 PREPARE_FOR_EXECUTION(context, WeakMap, Set, WeakMap);
10478 auto self = Utils::OpenHandle(this);
10479 i::Handle<i::Object> result;
10480 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
10481 Utils::OpenHandle(*value)};
10482 has_pending_exception =
10483 !i::Execution::CallBuiltin(isolate, isolate->weakmap_set(), self,
10484 arraysize(argv), argv)
10485 .ToHandle(&result);
10486 RETURN_ON_FAILED_EXECUTION(WeakMap);
10487 RETURN_ESCAPED(Local<WeakMap>::Cast(Utils::ToLocal(result)));
10488 }
10489
New(v8::Isolate * isolate)10490 Local<debug::WeakMap> debug::WeakMap::New(v8::Isolate* isolate) {
10491 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
10492 LOG_API(i_isolate, WeakMap, New);
10493 ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
10494 i::Handle<i::JSWeakMap> obj = i_isolate->factory()->NewJSWeakMap();
10495 return ToApiHandle<debug::WeakMap>(obj);
10496 }
10497
Cast(v8::Value * value)10498 debug::WeakMap* debug::WeakMap::Cast(v8::Value* value) {
10499 return static_cast<debug::WeakMap*>(value);
10500 }
10501
getter()10502 Local<Value> debug::AccessorPair::getter() {
10503 i::Handle<i::AccessorPair> accessors = Utils::OpenHandle(this);
10504 i::Isolate* isolate = accessors->GetIsolate();
10505 i::Handle<i::Object> getter(accessors->getter(), isolate);
10506 return Utils::ToLocal(getter);
10507 }
10508
setter()10509 Local<Value> debug::AccessorPair::setter() {
10510 i::Handle<i::AccessorPair> accessors = Utils::OpenHandle(this);
10511 i::Isolate* isolate = accessors->GetIsolate();
10512 i::Handle<i::Object> setter(accessors->setter(), isolate);
10513 return Utils::ToLocal(setter);
10514 }
10515
IsAccessorPair(Local<Value> that)10516 bool debug::AccessorPair::IsAccessorPair(Local<Value> that) {
10517 i::Handle<i::Object> obj = Utils::OpenHandle(*that);
10518 return obj->IsAccessorPair();
10519 }
10520
value_type()10521 int debug::WasmValue::value_type() {
10522 i::Handle<i::WasmValue> obj = Utils::OpenHandle(this);
10523 return obj->value_type();
10524 }
10525
bytes()10526 v8::Local<v8::Array> debug::WasmValue::bytes() {
10527 i::Handle<i::WasmValue> obj = Utils::OpenHandle(this);
10528 DCHECK(i::wasm::ValueType::Kind::kI32 == obj->value_type() ||
10529 i::wasm::ValueType::Kind::kI64 == obj->value_type() ||
10530 i::wasm::ValueType::Kind::kF32 == obj->value_type() ||
10531 i::wasm::ValueType::Kind::kF64 == obj->value_type() ||
10532 i::wasm::ValueType::Kind::kS128 == obj->value_type());
10533
10534 i::Isolate* isolate = obj->GetIsolate();
10535 i::Handle<i::Object> bytes_or_ref(obj->bytes_or_ref(), isolate);
10536 i::Handle<i::ByteArray> bytes(i::Handle<i::ByteArray>::cast(bytes_or_ref));
10537
10538 int length = bytes->length();
10539
10540 i::Handle<i::FixedArray> fa = isolate->factory()->NewFixedArray(length);
10541 i::Handle<i::JSArray> arr = obj->GetIsolate()->factory()->NewJSArray(
10542 i::PACKED_SMI_ELEMENTS, length, length);
10543 i::JSArray::SetContent(arr, fa);
10544
10545 for (int i = 0; i < length; i++) {
10546 fa->set(i, i::Smi::FromInt(bytes->get(i)));
10547 }
10548
10549 return Utils::ToLocal(arr);
10550 }
10551
ref()10552 v8::Local<v8::Value> debug::WasmValue::ref() {
10553 i::Handle<i::WasmValue> obj = Utils::OpenHandle(this);
10554 DCHECK_EQ(i::wasm::HeapType::kExtern, obj->value_type());
10555
10556 i::Isolate* isolate = obj->GetIsolate();
10557 i::Handle<i::Object> bytes_or_ref(obj->bytes_or_ref(), isolate);
10558
10559 return Utils::ToLocal(bytes_or_ref);
10560 }
10561
IsWasmValue(Local<Value> that)10562 bool debug::WasmValue::IsWasmValue(Local<Value> that) {
10563 i::Handle<i::Object> obj = Utils::OpenHandle(*that);
10564 return obj->IsWasmValue();
10565 }
10566
GetMessageFromPromise(Local<Promise> p)10567 MaybeLocal<Message> debug::GetMessageFromPromise(Local<Promise> p) {
10568 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*p);
10569 i::Isolate* isolate = promise->GetIsolate();
10570
10571 i::Handle<i::Symbol> key = isolate->factory()->promise_debug_message_symbol();
10572 i::Handle<i::Object> maybeMessage =
10573 i::JSReceiver::GetDataProperty(promise, key);
10574
10575 if (!maybeMessage->IsJSMessageObject(isolate)) return MaybeLocal<Message>();
10576 return ToApiHandle<Message>(
10577 i::Handle<i::JSMessageObject>::cast(maybeMessage));
10578 }
10579
GetFunctionNameStr() const10580 const char* CpuProfileNode::GetFunctionNameStr() const {
10581 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10582 return node->entry()->name();
10583 }
10584
GetScriptId() const10585 int CpuProfileNode::GetScriptId() const {
10586 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10587 const i::CodeEntry* entry = node->entry();
10588 return entry->script_id();
10589 }
10590
GetScriptResourceName() const10591 Local<String> CpuProfileNode::GetScriptResourceName() const {
10592 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10593 i::Isolate* isolate = node->isolate();
10594 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
10595 node->entry()->resource_name()));
10596 }
10597
GetScriptResourceNameStr() const10598 const char* CpuProfileNode::GetScriptResourceNameStr() const {
10599 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10600 return node->entry()->resource_name();
10601 }
10602
IsScriptSharedCrossOrigin() const10603 bool CpuProfileNode::IsScriptSharedCrossOrigin() const {
10604 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10605 return node->entry()->is_shared_cross_origin();
10606 }
10607
GetLineNumber() const10608 int CpuProfileNode::GetLineNumber() const {
10609 return reinterpret_cast<const i::ProfileNode*>(this)->line_number();
10610 }
10611
GetColumnNumber() const10612 int CpuProfileNode::GetColumnNumber() const {
10613 return reinterpret_cast<const i::ProfileNode*>(this)
10614 ->entry()
10615 ->column_number();
10616 }
10617
GetHitLineCount() const10618 unsigned int CpuProfileNode::GetHitLineCount() const {
10619 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10620 return node->GetHitLineCount();
10621 }
10622
GetLineTicks(LineTick * entries,unsigned int length) const10623 bool CpuProfileNode::GetLineTicks(LineTick* entries,
10624 unsigned int length) const {
10625 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10626 return node->GetLineTicks(entries, length);
10627 }
10628
GetBailoutReason() const10629 const char* CpuProfileNode::GetBailoutReason() const {
10630 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10631 return node->entry()->bailout_reason();
10632 }
10633
GetHitCount() const10634 unsigned CpuProfileNode::GetHitCount() const {
10635 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
10636 }
10637
GetNodeId() const10638 unsigned CpuProfileNode::GetNodeId() const {
10639 return reinterpret_cast<const i::ProfileNode*>(this)->id();
10640 }
10641
GetSourceType() const10642 CpuProfileNode::SourceType CpuProfileNode::GetSourceType() const {
10643 return reinterpret_cast<const i::ProfileNode*>(this)->source_type();
10644 }
10645
GetChildrenCount() const10646 int CpuProfileNode::GetChildrenCount() const {
10647 return static_cast<int>(
10648 reinterpret_cast<const i::ProfileNode*>(this)->children()->size());
10649 }
10650
GetChild(int index) const10651 const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
10652 const i::ProfileNode* child =
10653 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
10654 return reinterpret_cast<const CpuProfileNode*>(child);
10655 }
10656
GetParent() const10657 const CpuProfileNode* CpuProfileNode::GetParent() const {
10658 const i::ProfileNode* parent =
10659 reinterpret_cast<const i::ProfileNode*>(this)->parent();
10660 return reinterpret_cast<const CpuProfileNode*>(parent);
10661 }
10662
GetDeoptInfos() const10663 const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
10664 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
10665 return node->deopt_infos();
10666 }
10667
Delete()10668 void CpuProfile::Delete() {
10669 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
10670 i::CpuProfiler* profiler = profile->cpu_profiler();
10671 DCHECK_NOT_NULL(profiler);
10672 profiler->DeleteProfile(profile);
10673 }
10674
GetTitle() const10675 Local<String> CpuProfile::GetTitle() const {
10676 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10677 i::Isolate* isolate = profile->top_down()->isolate();
10678 return ToApiHandle<String>(
10679 isolate->factory()->InternalizeUtf8String(profile->title()));
10680 }
10681
GetTopDownRoot() const10682 const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
10683 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10684 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
10685 }
10686
GetSample(int index) const10687 const CpuProfileNode* CpuProfile::GetSample(int index) const {
10688 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10689 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index).node);
10690 }
10691
GetSampleTimestamp(int index) const10692 int64_t CpuProfile::GetSampleTimestamp(int index) const {
10693 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10694 return profile->sample(index).timestamp.since_origin().InMicroseconds();
10695 }
10696
GetStartTime() const10697 int64_t CpuProfile::GetStartTime() const {
10698 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10699 return profile->start_time().since_origin().InMicroseconds();
10700 }
10701
GetEndTime() const10702 int64_t CpuProfile::GetEndTime() const {
10703 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
10704 return profile->end_time().since_origin().InMicroseconds();
10705 }
10706
GetSamplesCount() const10707 int CpuProfile::GetSamplesCount() const {
10708 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
10709 }
10710
New(Isolate * isolate,CpuProfilingNamingMode naming_mode,CpuProfilingLoggingMode logging_mode)10711 CpuProfiler* CpuProfiler::New(Isolate* isolate,
10712 CpuProfilingNamingMode naming_mode,
10713 CpuProfilingLoggingMode logging_mode) {
10714 return reinterpret_cast<CpuProfiler*>(new i::CpuProfiler(
10715 reinterpret_cast<i::Isolate*>(isolate), naming_mode, logging_mode));
10716 }
10717
CpuProfilingOptions(CpuProfilingMode mode,unsigned max_samples,int sampling_interval_us,MaybeLocal<Context> filter_context)10718 CpuProfilingOptions::CpuProfilingOptions(CpuProfilingMode mode,
10719 unsigned max_samples,
10720 int sampling_interval_us,
10721 MaybeLocal<Context> filter_context)
10722 : mode_(mode),
10723 max_samples_(max_samples),
10724 sampling_interval_us_(sampling_interval_us) {}
10725
Dispose()10726 void CpuProfiler::Dispose() { delete reinterpret_cast<i::CpuProfiler*>(this); }
10727
10728 // static
CollectSample(Isolate * isolate)10729 void CpuProfiler::CollectSample(Isolate* isolate) {
10730 i::CpuProfiler::CollectSample(reinterpret_cast<i::Isolate*>(isolate));
10731 }
10732
SetSamplingInterval(int us)10733 void CpuProfiler::SetSamplingInterval(int us) {
10734 DCHECK_GE(us, 0);
10735 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
10736 base::TimeDelta::FromMicroseconds(us));
10737 }
10738
SetUsePreciseSampling(bool use_precise_sampling)10739 void CpuProfiler::SetUsePreciseSampling(bool use_precise_sampling) {
10740 reinterpret_cast<i::CpuProfiler*>(this)->set_use_precise_sampling(
10741 use_precise_sampling);
10742 }
10743
StartProfiling(Local<String> title,CpuProfilingOptions options)10744 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10745 CpuProfilingOptions options) {
10746 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10747 *Utils::OpenHandle(*title), options);
10748 }
10749
StartProfiling(Local<String> title,bool record_samples)10750 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10751 bool record_samples) {
10752 CpuProfilingOptions options(
10753 kLeafNodeLineNumbers,
10754 record_samples ? CpuProfilingOptions::kNoSampleLimit : 0);
10755 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10756 *Utils::OpenHandle(*title), options);
10757 }
10758
StartProfiling(Local<String> title,CpuProfilingMode mode,bool record_samples,unsigned max_samples)10759 CpuProfilingStatus CpuProfiler::StartProfiling(Local<String> title,
10760 CpuProfilingMode mode,
10761 bool record_samples,
10762 unsigned max_samples) {
10763 CpuProfilingOptions options(mode, record_samples ? max_samples : 0);
10764 return reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
10765 *Utils::OpenHandle(*title), options);
10766 }
10767
StopProfiling(Local<String> title)10768 CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
10769 return reinterpret_cast<CpuProfile*>(
10770 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
10771 *Utils::OpenHandle(*title)));
10772 }
10773
UseDetailedSourcePositionsForProfiling(Isolate * isolate)10774 void CpuProfiler::UseDetailedSourcePositionsForProfiling(Isolate* isolate) {
10775 reinterpret_cast<i::Isolate*>(isolate)
10776 ->set_detailed_source_positions_for_profiling(true);
10777 }
10778
GetCodeStartAddress()10779 uintptr_t CodeEvent::GetCodeStartAddress() {
10780 return reinterpret_cast<i::CodeEvent*>(this)->code_start_address;
10781 }
10782
GetCodeSize()10783 size_t CodeEvent::GetCodeSize() {
10784 return reinterpret_cast<i::CodeEvent*>(this)->code_size;
10785 }
10786
GetFunctionName()10787 Local<String> CodeEvent::GetFunctionName() {
10788 return ToApiHandle<String>(
10789 reinterpret_cast<i::CodeEvent*>(this)->function_name);
10790 }
10791
GetScriptName()10792 Local<String> CodeEvent::GetScriptName() {
10793 return ToApiHandle<String>(
10794 reinterpret_cast<i::CodeEvent*>(this)->script_name);
10795 }
10796
GetScriptLine()10797 int CodeEvent::GetScriptLine() {
10798 return reinterpret_cast<i::CodeEvent*>(this)->script_line;
10799 }
10800
GetScriptColumn()10801 int CodeEvent::GetScriptColumn() {
10802 return reinterpret_cast<i::CodeEvent*>(this)->script_column;
10803 }
10804
GetCodeType()10805 CodeEventType CodeEvent::GetCodeType() {
10806 return reinterpret_cast<i::CodeEvent*>(this)->code_type;
10807 }
10808
GetComment()10809 const char* CodeEvent::GetComment() {
10810 return reinterpret_cast<i::CodeEvent*>(this)->comment;
10811 }
10812
GetPreviousCodeStartAddress()10813 uintptr_t CodeEvent::GetPreviousCodeStartAddress() {
10814 return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address;
10815 }
10816
GetCodeEventTypeName(CodeEventType code_event_type)10817 const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) {
10818 switch (code_event_type) {
10819 case kUnknownType:
10820 return "Unknown";
10821 #define V(Name) \
10822 case k##Name##Type: \
10823 return #Name;
10824 CODE_EVENTS_LIST(V)
10825 #undef V
10826 }
10827 // The execution should never pass here
10828 UNREACHABLE();
10829 // NOTE(mmarchini): Workaround to fix a compiler failure on GCC 4.9
10830 return "Unknown";
10831 }
10832
CodeEventHandler(Isolate * isolate)10833 CodeEventHandler::CodeEventHandler(Isolate* isolate) {
10834 internal_listener_ =
10835 new i::ExternalCodeEventListener(reinterpret_cast<i::Isolate*>(isolate));
10836 }
10837
~CodeEventHandler()10838 CodeEventHandler::~CodeEventHandler() {
10839 delete reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_);
10840 }
10841
Enable()10842 void CodeEventHandler::Enable() {
10843 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10844 ->StartListening(this);
10845 }
10846
Disable()10847 void CodeEventHandler::Disable() {
10848 reinterpret_cast<i::ExternalCodeEventListener*>(internal_listener_)
10849 ->StopListening();
10850 }
10851
ToInternal(const HeapGraphEdge * edge)10852 static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
10853 return const_cast<i::HeapGraphEdge*>(
10854 reinterpret_cast<const i::HeapGraphEdge*>(edge));
10855 }
10856
GetType() const10857 HeapGraphEdge::Type HeapGraphEdge::GetType() const {
10858 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
10859 }
10860
GetName() const10861 Local<Value> HeapGraphEdge::GetName() const {
10862 i::HeapGraphEdge* edge = ToInternal(this);
10863 i::Isolate* isolate = edge->isolate();
10864 switch (edge->type()) {
10865 case i::HeapGraphEdge::kContextVariable:
10866 case i::HeapGraphEdge::kInternal:
10867 case i::HeapGraphEdge::kProperty:
10868 case i::HeapGraphEdge::kShortcut:
10869 case i::HeapGraphEdge::kWeak:
10870 return ToApiHandle<String>(
10871 isolate->factory()->InternalizeUtf8String(edge->name()));
10872 case i::HeapGraphEdge::kElement:
10873 case i::HeapGraphEdge::kHidden:
10874 return ToApiHandle<Number>(
10875 isolate->factory()->NewNumberFromInt(edge->index()));
10876 default:
10877 UNREACHABLE();
10878 }
10879 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
10880 }
10881
GetFromNode() const10882 const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
10883 const i::HeapEntry* from = ToInternal(this)->from();
10884 return reinterpret_cast<const HeapGraphNode*>(from);
10885 }
10886
GetToNode() const10887 const HeapGraphNode* HeapGraphEdge::GetToNode() const {
10888 const i::HeapEntry* to = ToInternal(this)->to();
10889 return reinterpret_cast<const HeapGraphNode*>(to);
10890 }
10891
ToInternal(const HeapGraphNode * entry)10892 static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
10893 return const_cast<i::HeapEntry*>(
10894 reinterpret_cast<const i::HeapEntry*>(entry));
10895 }
10896
GetType() const10897 HeapGraphNode::Type HeapGraphNode::GetType() const {
10898 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
10899 }
10900
GetName() const10901 Local<String> HeapGraphNode::GetName() const {
10902 i::Isolate* isolate = ToInternal(this)->isolate();
10903 return ToApiHandle<String>(
10904 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
10905 }
10906
GetId() const10907 SnapshotObjectId HeapGraphNode::GetId() const { return ToInternal(this)->id(); }
10908
GetShallowSize() const10909 size_t HeapGraphNode::GetShallowSize() const {
10910 return ToInternal(this)->self_size();
10911 }
10912
GetChildrenCount() const10913 int HeapGraphNode::GetChildrenCount() const {
10914 return ToInternal(this)->children_count();
10915 }
10916
GetChild(int index) const10917 const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
10918 return reinterpret_cast<const HeapGraphEdge*>(ToInternal(this)->child(index));
10919 }
10920
ToInternal(const HeapSnapshot * snapshot)10921 static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
10922 return const_cast<i::HeapSnapshot*>(
10923 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
10924 }
10925
Delete()10926 void HeapSnapshot::Delete() {
10927 i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
10928 if (isolate->heap_profiler()->GetSnapshotsCount() > 1 ||
10929 isolate->heap_profiler()->IsTakingSnapshot()) {
10930 ToInternal(this)->Delete();
10931 } else {
10932 // If this is the last snapshot, clean up all accessory data as well.
10933 isolate->heap_profiler()->DeleteAllSnapshots();
10934 }
10935 }
10936
GetRoot() const10937 const HeapGraphNode* HeapSnapshot::GetRoot() const {
10938 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
10939 }
10940
GetNodeById(SnapshotObjectId id) const10941 const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
10942 return reinterpret_cast<const HeapGraphNode*>(
10943 ToInternal(this)->GetEntryById(id));
10944 }
10945
GetNodesCount() const10946 int HeapSnapshot::GetNodesCount() const {
10947 return static_cast<int>(ToInternal(this)->entries().size());
10948 }
10949
GetNode(int index) const10950 const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
10951 return reinterpret_cast<const HeapGraphNode*>(
10952 &ToInternal(this)->entries().at(index));
10953 }
10954
GetMaxSnapshotJSObjectId() const10955 SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
10956 return ToInternal(this)->max_snapshot_js_object_id();
10957 }
10958
Serialize(OutputStream * stream,HeapSnapshot::SerializationFormat format) const10959 void HeapSnapshot::Serialize(OutputStream* stream,
10960 HeapSnapshot::SerializationFormat format) const {
10961 Utils::ApiCheck(format == kJSON, "v8::HeapSnapshot::Serialize",
10962 "Unknown serialization format");
10963 Utils::ApiCheck(stream->GetChunkSize() > 0, "v8::HeapSnapshot::Serialize",
10964 "Invalid stream chunk size");
10965 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
10966 serializer.Serialize(stream);
10967 }
10968
10969 // static
10970 STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
10971 HeapProfiler::kUnknownObjectId;
10972
GetSnapshotCount()10973 int HeapProfiler::GetSnapshotCount() {
10974 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
10975 }
10976
GetHeapSnapshot(int index)10977 const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
10978 return reinterpret_cast<const HeapSnapshot*>(
10979 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
10980 }
10981
GetObjectId(Local<Value> value)10982 SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
10983 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
10984 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
10985 }
10986
GetObjectId(NativeObject value)10987 SnapshotObjectId HeapProfiler::GetObjectId(NativeObject value) {
10988 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(value);
10989 }
10990
FindObjectById(SnapshotObjectId id)10991 Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
10992 i::Handle<i::Object> obj =
10993 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
10994 if (obj.is_null()) return Local<Value>();
10995 return Utils::ToLocal(obj);
10996 }
10997
ClearObjectIds()10998 void HeapProfiler::ClearObjectIds() {
10999 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
11000 }
11001
TakeHeapSnapshot(ActivityControl * control,ObjectNameResolver * resolver,bool treat_global_objects_as_roots)11002 const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
11003 ActivityControl* control, ObjectNameResolver* resolver,
11004 bool treat_global_objects_as_roots) {
11005 return reinterpret_cast<const HeapSnapshot*>(
11006 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
11007 control, resolver, treat_global_objects_as_roots));
11008 }
11009
StartTrackingHeapObjects(bool track_allocations)11010 void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
11011 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
11012 track_allocations);
11013 }
11014
StopTrackingHeapObjects()11015 void HeapProfiler::StopTrackingHeapObjects() {
11016 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
11017 }
11018
GetHeapStats(OutputStream * stream,int64_t * timestamp_us)11019 SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
11020 int64_t* timestamp_us) {
11021 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
11022 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
11023 }
11024
StartSamplingHeapProfiler(uint64_t sample_interval,int stack_depth,SamplingFlags flags)11025 bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
11026 int stack_depth,
11027 SamplingFlags flags) {
11028 return reinterpret_cast<i::HeapProfiler*>(this)->StartSamplingHeapProfiler(
11029 sample_interval, stack_depth, flags);
11030 }
11031
StopSamplingHeapProfiler()11032 void HeapProfiler::StopSamplingHeapProfiler() {
11033 reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
11034 }
11035
GetAllocationProfile()11036 AllocationProfile* HeapProfiler::GetAllocationProfile() {
11037 return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
11038 }
11039
DeleteAllHeapSnapshots()11040 void HeapProfiler::DeleteAllHeapSnapshots() {
11041 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
11042 }
11043
AddBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)11044 void HeapProfiler::AddBuildEmbedderGraphCallback(
11045 BuildEmbedderGraphCallback callback, void* data) {
11046 reinterpret_cast<i::HeapProfiler*>(this)->AddBuildEmbedderGraphCallback(
11047 callback, data);
11048 }
11049
RemoveBuildEmbedderGraphCallback(BuildEmbedderGraphCallback callback,void * data)11050 void HeapProfiler::RemoveBuildEmbedderGraphCallback(
11051 BuildEmbedderGraphCallback callback, void* data) {
11052 reinterpret_cast<i::HeapProfiler*>(this)->RemoveBuildEmbedderGraphCallback(
11053 callback, data);
11054 }
11055
SetGetDetachednessCallback(GetDetachednessCallback callback,void * data)11056 void HeapProfiler::SetGetDetachednessCallback(GetDetachednessCallback callback,
11057 void* data) {
11058 reinterpret_cast<i::HeapProfiler*>(this)->SetGetDetachednessCallback(callback,
11059 data);
11060 }
11061
SetStackStart(void * stack_start)11062 void EmbedderHeapTracer::SetStackStart(void* stack_start) {
11063 CHECK(isolate_);
11064 reinterpret_cast<i::Isolate*>(isolate_)->global_handles()->SetStackStart(
11065 stack_start);
11066 }
11067
NotifyEmptyEmbedderStack()11068 void EmbedderHeapTracer::NotifyEmptyEmbedderStack() {
11069 CHECK(isolate_);
11070 reinterpret_cast<i::Isolate*>(isolate_)
11071 ->global_handles()
11072 ->NotifyEmptyEmbedderStack();
11073 }
11074
FinalizeTracing()11075 void EmbedderHeapTracer::FinalizeTracing() {
11076 if (isolate_) {
11077 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
11078 if (isolate->heap()->incremental_marking()->IsMarking()) {
11079 isolate->heap()->FinalizeIncrementalMarkingAtomically(
11080 i::GarbageCollectionReason::kExternalFinalize);
11081 }
11082 }
11083 }
11084
GarbageCollectionForTesting(EmbedderStackState stack_state)11085 void EmbedderHeapTracer::GarbageCollectionForTesting(
11086 EmbedderStackState stack_state) {
11087 CHECK(isolate_);
11088 CHECK(i::FLAG_expose_gc);
11089 i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
11090 heap->SetEmbedderStackStateForNextFinalization(stack_state);
11091 heap->PreciseCollectAllGarbage(i::Heap::kNoGCFlags,
11092 i::GarbageCollectionReason::kTesting,
11093 kGCCallbackFlagForced);
11094 }
11095
IncreaseAllocatedSize(size_t bytes)11096 void EmbedderHeapTracer::IncreaseAllocatedSize(size_t bytes) {
11097 if (isolate_) {
11098 i::LocalEmbedderHeapTracer* const tracer =
11099 reinterpret_cast<i::Isolate*>(isolate_)
11100 ->heap()
11101 ->local_embedder_heap_tracer();
11102 DCHECK_NOT_NULL(tracer);
11103 tracer->IncreaseAllocatedSize(bytes);
11104 }
11105 }
11106
DecreaseAllocatedSize(size_t bytes)11107 void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) {
11108 if (isolate_) {
11109 i::LocalEmbedderHeapTracer* const tracer =
11110 reinterpret_cast<i::Isolate*>(isolate_)
11111 ->heap()
11112 ->local_embedder_heap_tracer();
11113 DCHECK_NOT_NULL(tracer);
11114 tracer->DecreaseAllocatedSize(bytes);
11115 }
11116 }
11117
RegisterEmbedderReference(const BasicTracedReference<v8::Data> & ref)11118 void EmbedderHeapTracer::RegisterEmbedderReference(
11119 const BasicTracedReference<v8::Data>& ref) {
11120 if (ref.IsEmpty()) return;
11121
11122 i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
11123 heap->RegisterExternallyReferencedObject(
11124 reinterpret_cast<i::Address*>(ref.val_));
11125 }
11126
IterateTracedGlobalHandles(TracedGlobalHandleVisitor * visitor)11127 void EmbedderHeapTracer::IterateTracedGlobalHandles(
11128 TracedGlobalHandleVisitor* visitor) {
11129 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(isolate_);
11130 i::DisallowHeapAllocation no_allocation;
11131 isolate->global_handles()->IterateTracedNodes(visitor);
11132 }
11133
IsRootForNonTracingGC(const v8::TracedReference<v8::Value> & handle)11134 bool EmbedderHeapTracer::IsRootForNonTracingGC(
11135 const v8::TracedReference<v8::Value>& handle) {
11136 return true;
11137 }
11138
IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value> & handle)11139 bool EmbedderHeapTracer::IsRootForNonTracingGC(
11140 const v8::TracedGlobal<v8::Value>& handle) {
11141 return true;
11142 }
11143
ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value> & handle)11144 void EmbedderHeapTracer::ResetHandleInNonTracingGC(
11145 const v8::TracedReference<v8::Value>& handle) {
11146 UNREACHABLE();
11147 }
11148
GetWrapperInfo() const11149 const void* CTypeInfo::GetWrapperInfo() const {
11150 DCHECK(payload_ & kWrapperTypeInfoMask);
11151 return reinterpret_cast<const void*>(payload_ & kWrapperTypeInfoMask);
11152 }
11153
CFunction(const void * address,const CFunctionInfo * type_info)11154 CFunction::CFunction(const void* address, const CFunctionInfo* type_info)
11155 : address_(address), type_info_(type_info) {
11156 CHECK_NOT_NULL(address_);
11157 CHECK_NOT_NULL(type_info_);
11158 for (unsigned int i = 0; i < type_info_->ArgumentCount(); ++i) {
11159 if (type_info_->ArgumentInfo(i).IsArray()) {
11160 // Array args require an integer passed for their length
11161 // as the next argument.
11162 DCHECK_LT(i + 1, type_info_->ArgumentCount());
11163 switch (type_info_->ArgumentInfo(i + 1).GetType()) {
11164 case CTypeInfo::Type::kInt32:
11165 case CTypeInfo::Type::kUint32:
11166 case CTypeInfo::Type::kInt64:
11167 case CTypeInfo::Type::kUint64:
11168 break;
11169 default:
11170 UNREACHABLE();
11171 break;
11172 }
11173 }
11174 }
11175 }
11176
RegisterState()11177 RegisterState::RegisterState()
11178 : pc(nullptr), sp(nullptr), fp(nullptr), lr(nullptr) {}
11179 RegisterState::~RegisterState() = default;
11180
RegisterState(const RegisterState & other)11181 RegisterState::RegisterState(const RegisterState& other) V8_NOEXCEPT {
11182 *this = other;
11183 }
11184
operator =(const RegisterState & other)11185 RegisterState& RegisterState::operator=(const RegisterState& other)
11186 V8_NOEXCEPT {
11187 if (&other != this) {
11188 pc = other.pc;
11189 sp = other.sp;
11190 fp = other.fp;
11191 lr = other.lr;
11192 if (other.callee_saved) {
11193 // Make a deep copy if {other.callee_saved} is non-null.
11194 callee_saved =
11195 std::make_unique<CalleeSavedRegisters>(*(other.callee_saved));
11196 } else {
11197 // Otherwise, set {callee_saved} to null to match {other}.
11198 callee_saved.reset();
11199 }
11200 }
11201 return *this;
11202 }
11203
11204 namespace internal {
11205
11206 const size_t HandleScopeImplementer::kEnteredContextsOffset =
11207 offsetof(HandleScopeImplementer, entered_contexts_);
11208 const size_t HandleScopeImplementer::kIsMicrotaskContextOffset =
11209 offsetof(HandleScopeImplementer, is_microtask_context_);
11210
FreeThreadResources()11211 void HandleScopeImplementer::FreeThreadResources() { Free(); }
11212
ArchiveThread(char * storage)11213 char* HandleScopeImplementer::ArchiveThread(char* storage) {
11214 HandleScopeData* current = isolate_->handle_scope_data();
11215 handle_scope_data_ = *current;
11216 MemCopy(storage, this, sizeof(*this));
11217
11218 ResetAfterArchive();
11219 current->Initialize();
11220
11221 return storage + ArchiveSpacePerThread();
11222 }
11223
ArchiveSpacePerThread()11224 int HandleScopeImplementer::ArchiveSpacePerThread() {
11225 return sizeof(HandleScopeImplementer);
11226 }
11227
RestoreThread(char * storage)11228 char* HandleScopeImplementer::RestoreThread(char* storage) {
11229 MemCopy(this, storage, sizeof(*this));
11230 *isolate_->handle_scope_data() = handle_scope_data_;
11231 return storage + ArchiveSpacePerThread();
11232 }
11233
IterateThis(RootVisitor * v)11234 void HandleScopeImplementer::IterateThis(RootVisitor* v) {
11235 #ifdef DEBUG
11236 bool found_block_before_deferred = false;
11237 #endif
11238 // Iterate over all handles in the blocks except for the last.
11239 for (int i = static_cast<int>(blocks()->size()) - 2; i >= 0; --i) {
11240 Address* block = blocks()->at(i);
11241 // Cast possibly-unrelated pointers to plain Address before comparing them
11242 // to avoid undefined behavior.
11243 if (last_handle_before_deferred_block_ != nullptr &&
11244 (reinterpret_cast<Address>(last_handle_before_deferred_block_) <=
11245 reinterpret_cast<Address>(&block[kHandleBlockSize])) &&
11246 (reinterpret_cast<Address>(last_handle_before_deferred_block_) >=
11247 reinterpret_cast<Address>(block))) {
11248 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
11249 FullObjectSlot(last_handle_before_deferred_block_));
11250 DCHECK(!found_block_before_deferred);
11251 #ifdef DEBUG
11252 found_block_before_deferred = true;
11253 #endif
11254 } else {
11255 v->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block),
11256 FullObjectSlot(&block[kHandleBlockSize]));
11257 }
11258 }
11259
11260 DCHECK(last_handle_before_deferred_block_ == nullptr ||
11261 found_block_before_deferred);
11262
11263 // Iterate over live handles in the last block (if any).
11264 if (!blocks()->empty()) {
11265 v->VisitRootPointers(Root::kHandleScope, nullptr,
11266 FullObjectSlot(blocks()->back()),
11267 FullObjectSlot(handle_scope_data_.next));
11268 }
11269
11270 DetachableVector<Context>* context_lists[2] = {&saved_contexts_,
11271 &entered_contexts_};
11272 for (unsigned i = 0; i < arraysize(context_lists); i++) {
11273 context_lists[i]->shrink_to_fit();
11274 if (context_lists[i]->empty()) continue;
11275 FullObjectSlot start(&context_lists[i]->front());
11276 v->VisitRootPointers(Root::kHandleScope, nullptr, start,
11277 start + static_cast<int>(context_lists[i]->size()));
11278 }
11279 }
11280
Iterate(RootVisitor * v)11281 void HandleScopeImplementer::Iterate(RootVisitor* v) {
11282 HandleScopeData* current = isolate_->handle_scope_data();
11283 handle_scope_data_ = *current;
11284 IterateThis(v);
11285 }
11286
Iterate(RootVisitor * v,char * storage)11287 char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) {
11288 HandleScopeImplementer* scope_implementer =
11289 reinterpret_cast<HandleScopeImplementer*>(storage);
11290 scope_implementer->IterateThis(v);
11291 return storage + ArchiveSpacePerThread();
11292 }
11293
DetachPersistent(Address * prev_limit)11294 std::unique_ptr<PersistentHandles> HandleScopeImplementer::DetachPersistent(
11295 Address* prev_limit) {
11296 std::unique_ptr<PersistentHandles> ph(new PersistentHandles(isolate()));
11297 DCHECK_NOT_NULL(prev_limit);
11298
11299 while (!blocks_.empty()) {
11300 Address* block_start = blocks_.back();
11301 Address* block_limit = &block_start[kHandleBlockSize];
11302 // We should not need to check for SealHandleScope here. Assert this.
11303 DCHECK_IMPLIES(block_start <= prev_limit && prev_limit <= block_limit,
11304 prev_limit == block_limit);
11305 if (prev_limit == block_limit) break;
11306 ph->blocks_.push_back(blocks_.back());
11307 #if DEBUG
11308 ph->ordered_blocks_.insert(blocks_.back());
11309 #endif
11310 blocks_.pop_back();
11311 }
11312
11313 // ph->blocks_ now contains the blocks installed on the
11314 // HandleScope stack since BeginDeferredScope was called, but in
11315 // reverse order.
11316
11317 // Switch first and last blocks, such that the last block is the one
11318 // that is potentially half full.
11319 DCHECK(!blocks_.empty() && !ph->blocks_.empty());
11320 std::swap(ph->blocks_.front(), ph->blocks_.back());
11321
11322 ph->block_next_ = isolate()->handle_scope_data()->next;
11323 Address* block_start = ph->blocks_.back();
11324 ph->block_limit_ = block_start + kHandleBlockSize;
11325
11326 DCHECK_NOT_NULL(last_handle_before_deferred_block_);
11327 last_handle_before_deferred_block_ = nullptr;
11328 return ph;
11329 }
11330
BeginDeferredScope()11331 void HandleScopeImplementer::BeginDeferredScope() {
11332 DCHECK_NULL(last_handle_before_deferred_block_);
11333 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
11334 }
11335
InvokeAccessorGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info,v8::AccessorNameGetterCallback getter)11336 void InvokeAccessorGetterCallback(
11337 v8::Local<v8::Name> property,
11338 const v8::PropertyCallbackInfo<v8::Value>& info,
11339 v8::AccessorNameGetterCallback getter) {
11340 // Leaving JavaScript.
11341 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
11342 RuntimeCallTimerScope timer(isolate,
11343 RuntimeCallCounterId::kAccessorGetterCallback);
11344 Address getter_address = reinterpret_cast<Address>(getter);
11345 VMState<EXTERNAL> state(isolate);
11346 ExternalCallbackScope call_scope(isolate, getter_address);
11347 getter(property, info);
11348 }
11349
InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value> & info,v8::FunctionCallback callback)11350 void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
11351 v8::FunctionCallback callback) {
11352 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
11353 RuntimeCallTimerScope timer(isolate, RuntimeCallCounterId::kFunctionCallback);
11354 Address callback_address = reinterpret_cast<Address>(callback);
11355 VMState<EXTERNAL> state(isolate);
11356 ExternalCallbackScope call_scope(isolate, callback_address);
11357 callback(info);
11358 }
11359
InvokeFinalizationRegistryCleanupFromTask(Handle<Context> context,Handle<JSFinalizationRegistry> finalization_registry,Handle<Object> callback)11360 void InvokeFinalizationRegistryCleanupFromTask(
11361 Handle<Context> context,
11362 Handle<JSFinalizationRegistry> finalization_registry,
11363 Handle<Object> callback) {
11364 Isolate* isolate = finalization_registry->native_context().GetIsolate();
11365 RuntimeCallTimerScope timer(
11366 isolate, RuntimeCallCounterId::kFinalizationRegistryCleanupFromTask);
11367 // Do not use ENTER_V8 because this is always called from a running
11368 // FinalizationRegistryCleanupTask within V8 and we should not log it as an
11369 // API call. This method is implemented here to avoid duplication of the
11370 // exception handling and microtask running logic in CallDepthScope.
11371 if (IsExecutionTerminatingCheck(isolate)) return;
11372 Local<v8::Context> api_context = Utils::ToLocal(context);
11373 CallDepthScope<true> call_depth_scope(isolate, api_context);
11374 VMState<OTHER> state(isolate);
11375 Handle<Object> argv[] = {callback};
11376 if (Execution::CallBuiltin(isolate,
11377 isolate->finalization_registry_cleanup_some(),
11378 finalization_registry, arraysize(argv), argv)
11379 .is_null()) {
11380 call_depth_scope.Escape();
11381 }
11382 }
11383
11384 // Undefine macros for jumbo build.
11385 #undef LOG_API
11386 #undef ENTER_V8_DO_NOT_USE
11387 #undef ENTER_V8_HELPER_DO_NOT_USE
11388 #undef PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE
11389 #undef PREPARE_FOR_EXECUTION_WITH_CONTEXT
11390 #undef PREPARE_FOR_EXECUTION
11391 #undef ENTER_V8
11392 #undef ENTER_V8_NO_SCRIPT
11393 #undef ENTER_V8_NO_SCRIPT_NO_EXCEPTION
11394 #undef ENTER_V8_FOR_NEW_CONTEXT
11395 #undef EXCEPTION_BAILOUT_CHECK_SCOPED_DO_NOT_USE
11396 #undef RETURN_ON_FAILED_EXECUTION
11397 #undef RETURN_ON_FAILED_EXECUTION_PRIMITIVE
11398 #undef RETURN_ESCAPED
11399 #undef SET_FIELD_WRAPPED
11400 #undef NEW_STRING
11401 #undef CALLBACK_SETTER
11402
11403 } // namespace internal
11404 } // namespace v8
11405
11406 #undef TRACE_BS
11407